递归下降语法分析程序设计.docx
- 文档编号:24534098
- 上传时间:2023-05-28
- 格式:DOCX
- 页数:17
- 大小:480.83KB
递归下降语法分析程序设计.docx
《递归下降语法分析程序设计.docx》由会员分享,可在线阅读,更多相关《递归下降语法分析程序设计.docx(17页珍藏版)》请在冰豆网上搜索。
递归下降语法分析程序设计
编译方法实验报告
实验名称:
简单的语法分析程序设计
实验要求
1.功能:
对简单的赋值语句进行语法分析
随机输入赋值语句,输出所输入的赋值语句与相应的四元式
2.采用递归下降分析程序完成(自上而下的分析)
3.确定各个子程序的功能并画出流程图
4.文法如下:
5.编码、调试通过
采用标准输入输出方式。
输入输出的样例如下:
【样例输入】
x:
=a+b*c/d-(e+f)
【样例输出】(说明,语句和四元式之间用5个空格隔开)
T1:
=b*c (*,b,c,T1)
T2:
=T1/d (/,T1,d,T2)
T3:
=a+T2 (+,a,T2,T3)
T4:
=e+f (+,e,f,T4)
T5:
=T3-T4 (-,T3,T4,T5)
x:
=T5 (:
=,T5,—,x)
【样例说明】程序除能够正确输出四元式外,当输入的表达式错误时,还应能检测出语法错误,给出相应错误提示。
6.设计3—5个赋值语句测试实例,检验程序能否输出正确的四元式;当输入错误的句子时,检验程序能够给出语法错误的相应提示信息。
7.报告内容包括:
递归程序的调用过程,各子程序的流程图和总控流程图,详细设计,3-5个测试用例的程序运行截图及相关说明,有详细注释的程序代码清单等。
1。
语法分析递归下降分析算法
1。
1背景知识
无回溯的自上向下分析技术可用的先决条件是:
无左递归和无回溯。
无左递归:
既没有直接左递归,也没有间接左递归。
无回溯:
对于任一非终结符号U的产生式右部x1|x2|…|xn,其对应的字的首终结符号两两不相交.
如果一个文法不含回路,也不含以ε为右部的产生式,那么可以通过执行消除文法左递归的算法消除文法的一切左递归(改写后的文法可能含有以ε为右部的产生式).
文法的左递归消除算法:
1、将文法G的所有非终结符排序为U1,U2,…,Un;
2、For(i=1;i++;i≥n)
{
forj→1toi-1
把产生式Ui→Ujα替换成Ui→β1α|β2α|…|βmα;
其中:
Uj→β1|β2|…|βm消除Ui产生式中的直接左递归;
}
3。
化简改写之后的文法,删除多余产生式。
文法的直接左递归消除公式:
直接左递归形式:
U→Ux|y;
其中:
x,y∈(VN∪VT)*,y不以U打头。
直接左递归的消除:
U→yU‟
U‟→xU‟|ε
直接左递归的一般形式:
U→Ux1|Ux2|…|Uxm|y1|y2|…|yn;
其中:
xi≠ε,yi都不以U打头。
一般形式直接左递归的消除:
U→y1U‟|y2U‟|…|ynU‟
U‟→x1U‟|x2U‟|…|xmU‟|ε
回溯的消除的前提是文法不得含有左递归,可提左因子来消除回溯。
1。
2消除左递归
根据实验中给出的文法,进行消除左递归及回溯,得到下列的式子
A->V:
=E
E—〉TE’
E'—>+TE’|-TE’|null
T-〉FT’
T'-〉*FT’|/FT'|null
F—〉V|(E)
V->a|b|c|d|e。
..|z
2.详细设计及流程图
根据消除左递归后的文法,可以编写相应的函数。
2.1函数voidV()//V—>a|b|c|d|e.。
.|z
voidV()//V—>a|b|c|d|e。
..|z函数设计主要用来识别小写字母的,如果是小写字母的话,放入字符表,不是的话,输出语法错误。
函数比较简单,代码如下:
if(islower(s[sym]))
{
Table[list_n][0]=s[sym];//把读取的小写字母存入符号表,便于分析是生成中间代码
Table[list_n][1]=’\0';
list_n++;
sym++;
}
else
{
printf("OperandErrors!
\n");//运算对象错误
SIGN=1;
exit(0);
}
2.2函数voidA()//A—〉V:
=E
voidA()//A->V:
=E函数主要用来实现赋值的操作,流程图如图1所示。
图1A()函数流程图
2。
3函数voidE()//E->TE’
函数E()里面主要递归调用函数T()和E’().当没有出现语法错误时就可正常的运行.函数比较简单,代码如下:
{
if(SIGN==0)
{
T();
E1();
}
}
2.4函数voidT()//T->FT'
函数T()里面主要递归调用函数F()和T’’()。
当没有出现语法错误时就可正常的运行。
函数比较简单,代码如下:
if(SIGN==0)
{
F();
T1();
}
2.5函数voidE1()//E'-〉+TE’|—TE'|null
函数voidE1()//E'-〉+TE'|—TE'|null,主要用来实现加减法的语义分析.流程图如图2所示.
图2E1()函数流程图
2.6函数voidT1()//T'—>*FT'|/FT'|null
函数voidT1()//T’->*FT'|/FT'|null,主要用来实现乘除法的语义分析.流程图如图3所示。
图3T1()函数流程图
3.测试用例及截图
3。
1测试用例1及截图
用例1为实验要求上的的用例。
测试结果图4所示。
图4测试用例1及结果截图
3.2测试用例2及截图
用例2为出现大写字母,出现报错.测试结果图5所示.
图5测试用例2及结果截图
3。
3测试用例3及截图
用例3为随意编写用例。
测试结果图6所示.
图6测试用例3及结果截图
代码清单
#include〈stdio。
h〉
#include h> #include〈string.h> #include〈ctype.h〉 voidA();//A—>V: =E voidE();//E-〉TE' voidT();//T-〉FT’ voidE1();//E’-〉+TE'|—TE’|null voidT1();//T'->*FT’|/FT'|null voidF();//F-〉V|(E) voidV();//V—>a|b|c|d|e.。 。 |z chars[50],n=’1';//s[50]用于存放输入的赋值表达式 charTable[50][3];//产生中间代码所需的符号表 intSIGN,sym;//sym为s[50]中当前读入符号的下标 intlist_n=0;//符号表的下标 /*消除左递归及回溯 A->V: =E E-〉TE' E’->+TE'|—TE'|null T->FT' T’-〉*FT'|/FT'|null F->V|(E) V->a|b|c|d|e。 .。 |z */ intmain() { SIGN=0;//SIGN用于指示赋值表达式是否出现错误 sym=0; scanf(”%s”,&s); if(s[0]==’\0’)//没有输入的情况直接退出 return0; A(); if(s[sym]! ='\0’&&SIGN==0) { printf(”ERROR! \n”); exit(0); } return0; } voidA()//A-〉V: =E { V(); if(s[sym]==’: ’&&s[sym+1]=='=’)//判断赋值号是否有拼写错误 { sym+=2; E(); printf("%s: =%s",Table[list_n—2],Table[list_n—1]); printf("(: =,%s,-,%s)\n”,Table[list_n-1],Table[list_n—2]); } else { printf(”TheassignmentSymbolspellingmistakes! \n”);//赋值号拼写错误 SIGN=1; exit(0); } } voidV()//V->a|b|c|d|e。 。 .|z { if(islower(s[sym])) { Table[list_n][0]=s[sym];//把读取的小写字母存入符号表,便于分析是生成中间代码 Table[list_n][1]='\0’; list_n++; sym++; } else { printf(”OperandErrors! \n”);//运算对象错误 SIGN=1; exit(0); } } voidE()//E->TE' { if(SIGN==0) { T(); E1(); } } voidT()//T—>FT' { if(SIGN==0) { F(); T1(); } } voidE1()//E’-〉+TE’|-TE'|null { intp; if(SIGN==0) { if(s[sym]=='+’||s[sym]==’-’) { p=sym;//用p记录出现’+'或’-'时sym的值 sym++; T(); charch[3]; ch[0]='T’; ch[1]=n; ch[2]=’\0'; if(s[p]==’+') { printf(”%s: =%s+%s”,ch,Table[list_n—2],Table[list_n-1]);//输出三地址代码 printf("(+,%s,%s,%s)\n”,Table[list_n—2],Table[list_n—1],ch);//输出四元式 } else { printf(”%s: =%s-%s”,ch,Table[list_n-2],Table[list_n-1]);//输出三地址代码 printf(”(—,%s,%s,%s)\n”,Table[list_n—2],Table[list_n-1],ch);//输出四元式 } strcpy(Table[list_n-2],ch);//将当前结果归结式放在符号表中 list_n——; n++; E1(); } } } voidT1()//T'—>*FT'|/FT’|null { intp; if(SIGN==0) { if(s[sym]=='*’||s[sym]==’/') { p=sym; sym++; F(); charch[3]; ch[0]='T’; ch[1]=n; ch[2]=’\0'; if(s[p]==’*') { printf(”%s: =%s*%s”,ch,Table[list_n-2],Table[list_n-1]);//输出三地址代码 printf("(*,%s,%s,%s)\n",Table[list_n-2],Table[list_n-1],ch);//输出四元式 } else { printf("%s: =%s/%s",ch,Table[list_n-2],Table[list_n—1]);//输出三地址代码 printf("(/,%s,%s,%s)\n",Table[list_n—2],Table[list_n—1],ch);//输出四元式 } strcpy(Table[list_n-2],ch);//将当前结果归结式放在符号表中 list_n-—; n++; T1(); } } } voidF()//F—>V|(E) { if(SIGN==0) { if(s[sym]=='(') { sym++; E(); if(s[sym]==’)’) sym++; else { printf(”ERROR! \n”); SIGN=1; exit(0); } } elseif(islower(s[sym]))//判断s[sym]是否是小写字母 V(); else { printf("ERROR! \n"); SIGN=1; exit(0); } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 递归 下降 语法分析 程序设计
![提示](https://static.bdocx.com/images/bang_tan.gif)