编译原理 预测分析表的实现

 

/*
 *  程序功能:该程序为语法分析中的预测分析程序,
 *            可根据给出的文法分析一段表达式是否
 *            满足该文法。
 * 
 *  版本 :1.00
 * 
 *  给定文法:该程序中的文法为《编译原理》第96页例1的文法。
 *
 *  书本 :清华大学出版社 《编译原理》(第二版) 张素琴 吕映芝 蒋维杜 戴维兰 编著
 *
 *  完成时间:2007-12-12
 *
 *  coder : sparkvivid
 *
 
*/

 
 
#include
" stdio.h "
#include
" string.h "     /*程序中用到strcpy()函数*/

/*全局变量定义*/
char  inputString[ 10 ];  /*用来存储用户输入的字符串,最长为20个字符*/
char  stack[ 10 ];        /*用来进行语法分析的栈结构*/
int    base = 0 ;           /*栈底指针*/
int   top = 1 ;            /*栈顶指针*/
char  VT[ 4 ] = {'a','d','b','e'} ;    /*用来存放5个终结符*/
char  chanShengShi[ 10 ];           /*用来存放预测分析表M[A,a]中的一条产生式*/
int  firstCharIntex = 0 ;            /*如果a匹配产生式,则每次firstCharIntex 自增 1 */  
                                
/*firstCharIntex用来存放用户输入串的第一个元素的下标*/



/*自定义函数声明*/
char  pop() ;        /*弹出栈顶元素*/

int  push() ;        /*向栈内添加一个元素,成功返回1,若栈已满则返回0*/

int  search( char  temp)  ;     /*查找非终结符集合VT中是否存在变量temp,存在返回1,不存在返回0*/

int  M( char  A,  char  a)  ;     /* 若预测分析表M[A,a]中存在产生式,
                               则将该产生式赋给字符数组chanShengShi[10],并返回 1,
                               若M[A,a]中无定义产生式则返回 0
                             
*/


void  init()  ;               /*初始化数组inputString[10] 、栈 stack[10] 和 chanShengShi[10]*/  


int  yuCeFenXi()  ;           /* 进行输入串的预测分析的主功能函数,
                               若输入串满足文法则返回 1,不满足则返回0
                             
*/

void  printStack();           /*打印栈内元素    */
void  printinputString();     /*打印用户输入串  */                           


/*进入主函数*/
void  main()
{
  clrscr();    
  yuCeFenXi();   
/*调用语法预测分析函数*/
  getch();
}
                            

/*函数的定义*/    

int  yuCeFenXi()
{
  
char X;     /*X变量存储每次弹出的栈顶元素*/
  
char a;     /*a变量存储用户输入串的第一个元素*/
  
int i;
  
int counter=1;  /*该变量记录语法分析的步骤数*/
  
  init();         
/*初始化数组*/
  printf(
"wen fa  :     ");   /*输出文法做为提示*/
  printf(
"S -> aH         ");
  printf(
"H -> aMd | d    ");
  printf(
"M -> Ab |   ");
  printf(
"A -> aM | e     ");
  
  printf(
" input string ,'#' is a end sign  !!(aaabd#)  ");  /*提示用户输入将要测试的字符串*/
  scanf(
"%s",inputString);
  
  push(
'#');  
  push(
'S');
  
  printf(
" Counter-----Stack---------------Input string ");  /*输出结果提示语句*/
  
  
while(1)                       /*while循环为语法分析主功能语句块*/
  
{
    printf(
" ");
    printf(
"  %d",counter);      /*输出分析步骤数*/
    printf(
"         ");         /*输出格式控制语句*/
       printStack();                
/*输出当前栈内所有元素*/
       X
=pop();                     /*弹出栈顶元素赋给变量X*/
      printinputString();          
/*输出当前用户输入的字符串*/
      
if( search(X)==0 )           /*在终结符集合VT中查找变量X的值,存在返回 1,否则返回 0*/
      
{
        
if(X == '#')               /*栈已经弹空,语法分析结果正确,返回 1*/
        
{
            printf(
"success ... ");  /*语法分析结束,输入字符串符合文法定义*/
            
return 1;
        }

        
else  
        
{
            a 
= inputString[firstCharIntex];
            
if( M(X,a)==1 )          /*查看预测分析表M[A,a]是否存在产生式,存在返回1,不存在返回0*/
            
{
                
for(i=0;i<10;i++)     /* '$'为产生式的结束符,for循环找出该产生式的最后一个元素的下标*/
                
{
                  
if( chanShengShi[i]=='$' )     break;  
                }

                i
-- ;            /*因为 '$' 不是产生式,只是一个产生式的结束标志,所以i自减1*/
                
                
while(i>=0)
                
{
                  push( chanShengShi[i] );  
/*将当前产生式逆序压入栈内*/
                  i
-- ;    
                }

            }

            
else
            
{
                printf(
" error(1) !!");   /*若预测分析表M[A,a]不存在产生式,说明语法错误*/
                
return 0;
            }
        
        }
        
      }

      
else       /*说明X为终结符*/
      
{
        
if( X==inputString[firstCharIntex] )  /*如果X等于a,说明a匹配*/
        
{
            firstCharIntex
++;  /*输入串的第一个元素被约去,下一个元素成为新的头元素*/
        }

        
else
        
{
          printf(
" error(2) !! ");
          
return 0;    
        }
            
      }
    
      counter
++;    
  }

}
                     

