编译原理实验报告5语法分析程序的设计2Word文档下载推荐.docx
- 文档编号:16926230
- 上传时间:2022-11-27
- 格式:DOCX
- 页数:32
- 大小:770.94KB
编译原理实验报告5语法分析程序的设计2Word文档下载推荐.docx
《编译原理实验报告5语法分析程序的设计2Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告5语法分析程序的设计2Word文档下载推荐.docx(32页珍藏版)》请在冰豆网上搜索。
N;
=j+1;
S[k]:
=N;
ENDOFWHILE;
IFS[j]aORS[j]aTHEN
=k+1;
=a
END
ELSEERROR
UNTILa=‘#’
1、根据给出算法,利用适当的数据结构实现算符优先分析程序;
2、利用算符优先分析程序完成下列功能:
1)手工将测试的表达式写入文本文件,每个表达式写一行,用“;
”表示结束;
2)读入文本文件中的表达式;
3)调用实验2中的词法分析程序搜索单词;
4)把单词送入算法优先分析程序,判断表达式是否正确(是否是给出文法的语
言),若错误,应给出错误信息;
5)完成上述功能,有余力的同学可以对正确的表达式计算出结果。
四、实验环境
PC微机
DOS操作系统或Windows
TurboC程序集成环境或
操作系统VisualC++
程序集成环境
五、实验步骤
1、分析文法中终结符号的优先关系;
2、存放优先关系或构造优先函数;
3、利用算符优先分析的算法编写分析程序;
4、写测试程序,包括表达式的读入和结果的输出;
5、程序运行效果,测试数据可以参考下列给出的数据。
六、测试数据
输入数据:
编辑一个文本文文件expression.txt,在文件中输入如下内容:
10;
1+2;
(1+2)*3+(5+6*7);
((1+2)*3+4;
1+2+3+(*4+5);
(a+b)*(c+d);
((ab3+de4)**5)+1;
正确结果:
(1)10;
输出:
正确
(2)1+2;
(3)(1+2)*3+(5+6*7);
(4)((1+2)*3+4
错误
(5)1+2+3+(*4+5)
(6)(a+b)*(c+d)
(7)((ab3+de4)**5)+1
七、实验报告要求
实验报告应包括以下几个部分:
1、给定文法优先关系和存放方式;
#
e1
e2
e3
e4
引入“#”,将句型包含起来并填入出错标记。
使用二维数组将其存放。
2、算符优先分析程序的算法和结构;
程序从文本文件中逐行读取表达式,每行以“;
”做标记。
调用词法分析程序将这行数据分析出由一个个的单词组成的表达式,再逐个分析单词。
另外,由于文
法中没写入关于标识符和常数的产生式,所以在对单词符号进行语法分析时,会将标识符和常数自动规约为“i”。
数据结构:
优先关系表R:
二维数组,存储了终结符+、*、(、)、i、#的优先关系。
符号W:
结构体,有四个成员,包括:
ch:
char类型,非终结符与终结符的字符标记;
po:
int类型,只对终结符有效,与在R中的位置有关,有词法分析器提供;
对于非终结符,其po无效;
val:
string类型,综合属性;
对终结符i,其值由词法分析器提供;
对非终
结符,其值由规约时对应的产生式的规则计算得到;
对界符或运算符,val无效;
type:
int
类型,标记属性值类型,
0为标识符,不可计算;
1为可计算的
数值;
由词法分析器提供;
注意:
程序内部数值的计算和标记一律使用十进制,文本中的表达式必须为十进制整数,即如果在文本中使用八进制或十六进制,词法分析器分析后不会添加至缓冲区,在表达式语法正确且其中不含标志符时,计算得到的结果一律使用十进制。
例:
对于文本中十进制数字
10,其对应的初始结构体成员的值
ch=’i’,po=5,
val=”10”,type=1。
符号栈S:
符号结构体的一维数组。
算法:
说明:
算符优先文法并未对非终结符定义优先关系,无法对单非产生式进行规约,所
以实际上在规约时,上面的E->
T,T->
F基本没有使用,而且规约时并不严格按照
产生式的右部规约,只要待规约项符合句型#N1a1N2a2⋯NnanNn+1#(每个ai都是
终结符,Ni是可有可无的非终结符),
并且相对产生式,在相同位置有相同的非终结符即可规约,这样算符优先文法规约
很快,但有些语法错误将无法识别,在本实验中,只要在要规约的地方准确的判断
可规约的项,即符合句型,在不严格要求非终结符相同而终结符位置符号相同时,
存在可匹配文法的产生式,即可规约,例如:
F*F可以匹配T*F继而规约为T。
定义用W[ch]表示字符名为ch的符号;
实际程序中关于终结符优先关系的比
较是利用R获取优先关系标志的,算法中为了可读性,直接将结构体进行比较了。
从文本文件读入一行数据,
反复调用
scanP()得到符号集合,用符号结构体数组
E存
储;
k=1;
i=0;
S[k]=W[#];
Do{
A=E[i++];
if(S[k]是终结符)
j=k;
else
j=k–1;
while(S[j]>
A){
Q=S[j];
If(S[j-1]是终结符)
j=j–1;
j=j–2;
}while(S[j]<
Q);
N=Statute(S,j+1,k);
k=j+1;
S[k]=N;
}
If(S[j]<
A||S[j]==A){
k++;
S[k]=A;
elseerror(S[j].po,A.po);
}while(A==W[#]);
程序功能说明:
程序从文本文件读入表达式,判断语法是否正确,正确则输出结果,其中有标识符的话,结果还是含有标识符的原表达式,语法错误的话,则输出错误信息。
源程序:
程序中文本文件在桌面文件名为
expression.txt
#include<
iostream>
string>
stdlib.h>
usingnamespacestd;
#defineNULL0
#defineMAXSIZE30
//单行表达式的符号总数最大值
typedefstructgrammar_symbol
//文法符号
{
charch;
intpo;
stringval;
inttype;
}W;
charpre[6][6]={//优先关系表
{'
>
'
'
<
'
},{'
='
1'
2'
3'
}
};
charGetChar(FILE*fp){//读取文件中的一个字符charch;
ch=fgetc(fp);
returnch;
charGetBC(FILE*fp){
//读取文件的字符直至
ch不是空白
do{
ch=GetChar(fp);
}while(ch=='
'
||ch=='
\t'
\n'
);
returnch;
voidConcat(charch,charstrToken[]){
//将ch中的字符连接到
strToken之后
charstr[2];
intlen=strlen(strToken);
strToken[len]=ch;
strToken[len+1]='
\0'
;
intIsLetter(charch){
//布尔函数,判断
ch中的字符是否
为字母,是返回1,否则返回0
intflag=0;
if(ch>
='
a'
&
&
ch<
z'
flag=1;
returnflag;
intIsDigit(charch){
是返回1,否则返回0
//布尔函数,判断ch中的字符是否为数字
0'
9'
intReserve(charstrToken[]){//整型函数,对strToken中的字符串查找保留字表,若它
是一个保留字则返回它的编码,否则返回0
intcode=0,i;
charkeyWord[6][6]={"
if"
"
then"
else"
while"
do"
};
for(i=0;
i<
5;
i++){
if(strcmp(strToken,keyWord[i])==0){
code=i+1;
break;
returncode;
intSearchOP(charch){//整型函数,对strToken中的字符串查找运算符和界符,若它
是一个运算符或界符,则返回它的编码,否则返回0
charOP[10]={'
+'
*'
('
)'
-'
/'
10;
if(ch==OP[i]){
charRetract(FILE*fp,charch){//子函数,将搜索指示器回调一个字符位置,
将ch置为空白字符
ch='
fseek(fp,-1L,1);
voidProError(){
printf("
输入错误!
return;
\n"
//错误处理函数
intscan(FILE*fp,W*E,intnum){
Ww;
charstrToken[10];
strToken[0]='
//置strToken为空串
ch=GetBC(fp);
//先读取一个非空白的字符
if(feof(fp))return0;
if(ch=='
){
"
return0;
//判断表达式尾,是则返回调用程序
if(IsLetter(ch)){
//判断标识符
while(IsLetter(ch)||IsDigit(ch)){
Concat(ch,strToken);
ch=Retract(fp,ch);
if(Reserve(strToken)){
%s,->
strToken);
//判断关键字
%s"
w.ch='
i'
w.po=4;
w.val=strToken;
w.type=0;
E[num]=w;
elseif(ch>
){
while(IsDigit(ch)){
//判断十进制整数
w.type=1;
elseif(ch=='
7'
while(ch>
//判断八进制整数
2,%s>
x'
//判断十六进制整数
while(IsDigit(ch)||ch>
f'
3,%s>
else{//判断十进制的0
0"
w.val="
elseif(SearchOP(ch)!
=0){//判断运算符和界符
%c"
ch);
intpo=SearchOP(ch)-1;
w.ch=ch;
w.po=po;
else{//出错
ProError();
return1;
boolcheckVt(charch){
boolflag=false;
inti;
charVt[6]={'
('
#'
6;
if(ch==Vt[i]){
flag=true;
WStatute(W*S,ints,inte){//规约子函数,将S中j+1到k的符号规约为N
WN;
if(S[s].ch=='
s==e){
N.ch='
F'
N.val=S[s].val;
N.type=S[s].type;
elseif(S[s].ch=='
!
(checkVt(S[s+1].ch))&
S[e].ch=='
){if(S[s+1].type==1){
N.val=S[s+1].val;
N.type=S[s+1].type;
else{
N.val='
+S[s+1].val+'
elseif(!
(checkVt(S[s].ch))&
S[s+1].ch=='
(checkVt(S[e].ch))){N.ch='
E'
if(S[s].type==1&
S[e].type==1){
N.type=1;
intv=atoi(S[s].val.data())+atoi(S[e].val.data());
charl[30];
sprintf_s(l,30,"
%d"
v);
N.val=l;
N.type=0;
N.val=S[s].val+S[s+1].ch+S[e].val;
elseif((s!
=e)&
T'
intv=atoi(S[s].val.data())*atoi(S[e].val.data());
sprintf_s(l,30,"
elseif(S[s].ch=='
s==e){
N.po=4;
returnN;
voiderror(charerrnum){
//错误处理子函数
if(errnum=='
错误,非法左括号
\n\n"
elseif(errnum=='
错误,缺少运算符
elseif(errnum=='
错误,非法右括号
4'
错误,缺少表达式
intsyntax(W*E,intnum){//算法对应的主要实现程序
WS[MAXSIZE];
intk=1,i=0,j;
Wborder,A,Q;
border.ch='
border.po=5;
E[num]=border;
S[k]=border;
if(checkVt(S[k].ch))//判断S[k]是终结符
j=k-1;
while(pre[S[j].po][A.po]=='
if(checkVt(S[j-1].ch))
j=j-1;
j=j-2;
}while(pre[S[j].po][Q.po]!
WN=Statute(S,j+1,k);
if(N.ch=='
){error('
return0;
k=j+1;
S[k]=N;
if(pre[S[j].po][A.po]=='
||pre[S[j].po][A.po]=='
error(pre[S[j].po][A.po]);
}while(A.ch!
if(A.ch=='
正确,结果为:
%s\n\n"
S[k-1].val.data());
intmain(){
FILE*fp;
errno_terr;
if((err=fopen_s(&
fp,"
C:
\\Users\\Administrator\\Desktop\\expression.txt"
r"
))!
=
NULL){//以只读方式打开文件,失败则退出程序
filecannotopen!
exit(0);
intn=0;
语法分析结果如下:
while(!
feof(fp)){
intnum=0;
WE[MAXSIZE];
GetBC(fp);
if(!
n++;
//若不是文件尾则执行循环
//存储一行表达式
(%d)"
n);
while
(1){
//只读一行,行末标志为
“;
”
intflag=scan(fp,E,num);
if(flag==0)break;
num++;
\n输出:
"
syntax(E,num);
fclose(fp);
//关闭文件
fp=NULL
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告 语法分析 程序 设计