您的位置:首页 > 其它

编译原理之算术表达式文法的预测分析算法c实现

2014-10-11 12:36 691 查看
预测分析法是一种确定的自顶向下的分析方法,一个文法能否用预测分析法进行分析,关键看其是否为LL(1)文法,一个预测分析器由三个部分组成:

#预测分析程序

#先进后出栈

#预测分析表

下面我们以一个具体的实例来看预测分析器的实现算法,其他文法可照推:

已知表达式文法:(只含*、+、)、(、i算术表达式的判断文法)

E->E+T|T

T->T*F|F

F->i|(E)

设计预测分析程序。

由于文法中含有左递归,所以必须先消除左递归,消除后为:

E->TE'

E'->+TE'|e

T->FT'

T'->*FT'|e

F->i|(E)

**说明:e代表空串**

进一步可得如下预测分析表:

i
+
*
(
)
#
E
TE’
TE’
E’
+TE’
e
e
T
FT’
FT’
T’
e
*FT’
e
e
F
i
(E)
预测分析程序如下:
/*构造表达式文法的预测分析器
将表达式各字符编码,再进行表达式文法的预测分析 */
#include<stdio.h>
typedef int Mat[5][6][3];//定义三维数组Mat,用于存储编码后的表达式文法的预测分析表
void ForecastAnalysisDevice(char *expressions,Mat forecasttable);//表达式文法的预测分析器
int main(){
Mat forecasttable = {2,1,9,9,9,9,9,9,9,2,1,9,9,9,9,9,9,9,
9,9,9,22,2,1,9,9,9,9,9,9,8,9,9,8,9,9,
4,3,9,9,9,9,9,9,9,4,3,9,9,9,9,9,9,9,
9,9,9,8,9,9,33,4,3,9,9,9,8,9,9,8,9,9,
11,9,9,9,9,9,9,9,9,44,0,55,9,9,9,9,9,9};
//编码表:0=E,1=E',2=T,3=T',4=F,11=i,22=+,33=*,44=(,55=),66=#,8=空串,9=栈顶空
char expressions[100]; //表达式
printf("###################################\n");
printf("请输入算术表达式...\nExpressions=
");
scanf("%s",expressions);
printf("-\n");
ForecastAnalysisDevice(expressions,forecasttable); //进行表达式文法的预测分析
printf("-----------------------------------\n");
printf("###################################\n");
return 0;
}
void ForecastAnalysisDevice(char *expressions,Mat forecasttable){
//表达式文法的预测分析器,expressions为表达式,forecasttable为表达式文法的预测分析表
char string[5] = {'i','+','*','(',')'}; //表达式字符集
int i = 0,j = 0,k,l;
int indexx,indexy,semp,sum;
int integer[100];
while(expressions[i] != '\0'){ //对表达式进行归一化编码转换
switch (expressions[i]){
case 105:integer[j++] = 0;break;
case 43:integer[j++] = 1;break;
case 42:integer[j++] = 2;break;
case 40:integer[j++] = 3;break;
case 41:integer[j++] = 4;break;
case 35:integer[j++] = 5;break;
}
i++;
}
integer[i++] = 5;
sum = i;
j = 0;
int temp[12] = {9,9,9,9,9,9,9,9,9,9,9,0};//初始化预测分析栈
while(temp[11] != 9){
for(i = 0;i < 12;i++){ //找到栈顶
if(temp[i] != 9)
break;
}
if(temp[i] == 55){ //“)”匹配
printf("\")\"匹配\n");
temp[i] = 9;
i = i+1;
j = j+1;
}
indexx = temp[i]; //预测分析表x下标,即第一纬下标
indexy = integer[j]; //预测分析表y下标,即第二纬下标
if(forecasttable[indexx][indexy][0] != 11 && forecasttable[indexx][indexy][0] != 22 && forecasttable[indexx][indexy][0]
!= 33 && forecasttable[indexx][indexy][0] != 44 && forecasttable[indexx][indexy][0] != 55 && forecasttable[indexx][indexy][0] != 66 && forecasttable[indexx][indexy][0] != 9 && forecasttable[indexx][indexy][0] != 8){
//产生式推导仍为非终结符
k = 2;
l = i;
while(k >= 0){
if(forecasttable[indexx][indexy][k] != 9){
if(forecasttable[indexx][indexy][k] > 9){ //大编码变形,转化为预测分析表列下标
semp = forecasttable[indexx][indexy][k]/10;
semp *= 10+1;
temp[l] = forecasttable[indexx][indexy][k] - semp;
l--;
}else{
temp[l] = forecasttable[indexx][indexy][k];
l--;
}
}
k--;
}
}
else if(forecasttable[indexx][indexy][0] == 9){ //出错处理
printf("...\n分析意外终止...\n输入的串\"%s\"不可接受!\n",expressions);
return ;
}
else if(forecasttable[indexx][indexy][0] == 8) //产生式推导为空
temp[i] = 9;
else{ //产生式推导出终结符
k = 2;
l = i;
while(k >= 0){
if(forecasttable[indexx][indexy][k] != 9){
temp[l] = forecasttable[indexx][indexy][k];
l--;
}
k--;
}
l++;
temp[l] -= (temp[l]/10)*10;
printf("\"%c\"匹配\n",string[temp[l]-1]);
//打印匹配字符
temp[l] = 9;
if(j < sum-1) //避免表达式遍历越界
j++;
}
}
printf("---------\n");
printf("Congratulation!\n输入的串\"%s\"可接受!\n",expressions);//表达式满足给定文法规则
return ;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: