递归下降语法分析器Word文档下载推荐.docx
《递归下降语法分析器Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《递归下降语法分析器Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。
3
三、试验结果。
5
四、讨论与分析。
7
五、附录。
六、试验者自评。
11
一、实验目的
通过设计、编制、调试一个递归下降语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,掌握常用的语法分析方法。
通过本实验,应达到以下目标:
1、掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的方法。
2、掌握词法分析的实现方法。
3、上机调试编出的语法分析程序。
二、实验过程
我们在设计递归下降语法分析器时,应该首先对递归下降语法的相关的背景知识有足够的了解以及熟练的掌握。
从而在脑海里形成语法分析的一般方案,根据方案一步步所要实现的目的,形成对递归下降语法分析器程序的模块划分和整体规划。
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‟|ε
回溯的消除的前提是文法不得含有左递归,可提左因子来消除回溯。
2、程序总体设计
1、分析对象
分析算术表达式的BNF定义如下:
〈算术表达式〉→〈项〉|〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉
〈项〉→〈因式〉|〈项〉*〈因式〉|〈项〉/〈因式〉
〈因式〉→〈变量〉│(〈算术表达式〉)
〈变量〉→i
用符号表示如下:
E→T|E+T|E-T
T→F|T*F|T/F
F→i│(E)
2.经消除直接左递归后
E→TE’
E’→+TE’|-TE’|ε
T→FT’
T’→*FT’|/FT’|ε
F→i|(E)
3.根据递归下降法分析法,完成上述算术表达式的分析器构造。
主要完成:
(1)通知外界键入算术表达式;
(2)控制过程分析算术表达式;
(3)根据分析结果正误,分别通知外界不同的信息。
4、程序流程图
三、实验结果
(1)输入i+i#
(2)输入+i#
(3)左右括号测试
(4)测试回车
(5)综合测试1
四、讨论与分析
本次试验完成了指导报告上要求的基本功能,并且本程序具有以下几种情况的排错:
对(i+i这种错误,以及i++i,ii这种错误等进行了错误排除。
除此本程序对回车换行符也进行也处理,其处理方法就是每当在取得一个字符后,用if(sym==’\n’)sym=advance();
进行处理即可。
另外在编写程序时遇到了这样一种错误,当输入i+i+i时,PE返还给主函数的是+号,解决方法是在P—E函数中把p_E(hh);
改为hh=p_E(hh);
五、附录:
关键代码
#include"
stdio.h"
#include"
string.h"
stdlib.h"
ctype.h"
intpT(charsym);
intp_E(charsym);
intp_T(charsym);
intpF(charsym);
inti=0,j=0;
//charsym;
charinstring[20];
charadvance()
{charcc;
i=i+1;
cc=instring[i];
returncc;
}
intpE(charsym)
{
charxx;
xx=sym;
xx=pT(sym);
//printf("
%c"
xx);
xx=p_E(xx);
/n%c"
returnxx;
intp_E(charsym)
chars,hh;
s=sym;
hh=sym;
if(sym=='
+'
||sym=='
-'
)
{
printf("
sym);
sym=advance();
if(sym=='
\n'
sym=advance();
hh=pT(sym);
//printf("
hh);
hh=p_E(hh);
}
elseif(s=='
)'
||s=='
#'
/0'
||'
{}
else
error!
"
);
return-1;
returnhh;
intpT(charsym)
{charyy;
yy=sym;
yy=pF(sym);
yy);
yy=p_T(yy);
//printf("
returnyy;
intp_T(charsym)
chars,zz;
zz=sym;
*'
/'
{
s=sym;
//zz=sym;
zz=pF(sym);
//printf("
zz);
p_T(zz);
elseif(sym=='
printf("
error2!
return-1;
returnzz;
intpF(charsym)
i'
%d"
j++);
if(sym=='
//printf("
('
sym=pE(sym);
{
printf("
}
else
error"
return-1;
err"
returnsym;
voidmain()
intb=0;
charsym,c,mm;
inputastring\n"
do{
c=getchar();
instring[b++]=c;
}while(c!
='
getchar();
sym=instring[0];
mm=pE(sym);
\n%c"
mm);
if(mm=='
)
\nrightagain!
else
printf("
\nerroragain!
六、实验者自评
首先,对本次实验我抱着认真,细心的态度去做的,并且做了各种情况的测试以及调试。
从中我深深地体会到进行全面测试的重要性。
再者,对于本实验,我是采用C语言编写的,相对于用VB或JAVA编写,它的交互性要差一些。
最后,通过本程序的编写以及调试,我对于一些常见错误的分析能力有了一定的提高。