void  init()
{
  
int i;
  
for(i=0;i<10;i++)
  
{
    inputString[i]
=NULL;    /*初始化数组inputString[10] */
    stack[i]
=NULL;        /*初始化栈stack[10]         */
    chanShengShi[i]
=NULL; /*初始化数组chanShengShi[10]*/
  }

}


int  M( char  A,  char  a)      /*文法定义因实际情况而定,该文法为课本例题的文法*/
{                         /*该函数模拟预测分析表中的二维数组              */
  
if( A=='S'&& a=='a' ) { strcpy(&chanShengShi[0],"aH$");  return 1; }
  
if( A=='H'&& a=='a' ) { strcpy(&chanShengShi[0],"aMd$"); return 1; }
  
if( A=='H'&& a=='d' ) { strcpy(&chanShengShi[0],"d$");   return 1; }
  
if( A=='M'&& a=='a' ) { strcpy(&chanShengShi[0],"Ab$");  return 1; }
  
if( A=='M'&& a=='d' ) { strcpy(&chanShengShi[0],"$");    return 1; }
  
if( A=='M'&& a=='b' ) { strcpy(&chanShengShi[0],"$");    return 1; }
  
if( A=='M'&& a=='e' ) { strcpy(&chanShengShi[0],"Ab$");  return 1; }
  
if( A=='A'&& a=='a' ) { strcpy(&chanShengShi[0],"aM$");  return 1; }
  
if( A=='A'&& a=='e' ) { strcpy(&chanShengShi[0],"e$");   return 1; }
  
else return 0/*没有定义产生式则返回0*/    
}


char  pop()           /*弹出栈顶元素,用topChar返回*/
{
  
char topChar;
  topChar
=stack[--top]; 
  
return topChar;
}


int  push( char  ch)
{
  
if( top>9 ) 
  
{
    printf(
" error : stack overflow ");      /*栈空间溢出*/
    
return 0;
  }
    
  
else
  
{
      stack[top]
=ch;  /*给栈顶空间赋值*/
    top
++;
    
return 1;
  }
  
}


int  search( char  temp)
{
  
int i,flag=0;       /*flag变量做为标志,若找到temp则赋1,否则赋0*/
  
for(i=0;i<4;i++)
  
{
    
if( temp==VT[i] ) /*终结符集合中存在temp*/
    
{
      flag
=1;    
      
break;
    }
    
  }

  
  
if(flag==1return 1;  /*flag==1说明已找到等于temp的元素*/
  
else return 0;
        
}


void  printStack()          /*输出栈内内容*/
{
  
int temp;
  
for(temp=1;temp<top;temp++)
  
{
    printf(
"%c",stack[temp]);    
  }
    
}


void  printinputString()    /*输出用户输入的字符串*/
{
  
int temp=firstCharIntex    ;
  printf(
"                     ");  /*该句控制输出格式*/
  
do{
        printf(
"%c",inputString[temp]);
        temp
++;
      }
while(inputString[temp-1]!='#');
  printf(
" ");     
}

 

运行结果截图 :

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值