编译原理提高型实验报告.docx
- 文档编号:11405536
- 上传时间:2023-02-28
- 格式:DOCX
- 页数:16
- 大小:142.48KB
编译原理提高型实验报告.docx
《编译原理提高型实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理提高型实验报告.docx(16页珍藏版)》请在冰豆网上搜索。
编译原理提高型实验报告
黄冈师范学院
提高型实验报告
实验课题OPG分析程序的设计___
(实验类型:
□综合型□设计型□应用型)
实验课程编译原理__
实验时间2014年12月16日
学生姓名
专业班级
学号
OPG分析表和分析程序的设计
实验目的和要求:
通过设计、编写和调试构造优先关系表的程序,了解构造算符优先关系表的步骤以及对文法的要求,并能够从文法G出发自动生成算符优先关系表。
实验原理分析(包括算法):
设计一个自动构造优先关系表的程序,该程序的输入是算符文法G,输出的是相应的优先关系表,并指出是否为算符优先文法。
(1)例如以下文法:
E->T+E|TT->F*T|FF->F↑P|PP->(E)|i
注:
I为整型常数后者为标识符表示的整型变量,使用中↑用**表示。
(2)构造优先分析表的算法,构造优先分析表需以下几个步骤:
1构造文法G中非终结符号的FIRSTVT集合
FIRSTVT集合用一个布尔数组F[P,a]表示,F是一个m*n的二维数组(m=文法G中非终结符号个数,n=文法G中终结符号个数)。
其中P∈VN,a∈VT,F[P,a]=TRUE的条件是当且仅当a∈FIRSTVT[P]。
对于文法G的所有非终结符号,构造布尔数组F[P,a]的算法(该算法使用一个数据结构STACK栈,用于存放相应于F[P,a]=TRUE的符号对(P,a))。
2构造文法G中非终结符号的LASTVT集合
类似于构造FIRSTVT集合,LASTVT集合用一个布尔数组L[P,a]表示,F是一个m*n的二维数组(m=文法G中非终结符号个数,n=文法G中终结符号个数)。
其中P∈VN,a∈VT,L[P,a]=TRUE的条件是当且仅当a∈LASTVT[P]。
对于文法G的所有非终结符号,构造布尔数组L[P,a]的算法(该算法使用一个数据结构STACK栈,用于存放相应于L[P,a]=TRUE的符号对(P,a))。
3构造文法G的优先关系表
使用文法G任何非终结符号的FIRSTVT集合和LASTVT集合,可以构造文法G的优先关系表。
优先关系表用一个数组R[a,b]表示,R是一个n*n的二维数组(n=文法G中终结符号个数)。
其中a,b∈VT,R[a,b]=‘=’、‘<’、‘>’或空(可能为多值),表示终结符号对(a,b)之间具有“=”“<”“>”优先关系或无优先关系。
4判断文法G是否为算符优先文法
构造出文法G的算符优先表R[a,b]后,判别文法G是否为算符优先文法的算法。
实验方案或步骤(流程图、主要数据结构、程序、小结)
·OPG分析程序的设计
·实验目的和要求:
通过设计,编写和调试算符优先分析程序,了解算符优先分析器的组成结构以及对文法的要求,掌握实现通用算符优先分析算法的方法。
·实验原理分析:
程序流程图
N
Y
结束
N
Y
N
Y
结束
算符优先分析属于自下而上的分析方法,该语法分析程序的输入是终结符号串(即单词符号串,以一个“#”结尾)。
如果输入串是句子,则输出“YES”,否则输出“NO”和错误信息。
算符优先分析过程与非终结符号无关,当由文法产生了优先关系之后文法就失去了作用。
本题目给出文法的目的是为了便于对语法分析结果进行验证。
(1)文法设算符优先文法G为:
E→E+T|T
T→T*F|F
F→P↑F|P
P→(E)|i
说明:
i为整形常数或者为表示符表示整形变量;使用中↑用**表示。
(2)优先关系表设优先关系表如下所示。
+
*
↑
i
(
)
#
+
>
<
<
<
<
>
>
*
>
>
<
<
<
>
>
↑
>
>
<
<
<
>
>
i
>
>
>
>
>
(
<
<
<
<
<
=
)
>
>
>
>
>
#
<
<
<
<
<
=
·实验方案或步骤
输出移近——规约过程。
源代码如下:
#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()
{
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);
k=j+1;
i--;
AnalyseStack[k]='N';
intr,r1;
r=strlen(AnalyseStack);
for(r1=k+1;r1 AnalyseStack[r1]='\0'; break; } else continue; } } else { if(p=='<')//表示移进 { count++; printf("(%d)%s\t%10c\t%5c%17s\t移进\n",count,AnalyseStack,p,a,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); printf("该句子是该文法的合法句子。 \n"); break; } else { count++; printf("(%d)%s\t%10c\t%5c%17s\t移进\n",count,AnalyseStack,p,a,remain); k=k+1; AnalyseStack[k]=a; remainString(); } } else { printf("错误! 该句子不是该文法的合法句子! \n"); break; } } } } } 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() { init(); printf("文法为: \n"); printf("(0)E'->#E#\n"); printf(" (1)E->E+T\n"); printf(" (2)E->T*F\n"); printf("(3)T->T\n"); printf("(4)T->F\n"); printf("(5)F->P↑F\n"); printf("(6)F->P\n"); printf("(7)P->(E)\n"); printf("(8)P->i\n"); printf("\n--------------------------------------------------------\n\n"); printf("**********************算符优先关系表********************\n"); printf("\t+\t*\ti\t↑\t(\t)\t#\n"); printf("+\t>\t<\t<\t<\t<\t>\t>\n"); printf("*\t>\t>\t<\t<\t<\t>\t>\n"); printf("↑\t>\t>\t<\t<\t<\t>\t>\n"); printf("i\t>\t>\t>\t\t\t>\t>\n"); printf("(\t<\t<\t<\t<\t(\t=\t\n"); printf(")\t>\t>\t>\t\t\t>\t>\n"); printf("#\t<\t<\t<\t<\t<\t\t=\n"); printf("==========================================================\n"); printf("请输入要进行分析的句子(以#号结束输入): \n"); gets(input);//将输入的字符串存到数组中 printf("步骤栈优先关系当前符号剩余输入串移进或归约\n"); k=0; AnalyseStack[k]='#'; AnalyseStack[k+1]='\0'; intlength,i;//初始化剩余字符串数组为输入串 length=strlen(input);// for(i=0;i remain[i]=input[i]; remain[i]='\0'; analyse();//对所输入的句子进行算符优先分析过程的函数 } 程序运行结果截图: 实验小结: 通过此次实验,使我对算符优先分析算法的设计过程有了更深一层的了解: 即先对已给定的文法按其产生式构造算符优先关系表,有了算符优先关系表并满足算符优先文法时,我们就可以对任意给定的符号串进行分析,形成句柄时就归约,否则就移进,最后判定输入串是否为该文法的句子。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 提高 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)