语法分析实验.docx
- 文档编号:4014310
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:14
- 大小:224.17KB
语法分析实验.docx
《语法分析实验.docx》由会员分享,可在线阅读,更多相关《语法分析实验.docx(14页珍藏版)》请在冰点文库上搜索。
语法分析实验
湖南**大学**********学院
学生实验报告
姓名:
林*文年级专业班级**级计算机*班日期20**年**月*日成绩
课程名称
编译原理
实验名称
词法分析实验
实验类型
设计性
【实验目的、要求】
了解语法分析器的内部工作原理,通过在本次实验中运用一定的编程技巧,掌握对表达式进行处理的一种方法。
【实验内容】
语法分析实验可以选择自上而下的LL
(1)语法分析方法,也可以选择自下而上的算符优先分析法。
(学生自行选择)
算术表达式的文法可以是(可以根据需要适当改变):
E→E+E|E-E|E*E|E/E|(E)|i
根据算符优先分析法,将表达式进行语法分析,判断一个表达式是否正确。
【实验环境】
计算机、编程环境vc++6.0
【实验步骤、过程】
1功能描述
如参考C语言的运算符。
输入如下表达式(以分号为结束)和输出结果:
(1)10;输出:
正确
(2)1+2;输出:
正确
(3)(1+2)/3+4-(5+6/7);输出:
正确
(4)((1-2)/3+4;输出:
错误
(5)1+2-3+(*4/5);输出:
错误
注意:
为降低难度,表达式中不含变量(只含无符号整数);如果遇到错误的表达式,应输出错误提示信息(该信息越详细越好);测试用的表达式事先放在文本文件中,一行存放一个表达式,同时以分号分割。
同时将预期的输出结果写在另一个文本文件中,以便和输出进行对照.
2程序结构描述
1、定义语法结构体跟变量定义和数据栈的相关调用程序。
2、规约程序,如果跟语法中规约的相符就规约,否则就退出并提示错误。
3、计算运算符优先级构造程序。
4、计算数值(四则运算)。
5、对照表规约程序。
6、将字符串分成数据跟运算符进栈出栈操作。
7、将读取的字符转进行转译。
8、主函数调用程序。
3流程图(或原理图)
4关键代码
#include
#include
intright,result;//输出的标志
charguiyue[10][10]={"e+e","e-e","e*e","e/e","(e)","e"};//构造的规约对照表
intcount=0;//全局变量,获取文件的行数
charch[100][100];//ch存放读取文件的字符
typedefcharElemType;
#defineMAXSIZE100
//构造栈
typedefstructSeqStack
{
ElemTypedata[MAXSIZE];
inttop;
}SeqStack;
//初始化
voidinput()
{
while(gets(ch[count++]));
}
SeqStackSeqStackInit()
{
SeqStacks;
s.top=-1;
returns;
}
//入栈
SeqStackSeqStackPush(SeqStacks,ElemTypex)
{
if(s.top==MAXSIZE-1)
right=0;
else
{
s.top++;
s.data[s.top]=x;
}
returns;
}
//出栈
SeqStackSeqStackPop(SeqStacks)
{
ElemTypex;
if(s.top==-1)
right=0;
else
{
x=s.data[s.top];
s.top--;
}
returns;
}
//取栈顶元素
ElemTypeSeqStackGetTop(SeqStacks)
{
if(s.top==-1)
{
right=0;
return0;
}
else
return(s.data[s.top]);
}
/*['+']['-']['*']['/']['('][')']['#']
运['+']>><<<>>;
算['-']>><<<>>;
符['*']>>>><>>;
优['/']>>>><>>;
先['(']<<<<<=~;
级[')']>>>>~>>;
级['#']<<<<<~=';*/
//计算运算符优先级,根据上面的优先级表写出的函数
charprecede(chara,charb)
{
charr;
switch(b)
{
case'+':
case'-':
if(a=='('||a=='#')
r='<';
else
r='>';
break;
case'*':
case'/':
if(a=='*'||a=='/'||a==')')
r='>';
else
r='<';
break;
case'(':
if(a==')')
right=0;
else
r='<';
break;
case')':
if(a=='(')
r='=';
else
if(a=='#')
right=0;
else
r='>';
break;
case'#':
if(a=='(')
right=0;
else
if(a=='#')
r='=';
else
r='>';
break;
}
returnr;
}
//数值计算
intoperate(inta,charc,intb)
{
intres=0;
switch(c)
{
case'+':
res=a+b;
break;
case'-':
res=a-b;
break;
case'*':
res=a*b;
break;
case'/':
res=a/b;
break;
default:
break;
}
returnres;
}
//规约
boolstatute(char*s)
{
inti;
for(i=0;i<6;i++)
{
if(strcmp(s,guiyue[i])==0)//跟构造的规约对照表对照
returntrue;
}
returnfalse;
}
voidjudge(inti)
{
result=1;
intl=strlen(ch[i]);//l每行的个数a存放数值
inta2,b2;//出栈数值元素的存放a2b2
charstr[5]="",a,b,theta;//出栈元素的存放a放数栈元素theta运算符栈元素b数栈元素
str便于规约
SeqStackoptr,opnd,opnd2;//定义出2个栈运算符栈运算数栈
optr=SeqStackInit();//运算符栈,字符元素
opnd=SeqStackInit();//运算数栈,实数元素
opnd2=SeqStackInit();
optr=SeqStackPush(optr,'#');
intj=0;
while(!
((ch[i][j]=='#')&&(SeqStackGetTop(optr)=='#')))//判断栈低跟ch[]中的
是否不是#
{
if(ch[i][j]==''||ch[i][j]=='\t')
{
while(j j++;//清除空格 } elseif(ch[i][j]>='0'&&ch[i][j]<='9') { opnd=SeqStackPush(opnd,'e'); opnd2=SeqStackPush(opnd2,ch[i][j]); j++; }//将数值压进运算数栈 else//ch[][]中是运算符 { switch(precede(SeqStackGetTop(optr),ch[i][j]))//比较栈里的运算符 跟ch中的运算符 { case'<': //参考算符优先级表 optr=SeqStackPush(optr,ch[i][j]); j++; break; case'=': //参考算符优先级表 optr=SeqStackPop(optr); j++; break; case'>': //参考算符优先级表 theta=SeqStackGetTop(optr); optr=SeqStackPop(optr); b=SeqStackGetTop(opnd); opnd=SeqStackPop(opnd); a=SeqStackGetTop(opnd); opnd=SeqStackPop(opnd);//以上是对一系列出2个栈(运算符栈 运算数栈)的操作 str[0]='e'; str[1]=theta; str[2]='e'; if(statute(str)==true)//规约成功则进行数值计算 { b2=SeqStackGetTop(opnd2)-'0';//将字符转换成数值 opnd2=SeqStackPop(opnd2); a2=SeqStackGetTop(opnd2)-'0';//将字符转换成数值 opnd2=SeqStackPop(opnd2); opnd=SeqStackPush(opnd,'e'); opnd2=SeqStackPush(opnd2,operate (a2,theta,b2)+'0');//调用数值运算 result=SeqStackGetTop(opnd2)-'0';//取栈顶元素 } else//规约失败则表达式错误 { right=0; return; } break; default: return; } } } } voidprocess() { for(inti=0;i { right=1; printf("第%d的表达式: %s\n经判断: ",i+1,ch[i]);//显示读取文件的行数跟表达式 judge(i); //正确错误的输出 if(right==0) printf("表达式错误! ! ! \n\n"); else printf("表达式正确! \t其结果: %d\n\n",result); } } intmain() { freopen("D: \\colin.txt","r",stdin);//读取实验文件代码 input(); process(); return0; } 【实验结果和总结】(对实验结果进行相应分析,或总结实验的心得体会,并提出实验的改进意见) 1实验结果记录(截图) 实验文件: (截图) 实验结果: (截图) 2实验总结遇到的问题所用的时间所用方法和手段以及心得体会 这个程序存在很多的不足和漏洞,但是我想这只是我的初步程序,应该花更多的时间去考其他的可能性,尽力的完善它。 所用的时间: 程序花费3天。 遇到的问题; 1.不会使用栈操作。 2.不会构造计算运算符的优先级的函数。 3.规约函数没有对照表不会处理。 所用的方法和手段: 1.与同学交流,并上网查询,学习好栈操作的知识。 2.根据网上的资料提示,事先先构造好优先级表,然后用函数将其描述出来。 3.构造对照表,将字符赋给一个空串,然后进行比较判断。 心得体会: 经过这次的编译原理实验,不仅仅加深并且更熟识掌握的语言。 而且在遇到问题无从下手的时候,跟同学交流,还有差资料,真的是不错的选择。 而且经过这次的实验,我觉得我不应该是为了完成任务而去写这个程序,而是为了学得更多的知识而努力奋斗。 指导教师签名: 2012年11月10日 【备注】
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语法分析 实验