编译原理实验之预测分析算法的设计与实现
2014-09-08 23:45
831 查看
不要被大段的代码吓到,其实问题很简单,只需照着书上的过程走即可。
实验要求:
输入文法及待分析的输入串,输出其预测分析过程及结果。(基本要求就是:所有字符都只有一个字符组成,不能出现A*等字符,你可自行修改自己的文法后在用下面的代码)
注明:代码分了多个写,主函数是1.cpp代码如下(后期我会再发个链接过来可直接看到源文件,对不太熟悉VS工具的比较有帮助),想看中间结果的话可以将注释解开即可:
#include"head.h"
#include"apart_from.h"
#include"first.h"
#include"follw.h"
#include"table.h"
#include"judge.h"
int main(){
int i=0,j;
while((scanf("%s",form[i].formula),form[i].formula[0])!='#'){
i++;
}
sum = i;
apart();
First();
Follow();
printf("非终结符:\n");
printf("%s\n",ter_symbol);
printf("终结符:\n");
printf("%s\n",non_ter);
/*
printf("first集:\n");
for(j=0;j<strlen(ter_symbol);j++)
printf("%s\n",first_set[j]);
printf("follow集:\n");
for(j=0;j<strlen(ter_symbol);j++)
printf("%s\n",follow_set[j]);
*/
getTable();
//printTable();//输出预测表
printf("输入串(以‘#’号键结束):\n");
scanf("%s",inter_symbol);
while(inter_symbol[strlen(inter_symbol)-1]!='#'){
printf("输入串没有以‘#’号键结束,请重新输入:\n");
scanf("%s",inter_symbol);
}
printf("步骤 符号栈 输入串 所用产生式\n");
printf("---- ------ ------ ----------\n");
Judge();
return 0;
}
apart_from.h的代码:
void apart(){
int i,len,k=0,j,l,p;
for(i=0;i<sum;i++){
for(j=0;j<k;j++){
if(ter_symbol[j]==form[i].formula[0])
break;
}
if(j==k)
ter_symbol[k++] = form[i].formula[0];
}//非终结符
ter_symbol[k]='\0';
k=0;
for(i=0;i<sum;i++){
len = strlen(form[i].formula);
for(j=3;j<len;j++){
if(form[i].formula[j]=='$')
break;
for(l=0;l<strlen(ter_symbol);l++){
if(form[i].formula[j]==ter_symbol[l])
break;
}
for(p=0;p<k;p++){
if(form[i].formula[j]==non_ter[p])
break;
}
if(l==strlen(ter_symbol)&&p==k){
non_ter[k++]=form[i].formula[j];
}
}
}//终结符
non_ter[k]='\0';
}
head.h的代码:
first.h的代码:
follow.h的代码:
judge.h的代码:
int top;
char stack[200];
int x;
void Judge(){
stack[0]='#';
stack[1]=form[0].formula[0];
int flag=1,step=0;
int i,j,l;
char print[100];
top=1;
x=0;//printf("---- ------ ------\n");
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
printf("\n");
while(flag){
if(get_non(stack[top])>=0){
if(stack[top]==inter_symbol[x]){
x++;//终结符匹配上
top--;
if(step<10)
printf(" %d ",step++);
else
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
printf("\n");
}
else
break;
}
else if(stack[top]=='#'){
if(stack[top]==inter_symbol[x])
flag=0;//彻底结束
else
break;
}
else{
int col=get_ter(stack[top]);
int row=get_non(inter_symbol[x]);
if(inter_symbol[x]=='#')
row=strlen(non_ter);
if(M[col][row]>=0){//非终结符
if(form[M[col][row]].formula[3]=='$'){
top--;
}
else
{
for(i=strlen(form[M[col][row]].formula)-1;i>=3;i--){
stack[top++]=form[M[col][row]].formula[i];
}
top--;
}
if(step<10)
printf(" %d ",step++);
else
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
for(l=0;l<=(11-strlen(inter_symbol));l++)
printf(" ");
printf("%s",form[M[col][row]].formula);
printf("\n");
}
else break;
}
}
if(flag){
printf("输入串无法匹配成功!\n");
}
else{
printf("输入串匹配成功!\n");
}
}
table.h的代码:
void getTable(){//ter_symbol[200];//非终结符号
// non_ter[200];//终结符号
int i,j,k,col,row,flag=0;
for(i=0;i<strlen(ter_symbol);i++){
for(j=0;j<strlen(non_ter)+1;j++)
M[i][j]=-1;
}
for(i=0;i<sum;i++){//printf("lalallallalallalallalalla\n");
flag=0;
if((row=get_non(form[i].formula[3]))>=0){//printf("%d %d 1\n",row,i);
col=get_ter(form[i].formula[0]);
M[col][row]=i;
}//右部是终结符
else if((row=get_non(form[i].formula[3]))==-1){//非终结符和空
//if()
col=get_ter(form[i].formula[0]);//左部是行坐标
k=get_ter(form[i].formula[3]);//右部非终结符的下标
if(k>=0){
for(j=1;j<strlen(first_set[k]);j++){
if(first_set[k][j]=='$'){//非终结符的first集有空
flag=1;
continue;
}
row=get_non(first_set[k][j]);
M[col][row]=i;
}
}
if(form[i].formula[3]=='$')
{ flag=1;//printf("%c##########################\n",form[i].formula[3]);
}
if(flag){//右部为空,或者右部的first集有空
for(j=1;j<strlen(follow_set[col]);j++){
if(follow_set[col][j]=='#')
row=strlen(non_ter);
else row=get_non(follow_set[col][j]);
M[col][row]=i;
}
}
}
}
}
鄙人不才,欢迎找错。
实验要求:
输入文法及待分析的输入串,输出其预测分析过程及结果。(基本要求就是:所有字符都只有一个字符组成,不能出现A*等字符,你可自行修改自己的文法后在用下面的代码)
注明:代码分了多个写,主函数是1.cpp代码如下(后期我会再发个链接过来可直接看到源文件,对不太熟悉VS工具的比较有帮助),想看中间结果的话可以将注释解开即可:
#include"head.h"
#include"apart_from.h"
#include"first.h"
#include"follw.h"
#include"table.h"
#include"judge.h"
int main(){
int i=0,j;
while((scanf("%s",form[i].formula),form[i].formula[0])!='#'){
i++;
}
sum = i;
apart();
First();
Follow();
printf("非终结符:\n");
printf("%s\n",ter_symbol);
printf("终结符:\n");
printf("%s\n",non_ter);
/*
printf("first集:\n");
for(j=0;j<strlen(ter_symbol);j++)
printf("%s\n",first_set[j]);
printf("follow集:\n");
for(j=0;j<strlen(ter_symbol);j++)
printf("%s\n",follow_set[j]);
*/
getTable();
//printTable();//输出预测表
printf("输入串(以‘#’号键结束):\n");
scanf("%s",inter_symbol);
while(inter_symbol[strlen(inter_symbol)-1]!='#'){
printf("输入串没有以‘#’号键结束,请重新输入:\n");
scanf("%s",inter_symbol);
}
printf("步骤 符号栈 输入串 所用产生式\n");
printf("---- ------ ------ ----------\n");
Judge();
return 0;
}
apart_from.h的代码:
void apart(){
int i,len,k=0,j,l,p;
for(i=0;i<sum;i++){
for(j=0;j<k;j++){
if(ter_symbol[j]==form[i].formula[0])
break;
}
if(j==k)
ter_symbol[k++] = form[i].formula[0];
}//非终结符
ter_symbol[k]='\0';
k=0;
for(i=0;i<sum;i++){
len = strlen(form[i].formula);
for(j=3;j<len;j++){
if(form[i].formula[j]=='$')
break;
for(l=0;l<strlen(ter_symbol);l++){
if(form[i].formula[j]==ter_symbol[l])
break;
}
for(p=0;p<k;p++){
if(form[i].formula[j]==non_ter[p])
break;
}
if(l==strlen(ter_symbol)&&p==k){
non_ter[k++]=form[i].formula[j];
}
}
}//终结符
non_ter[k]='\0';
}
head.h的代码:
#include<stdio.h> #include<string.h> typedef struct { char formula[200];//表达式 }grammerElement; grammerElement form[200]; //原始文法的产生式集 int sum; char ter_symbol[200];//非终结符号 char non_ter[200];//终结符号 char inter_symbol[400];//输入符号 char first_set[100][100];//各产生式右部的FIRST集 char follow_set[100][100];//各产生式左部的FOLLOW集 int M[200][200];//分析表 //判断是非终结符 int get_ter(char a){ for(int i=0;i<strlen(ter_symbol);i++) if(ter_symbol[i]==a) return i; return -1; } //判断是终结符 int get_non(char a){ for(int i=0;i<strlen(non_ter);i++){ if(non_ter[i]==a) return i; } return -1; } //判断将要加入的first集的终结符是否已经存在。 int is_sameFir(int col,int stop,char a){ for(int i=1;i<stop;i++){ if(first_set[col][i]==a) return 0; } return 1; } //判断将要加入的follow集的终结符是否已经存在。 int is_sameFol(int col,int stop,char a){ for(int i=1;i<stop;i++){ if(follow_set[col][i]==a) return 0; } return 1; } void printTable(){ for(int i=0;i<strlen(ter_symbol);i++){ for(int j=0;j<strlen(non_ter)+1;j++) printf("%d ",M[i][j]); printf("\n"); } }
first.h的代码:
//求一个非终结符的first集 int getFirst(char a,int col){ int i,j,k=1,l,p; for(i=0;i<sum;i++){ if(form[i].formula[0]==a){ for(j=0;j<strlen(non_ter);j++){ if(form[i].formula[3]==non_ter[j]) break; } //判断是否是终结符 if(j<strlen(non_ter)){ if(is_sameFir(col,k,form[i].formula[3])) first_set[col][k++]=form[i].formula[3]; continue; }//右部首字母是终结符; else if(form[i].formula[3]=='$'){ if(is_sameFir(col,k,'$')) first_set[col][k++]='$'; continue; }//右部首字母是kong; else if(form[i].formula[3]==a) continue;//右部首字母是自己; else{//printf("%d 1\n",col); for(l=3;l<strlen(form[i].formula);l++){//循环表达式找 for(j=0;j<strlen(ter_symbol);j++){//printf("%d 2\n",col); if(form[i].formula[l]==ter_symbol[j]) break; }//找到非终结符的下标 if(j==strlen(ter_symbol)){//printf("%d 3\n",col); if(is_sameFir(col,k,form[i].formula[l])) first_set[col][k++]=form[i].formula[l]; break; }//循环中碰到终结符,结束 if(first_set[j][0]=='0') getFirst(form[i].formula[l],j);//printf("%d 4\n",col);}//first集未求,递归求first集 for(p=1;p<strlen(first_set[j]);p++){//检查first集有没有空 if(first_set[j][p]=='$') break; else if(is_sameFir(col,k,first_set[j][p])) //把非空的加进first集 first_set[col][k++]=first_set[j][p];//printf("%d 5\n",col);} } if(p==strlen(first_set[j])){//没有非空的就跳出 //flag=1; break; } } if(l==strlen(form[i].formula)&&is_sameFir(col,k,'$')) first_set[col][k++]='$'; } } } first_set[col][k]='\0'; first_set[col][0]='1';//标志已经求得first集 return 0; } void First(){ int i,len_ter=strlen(ter_symbol); for(i=0;i<len_ter;i++){ first_set[i][0]='0'; } for(i=0;i<len_ter;i++){ if(first_set[i][0]=='0') getFirst(ter_symbol[i],i); } }
follow.h的代码:
int getFollow(char a,int col){ int i,j,len,k=1,p,l,flag; if(col==0) k=2; for(i=0;i<sum;i++){ len=strlen(form[i].formula); for(j=3;j<len;j++){ flag=0; if(form[i].formula[j]==a){ if(j<len-1){//printf("%d %c1\n",col,a);//当前非终结符不是最终字符 for(p=0;p<strlen(ter_symbol);p++){ if(form[i].formula[j+1]==ter_symbol[p]) break; }//找到后边非终结符的下标 if(p==strlen(ter_symbol)){//终结符 if(is_sameFol(col,k,form[i].formula[j+1])) follow_set[col][k++]=form[i].formula[j+1];//printf("%d 2\n",col); continue; } else{//printf("%d 3\n",col);//非终结符 for(l=1;l<strlen(first_set[p]);l++) if(first_set[p][l]=='$')//将来会有漏洞 {flag=1;} else if(is_sameFol(col,k,first_set[p][l])){ follow_set[col][k++]=first_set[p][l]; } } }//if/ if(j==len-1||flag){//if(col==2) return 0;//printf("%d 4 %s %s\n",col,follow_set[0],follow_set[1]);// p=get_ter(form[i].formula[0]);//找到后边非终结符的下标 if(a==form[i].formula[0]) {//printf("%d 4 %s %s\n",col,follow_set[0],follow_set[1]); break;} if(follow_set[p][0]=='0'){ getFollow(ter_symbol[p],p); //printf("%d %c5\n",col,ter_symbol[p]); } for(l=1;l<strlen(follow_set[p]);l++){ if(is_sameFol(col,k,follow_set[p][l])) follow_set[col][k++]=follow_set[p][l]; } } } } } if(strlen(follow_set[col])>1) follow_set[col][0]='1'; follow_set[col][k]='\0'; return 0; } void Follow(){ int i; for(i=0;i<strlen(ter_symbol);i++){ follow_set[i][0]='0'; } //follow_set[0][0]='1'; follow_set[0][1]='#'; for(i=0;i<strlen(ter_symbol);i++){ // printf("%s\n",follow_set[0]); if(follow_set[i][0]=='0') getFollow(ter_symbol[i],i); //printf("%c...............\n",ter_symbol[i]);} } }
judge.h的代码:
int top;
char stack[200];
int x;
void Judge(){
stack[0]='#';
stack[1]=form[0].formula[0];
int flag=1,step=0;
int i,j,l;
char print[100];
top=1;
x=0;//printf("---- ------ ------\n");
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
printf("\n");
while(flag){
if(get_non(stack[top])>=0){
if(stack[top]==inter_symbol[x]){
x++;//终结符匹配上
top--;
if(step<10)
printf(" %d ",step++);
else
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
printf("\n");
}
else
break;
}
else if(stack[top]=='#'){
if(stack[top]==inter_symbol[x])
flag=0;//彻底结束
else
break;
}
else{
int col=get_ter(stack[top]);
int row=get_non(inter_symbol[x]);
if(inter_symbol[x]=='#')
row=strlen(non_ter);
if(M[col][row]>=0){//非终结符
if(form[M[col][row]].formula[3]=='$'){
top--;
}
else
{
for(i=strlen(form[M[col][row]].formula)-1;i>=3;i--){
stack[top++]=form[M[col][row]].formula[i];
}
top--;
}
if(step<10)
printf(" %d ",step++);
else
printf(" %d ",step++);
for(l=0;l<=top;l++)
printf("%c",stack[l]);
for(l=0;l<=22-top+x;l++)
printf(" ");
for(l=x;l<strlen(inter_symbol);l++)
printf("%c",inter_symbol[l]);
for(l=0;l<=(11-strlen(inter_symbol));l++)
printf(" ");
printf("%s",form[M[col][row]].formula);
printf("\n");
}
else break;
}
}
if(flag){
printf("输入串无法匹配成功!\n");
}
else{
printf("输入串匹配成功!\n");
}
}
table.h的代码:
void getTable(){//ter_symbol[200];//非终结符号
// non_ter[200];//终结符号
int i,j,k,col,row,flag=0;
for(i=0;i<strlen(ter_symbol);i++){
for(j=0;j<strlen(non_ter)+1;j++)
M[i][j]=-1;
}
for(i=0;i<sum;i++){//printf("lalallallalallalallalalla\n");
flag=0;
if((row=get_non(form[i].formula[3]))>=0){//printf("%d %d 1\n",row,i);
col=get_ter(form[i].formula[0]);
M[col][row]=i;
}//右部是终结符
else if((row=get_non(form[i].formula[3]))==-1){//非终结符和空
//if()
col=get_ter(form[i].formula[0]);//左部是行坐标
k=get_ter(form[i].formula[3]);//右部非终结符的下标
if(k>=0){
for(j=1;j<strlen(first_set[k]);j++){
if(first_set[k][j]=='$'){//非终结符的first集有空
flag=1;
continue;
}
row=get_non(first_set[k][j]);
M[col][row]=i;
}
}
if(form[i].formula[3]=='$')
{ flag=1;//printf("%c##########################\n",form[i].formula[3]);
}
if(flag){//右部为空,或者右部的first集有空
for(j=1;j<strlen(follow_set[col]);j++){
if(follow_set[col][j]=='#')
row=strlen(non_ter);
else row=get_non(follow_set[col][j]);
M[col][row]=i;
}
}
}
}
}
鄙人不才,欢迎找错。
相关文章推荐
- 实验二 预测分析算法的设计与实现
- 编译原理之算术表达式文法的预测分析算法c实现
- 设计有穷自动机DFA实现C++简单程序的词法分析、扫描(编译原理实验) 推荐
- 编译原理(五) LL(1)文法分析法(预测分析表的构造算法C++实现)
- 编译原理之LR(0)分析算法的c实现
- 编译原理实验(三)词法语法分析综合设计
- 编译原理语法分析实验(Java实现)
- 编译原理 实验3 递归下降语法分析程序设计
- 编译原理 实验总结及实现分析 递归下降与算符优先原理
- 算法与分析设计 实验——插入排序C语言实现
- 编译原理实验之语法分析(算符优先分析算法(C语言))
- 编译原理(八) 算符优先分析法(分析过程的算法和C++实现)
- 吉首大学_编译原理实验题_基于预测方法的语法分析程序的设计【通过代码】
- 编译原理实验二——语法分析(预测分析)
- 编译原理-LL(1)预测分析实验 c源代码
- 编译原理(八) 算符优先分析法(分析过程的算法和C++实现)
- 编译原理之算术表达式的词法分析算法c实现
- 编译原理(五) LL(1)文法分析法(预测分析表的构造算法C++实现)
- 编译原理LL1文法分析表算法实现
- 算法设计与分析--霍夫曼树编码(C++实现)