清华大学计算机系列教材 编译原理第二版 张素琴,吕映芝等编著 P56 5.6 典型例题及解答 例题一为例,进行预测分析 tip:预测分析法和回归分析法都是自顶向下的方法,预测分析法只能分析满足LL1的文法 简单示例,为清楚原理 //课本P96 例1 #include "stdafx.h" #include <stdio.h> #include <iostream> #define MAXLEN 100 //栈的最大容量 using namespace std; int analysisStack[MAXLEN]={0,30};//分析栈 //略过词法分析阶段 //int shuru[MAXLEN]={1,1,1,2,3,0};//匹配 //int shuru[MAXLEN]={1,1,2,3,0};//不匹配 int shuru[MAXLEN]={1,3,0};//匹配 int inputLength=0; //输入串的长度 int leftString[MAXLEN]={};//剩余输入串 //定义产生式,根据题意,7条BNF,共7个产生式。每条最大长度不超过10 //右边的第一个符号为终结符 int product[10][10]={ {30,1,31,0}, {31,1,32,3,0}, {31,3,0}, {32,1,32,2,0}, {32,4,0}, {32,0}, {33,1,32,0}, {33,4,0}, }; void setLeftString()//设置剩余输入串,即要分析的字符串,词法分析的结果 { while (shuru[inputLength]!=0) { inputLength++; } int j=0;//指向分析串的指针,暂时的 for (j=0;j<=inputLength;j++) { leftString[j]=shuru[inputLength-j]; } } void outputAnalysis()//输出分析栈的内容 { printf("/n分析栈的内容:"); for (int i=1;i<MAXLEN;i++) { if (analysisStack[i]!=0)//打印非0元素 { printf("%d,",analysisStack[i]); } } } void outputLeftString()//输出剩余串 { printf("/n剩余输入串:"); for (int i=1;i<MAXLEN;i++) { if (leftString[i]!=0)//打印非0元素 { printf("%d,",leftString[i]); } } } int _tmain(int argc, _TCHAR* argv[]) { setLeftString(); int pointer1=1;//分析栈的指针 int pointer2=inputLength;//待分析串的指针 outputAnalysis(); outputLeftString(); int fenxicishu=0;//分析次数 while(fenxicishu<=20)//最多分析次数 { printf("/n/n第%d次分析结果:",fenxicishu+1); if (analysisStack[pointer1]==0 && leftString[pointer2]==0)//栈空,结束 { printf("栈空/n"); break; } else { if (analysisStack[pointer1]==leftString[pointer2])//分析栈起始符号和剩余输入串起始符号匹配 { printf("/n匹配"); analysisStack[pointer1]=0; pointer1--; leftString[pointer2]=0; pointer2--; fenxicishu++; } else { printf("/n不匹配,"); for(int i=0;i<10;i++)//产生式个数 { if(analysisStack[pointer1]==product[i][0])//左边匹配 { if (pointer1-pointer2==1) { analysisStack[pointer1]=0;//选择产生式->e pointer1--; break; } int k=i;//左边相同的产生式 while (analysisStack[pointer1]==product[k][0])//左边相同的产生式 { if (leftString[pointer2]==product[k][1])//右边以匹配的终结符开始 { break; } k++; } i=k; printf("找到产生式:%d->",product[i][0]); int productLength=0;//产生式的长度 while(product[i][productLength]!=0) { productLength++; printf("%d ",product[i][productLength]); } for (int j=1;j<productLength;j++)//产生式的长度 { analysisStack[j+pointer1-1]=product[i][productLength-j]; } pointer1=pointer1+productLength-2; } } } outputAnalysis(); outputLeftString(); fenxicishu++; } } if(analysisStack[1]!=0 || leftString[1]!=0 ) { printf("/n/n分析了%d次,仍没成功匹配/n/n",fenxicishu); } else { printf("/n/n成功匹配!!/n/n"); } system("pause"); return 0; }