清华大学计算机系列教材
编译原理第二版
张素琴,吕映芝等编著
P56 5.6 典型例题及解答 例题一为例,进行预测分析
tip:预测分析法和回归分析法都是自顶向下的方法,预测分析法只能分析满足LL1的文法
简单示例,为清楚原理
#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;
}