编译原理实验之预测分析算法的设计与实现

来源:互联网 发布:一楼土木人淘宝网 编辑:程序博客网 时间:2024/05/17 21:43

不要被大段的代码吓到,其实问题很简单,只需照着书上的过程走即可。

实验要求:

输入文法及待分析的输入串,输出其预测分析过程及结果。(基本要求就是:所有字符都只有一个字符组成,不能出现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;     }    }  } }}


鄙人不才,欢迎找错。
0 0
原创粉丝点击