编译原理实验报告实验二语法分析算符优先2.docx
《编译原理实验报告实验二语法分析算符优先2.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告实验二语法分析算符优先2.docx(11页珍藏版)》请在冰豆网上搜索。
![编译原理实验报告实验二语法分析算符优先2.docx](https://file1.bdocx.com/fileroot1/2022-12/16/2e9a23c3-fa37-4a83-b31d-2a71b7a12182/2e9a23c3-fa37-4a83-b31d-2a71b7a121821.gif)
编译原理实验报告实验二语法分析算符优先2
华北水利水电学院编译原理实验报告
一、实验题目:
语法分析(算符优先分析程序)
(1)选择最有代表性的语法分析方法算符优先法;
(2)选择对各种常见程序语言都用的语法结构,如赋值语句(尤指表达式)作为分析对象,并且与所选语法分析方法要比较贴切。
二、实验内容
(1)根据给定文法,先求出FirstVt和LastVt集合,构造算符优先关系表(要求算符优先关系表输出到屏幕或者输出到文件);
(2)根据算法和优先关系表分析给定表达式是否是该文法识别的正确的算术表达式(要求输出归约过程)
(3)给定表达式文法为:
G(E’):
E’→#E#
E→E+T|T
T→T*F|F
F→(E)|i
(4)分析的句子为:
(i+i)*i和i+i)*i
三、程序源代
#include
#include
#include
#include
#defineSIZE128
charpriority[6][6];//算符优先关系表数组
charinput[SIZE];//存放输入的要进行分析的句子
charremain[SIZE];//存放剩余串
charAnalyseStack[SIZE];//分析栈
voidanalyse();
inttestchar(charx);//判断字符X在算符优先关系表中的位置
voidremainString();//移进时处理剩余字符串,即去掉剩余字符串第一个字符
intk;
voidinit()//构造算符优先关系表,并将其存入数组中
{
priority[0][0]='>';
priority[0][1]='<';
priority[0][2]='<';
priority[0][3]='<';
priority[0][4]='>';
priority[0][5]='>';
priority[1][0]='>';
priority[1][1]='>';
priority[1][2]='<';
priority[1][3]='<';
priority[1][4]='>';
priority[1][5]='>';
priority[2][0]='>';
priority[2][1]='>';
priority[2][2]='$';//无优先关系的用$表示
priority[2][3]='$';
priority[2][4]='>';
priority[2][5]='>';
priority[3][0]='<';
priority[3][1]='<';
priority[3][2]='<';
priority[3][3]='<';
priority[3][4]='=';
priority[3][5]='$';
priority[4][0]='>';
priority[4][1]='>';
priority[4][2]='$';
priority[4][3]='$';
priority[4][4]='>';
priority[4][5]='>';
priority[5][0]='<';
priority[5][1]='<';
priority[5][2]='<';
priority[5][3]='<';
priority[5][4]='$';
priority[5][5]='=';
}
voidanalyse()//对所输入的句子进行算符优先分析过程的函数
{
FILE*fp;
fp=fopen("li","a");
inti,j,f,z,z1,n,n1,z2,n2;
intcount=0;//操作的步骤数
chara;//用于存放正在分析的字符
charp,Q,p1,p2;
f=strlen(input);//测出数组的长度
for(i=0;i<=f;i++)
{
a=input[i];
if(i==0)
remainString();
if(AnalyseStack[k]=='+'||AnalyseStack[k]=='*'||AnalyseStack[k]=='i'||AnalyseStack[k]=='('||AnalyseStack[k]==')'||AnalyseStack[k]=='#')
j=k;
else
j=k-1;
z=testchar(AnalyseStack[j]);//从优先关系表中查出s[j]和a的优先关系
if(a=='+'||a=='*'||a=='i'||a=='('||a==')'||a=='#')
n=testchar(a);
else//如果句子含有不是终结符集合里的其它字符,不合法
{
printf("错误!
该句子不是该文法的合法句子!
\n");
break;
}
p=priority[z][n];
if(p=='$')
{
printf("错误!
该句子不是该文法的合法句子!
\n");
return;
}
if(p=='>')
{for(;;)
{
Q=AnalyseStack[j];
if(AnalyseStack[j-1]=='+'||AnalyseStack[j-1]=='*'||AnalyseStack[j-1]=='i'||AnalyseStack[j-1]=='('||AnalyseStack[j-1]==')'||AnalyseStack[j-1]=='#')
j=j-1;
else
j=j-2;
z1=testchar(AnalyseStack[j]);
n1=testchar(Q);
p1=priority[z1][n1];
if(p1=='<')//把AnalyseStack[j+1]~AnalyseStack[k]归约为N
{
count++;
printf("(%d)%s\t%10c\t%5c%17s\t归约\n",count,AnalyseStack,p,a,remain);
fprintf(fp,"(%d)%s\t%17s\t%s\n",count,AnalyseStack,remain,"归约");
k=j+1;
i--;
AnalyseStack[k]='N';
intr,r1;
r=strlen(AnalyseStack);
for(r1=k+1;r1AnalyseStack[r1]='\0';
break;
}
else
continue;
}
}
else
{
if(p=='<')//表示移进
{
count++;
printf("(%d)%s\t%10c\t%5c%17s\t移进\n",count,AnalyseStack,p,a,remain);
fprintf(fp,"(%d)%s\t%17s\t%s\n",count,AnalyseStack,remain,"移进");
k=k+1;
AnalyseStack[k]=a;
remainString();
}
else
{
if(p=='=')
{
z2=testchar(AnalyseStack[j]);
n2=testchar('#');
p2=priority[z2][n2];
if(p2=='=')
{
count++;
printf("(%d)%s\t%10c\t%5c%17s\t接受\n",count,AnalyseStack,p,a,remain);
fprintf(fp,"(%d)%s\t%17s\t%s\n",count,AnalyseStack,remain,"接受");
printf("该句子是该文法的合法句子。
\n");
fprintf(fp,"%s","该句子是该文法的合法句子。
\n");
break;
}
else
{
count++;
printf("(%d)%s\t%10c\t%5c%17s\t移进\n",count,AnalyseStack,p,a,remain);
fprintf(fp,"(%d)%s\t%17s\t%s\n",count,AnalyseStack,remain,"移进");
k=k+1;
AnalyseStack[k]=a;
remainString();
}
}
else
{
printf("错误!
该句子不是该文法的合法句子!
\n");
fprintf(fp,"%s","错误!
该句子不是该文法的合法句子。
\n");
break;
}
}
}
}
fclose(fp);
}
inttestchar(charx)
{
intm;
if(x=='+')
m=0;
if(x=='*')
m=1;
if(x=='i')
m=2;
if(x=='(')
m=3;
if(x==')')
m=4;
if(x=='#')
m=5;
returnm;
}
voidremainString()
{
inti,j;
i=strlen(remain);
for(j=0;j
remain[j]=remain[j+1];
remain[i-1]='\0';
}
voidmain()
{
intm,n;
chars1[6]={'+','*','i','(',')','#'};
init();
printf("文法为:
\n");
printf("(0)E'->#E#\n");
printf("
(1)E->E+T\n");
printf("
(2)E->T\n");
printf("(3)T->T*F\n");
printf("(4)T->F\n");
printf("(5)F->(E)\n");
printf("(6)F->i\n");
FILE*fp;
fp=fopen("li","w");
fprintf(fp,"%s","要分析的文法为:
\n");
fprintf(fp,"%s","(0)E'->#E#\n");
fprintf(fp,"%s","
(1)E->E+T\n");
fprintf(fp,"%s","
(2)E->T\n");
fprintf(fp,"%s","(3)T->T*F\n");
fprintf(fp,"%s","(4)T->F\n");
fprintf(fp,"%s","(5)F->(E)\n");
fprintf(fp,"%s","(6)F->i\n");
fprintf(fp,"%s","优先关系表为:
\n");
fprintf(fp,"%s","+*i()#\n");
for(m=0;m<6;m++)
{
fprintf(fp,"%c",s1[m]);
for(n=0;n<6;n++)
{
fprintf(fp,"%c",priority[m][n]);
}
fprintf(fp,"%s","\n");
}
printf("-----------------------------------------\n");
printf("算符优先关系表\n");
printf("+*i()#\n");
printf("+><<<>>\n");
printf("*>><<>>\n");
printf("i>>>>\n");
printf("(<<<<=\n");
printf(")>>>>\n");
printf("#<<<<=\n");
printf("-----------------------------------------\n");
printf("请输入要进行分析的句子(以#号结束输入):
\n");
gets(input);//将输入的字符串存到数组中
fprintf(fp,"%s","需要分析的字符串为:
\n");
fprintf(fp,"%s",input);
fprintf(fp,"%s","\n");
fclose(fp);
printf("步骤栈优先关系当前符号剩余输入串移进或归约\n");
k=0;
AnalyseStack[k]='#';
AnalyseStack[k+1]='\0';
intlength,i;//初始化剩余字符串数组为输入串
length=strlen(input);//
for(i=0;iremain[i]=input[i];
remain[i]='\0';
analyse();//对所输入的句子进行算符优先分析过程的函数
}
四、测试结果
输入串(i+i)*i的算符优先分析过程
输入串i+i)*i的算符优先分析过程
五、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)
本次实验是算符优先分析法,这种方法特别有利于表达式分析,宜于手工实现。
算符优先分析过程是自下而上的规约过程,但这种规约未必是严格的最左规约,也就是说,算符优先分析法不是一种规范规约法。
通过这次实验,我对编译原理的理解又加深了一步。
本次试验很难,所以求助于网络和同学,然后经过自己的更改编辑,将结果存入名为li的文件中。
虽然对编程依旧感觉很困难,但是经过这次实验,我对存写文件,以及算符优先分析法的理解与学习又上升了一个台阶。