编译原理实验报告.docx
- 文档编号:5363141
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:30
- 大小:324.85KB
编译原理实验报告.docx
《编译原理实验报告.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告.docx(30页珍藏版)》请在冰豆网上搜索。
编译原理实验报告
课程实验报告
课程名称:
《编译原理》
专业班级:
学号:
姓名:
指导教师:
报告日期:
计算机科学与技术学院
目录
目录2
1实验一词法分析3
1.1实验目的3
1.2实验要求3
1.2.1带分析的简单语言的词法3
1.2.2各种单词符号对应的种别码3
1.3算法思想4
1.4实验程序设计说明5
1.5词法分析实现6
1.6词法实验结果及结果分析9
2实验二语法分析10
2.1实验目的10
2.2实验要求10
2.3算法思想10
2.4实验程序设计说明13
2.5语法分析实现14
3实验中遇到的问题及解决23
4参考资料25
1实验一词法分析
1.1实验目的
设计,编制并调试一个词法分析程序,加深对词法分析原理的理解
1.2实验要求
1.2.1带分析的简单语言的词法
(1)关键字:
Beginifthenwhiledoend
所有关键字都是小写。
(2)运算符和界符
:
=+-*/<>>>==:
()#
(3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义:
ID=letter(letter|diggit)*
NUM=digitdigit*
(4)空格由空白、制表符和换行符组成。
空格一般用来分隔ID、NUM、运算符、界符和关键字、词法分析阶段通常被忽略。
1.2.2各种单词符号对应的种别码
单词符号
种别码
单词符号
种别码
begin
1
:
17
if
2
:
=
18
then
3
<
20
while
4
<>
21
do
5
<=
22
end
6
>
23
letter(letter|diggit)*
10
>=
24
digitdigit*
11
=
25
+
12
;
26
-
13
(
27
*
14
)
28
/
15
#
0
1.3算法思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。
1、主程序示意图
主程序示意图如图所示。
其中初值包括如下俩个方面:
(1)关键字表的初值。
关键字作为特殊标识符处理,把他们预先安排在一张表格中(成为关键字表),当扫描程序识别出标识符,查关键字表。
如能查到匹配的单词,则该单词为关键字,否则为一般标识符。
关键字表为一个字符串数组,其描述如下:
Char*rwtab[6]={“begin”,“if”,“then”,“while”,“do”,“end”};
程序中需要用到的主要变量为syn,token和sum。
2、扫描子程序的算法思想
首先设置3个变量:
(1)token用来存放构成单词符号的字符串;
(2)sum用来存放整型单词;(3)syn用来存放单词符号的种别码。
扫描子程序主要部分流程如图所示。
1.4实验程序设计说明
词法分析程序结构由流程图可知,其功能大致如下:
输入:
所给文法的源程序字符串。
输出:
二元组(syn,token或sum)构成的序列。
其中:
syn为单词种别码;
token为存放的单词自身字符串;
sum为整型常数。
例如:
对源程序
beginx:
=9;ifx>0thenx:
=2*x+1/3;end#
的源文件,经词法分析后输出如下序列:
(1,begin)(10,’x’)(18,:
=)(11,9)(26,;)(2,if)…
1.5词法分析实现
#include
#include
charprog[80],token[8];
charch;
intsyn,p,m=0,n,sum=0;
char*rwtab[6]={"begin","if","then","while","do","end"};
voidscaner()
{
for(n=0;n<8;n++)token[n]=NULL;
ch=prog[p++];
while(ch=='')
{
ch=prog[p];
p++;
}
if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
m=0;
while((ch>='0'&&ch<='9')||(ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
p--;
syn=10;
for(n=0;n<6;n++)
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
elseif((ch>='0'&&ch<='9'))
{
{
sum=0;
while((ch>='0'&&ch<='9'))
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
}
p--;
syn=11;
if(sum>32767)
syn=-1;
}
elseswitch(ch)
{
case'<':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
elseif(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
p--;
}
break;
case'>':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
p--;
}
break;
case':
':
m=0;token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
p--;
}
break;
case'+':
syn=13;token[0]=ch;break;
case'-':
syn=14;token[0]=ch;break;
case'*':
syn=15;token[0]=ch;break;
case'/':
syn=16;token[0]=ch;break;
case'=':
syn=25;token[0]=ch;break;
case';':
syn=26;token[0]=ch;break;
case'(':
syn=27;token[0]=ch;break;
case')':
syn=28;token[0]=ch;break;
case'#':
syn=0;token[0]=ch;break;
default:
syn=-1;break;
}
}
intmain()
{
p=0;
printf("Pleaseinputstring:
\n");
do
{
scanf("%c",&ch);
prog[p++]=ch;
}while(ch!
='#');
p=0;
do
{
scaner();
switch(syn)
{
case11:
printf("(%d,%d)\n",syn,sum);break;
case-1:
printf("Errorinrow!
\n");break;
default:
printf("(%d,%s)\n",syn,token);break;
}
}
while(syn!
=0);
return0;
}
1.6词法实验结果及结果分析
由结果可知,begin,then,end为字符,对应单词符号表中的序号,x为变量,9为数字,#为结束标志,词法分析结果正确。
2实验二语法分析
2.1实验目的
编制一个递归下降分析程序,实现对词法分析程序所提供的单词序列的语法检查和结构分析。
2.2实验要求
利用c语言编制递归下降分析程序,并对简单语言进行语法分析。
1:
待分析的简单语言的语法
用扩充的BNF表示如下:
(1)<程序>:
:
=begin<语句串>end
(2)<语句串>:
:
=<语句>{;<语句>}
(3)<语句>:
:
=<赋值语句>
(4)<赋值语句>:
:
=ID:
:
=<表达式>
(5)<表达式>:
:
=<项>{+<项>|-<项>}
(6)<项>:
:
=<因子>{*<因子>|/<因子>}
(7)<因子>:
:
=ID|NUM|(<表达式>)
2:
实验要求说明
输入单词,以#结束,如果是正确的文法句子,则输出成功信息,打印“success”
,否则输出“error”。
例如:
输入begina:
=9;x:
=2*3;b:
=a+xend#
输出success
输入x:
=a+b*cend#
输出error
2.3算法思想
(1)主程序示意图
(2)递归下降分析程序示意图
(3)语句串分析过程示意图
(4)statement语句分析函数流程图
(5)expression表达式分析函数示意图
(6)term分析函数示意图
(7)factor分析过程示意图
2.4实验程序设计说明
本实验建立在第一个实验的词法分析基础之上,采用递归下降分析方法对简单语言进行语法分析。
不同于词法分析的断字符串成词,语法分析根据词法分析解析出的词进行语法分析。
由扩充的BNF可知,lrparser函数确定程序的完整性,并调用yucu函数对语句串进行分析,yucu函数则调用statement函数对语句进行分析,statement函数调用expression函数对表达式进行分析,expression函数调用term函数对项进行分析,term函数调用factor函数对因子进行分析,层层嵌套,一层层将源程序分解为最终的因子,完成最终语法分析。
各函数具体原理见流程图,BNF范式具体见实验要求。
2.5语法分析实现
#include
#include
charprog[80],token[8];
charch;
intsyn,sum;
intp,n=0,kk=0;
char*rwtab[6]={"begin","if","then","while","do","end"};
voidscaner();
intlrparser();
voidyucu();
intstatement();
voidexpression();
voidterm();
intfactor();
intError();
voidmain()
{
p=0;
printf("请输入要处理的字符串:
\n");
do
{
scanf("%c",&ch);
prog[p++]=ch;
}while(ch!
='#');
n=p;
p=0;
printf("\n输入的字符串长度为:
%d",n);
printf("个字节!
\n");
scaner();
lrparser();
if(kk!
=1)
{
p=0;
do
{
scaner();
printf("词法分析的结果是:
");
switch(syn)
{
case11:
printf("(11,%d)\n",sum);
break;
case-1:
printf("(-1,ERR:
%d)\n",p+1);
break;
case10:
printf("(10,\'%s\')\n",token);
break;
default:
printf("(%d,%s)\n",syn,token);
}
}while(syn!
=0);
printf("\n");
}
}
voidscaner()
{
intn,m=0;
for(n=0;n<8;n++)
token[n]=NULL;
ch=prog[p++];
while(ch==''||ch=='\n')
ch=prog[p++];
if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))
{
while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9'))
{
token[m++]=ch;
ch=prog[p++];
}
token[m++]='\0';
p--;
syn=10;
for(n=0;n<6;n++)
{
if(strcmp(token,rwtab[n])==0)
{
syn=n+1;
break;
}
}
}
elseif(ch>='0'&&ch<='9')
{
sum=0;
while(ch>='0'&&ch<='9')
{
sum=sum*10+ch-'0';
ch=prog[p++];
}
p--;
syn=11;
}
else
{
switch(ch)
{
case'<':
token[m++]=ch;
ch=prog[p++];
if(ch=='>')
{
syn=21;
token[m++]=ch;
}
elseif(ch=='=')
{
syn=22;
token[m++]=ch;
}
else
{
syn=20;
p--;
}
break;
case'>':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=23;
p--;
}
break;
case':
':
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++]=ch;
}
else
{
syn=17;
p--;
}
break;
case'+':
syn=13;
token[m++]=ch;
break;
case'-':
syn=14;
token[m++]=ch;
break;
case'*':
syn=15;
token[m++]=ch;
break;
case'/':
syn=16;
token[m++]=ch;
break;
case'=':
syn=25;
token[m++]=ch;
break;
case';':
syn=26;
token[m++]=ch;
break;
case'(':
syn=27;
token[m++]=ch;
break;
case')':
syn=28;
token[m++]=ch;
break;
case'#':
syn=0;
token[m++]=ch;
break;
default:
syn=-1;
}
token[m++]='\0';
}
}
intlrparser()
{
if(syn==1)
{
scaner();
yucu();
if(syn==6)
{
scaner();
if(syn==0&&kk==0)
printf("success!
\n");
}
else
{
if(kk!
=1)
{
printf("缺end错误\n");
kk=Error();
returnkk;
}
}
}
else
{
printf("begin错误\n");
kk=Error();
returnkk;
}
return0;
}
intfactor()
{
if(syn==10||syn==11)
{
scaner();
}
elseif(syn==27)
{
scaner();
expression();
if(syn==28)
scaner();
else
{
printf("')'错误\n");
kk=Error();
returnkk;
}
}
else
{
printf("表达式错误\n");
kk=Error();
returnkk;
}
return0;
}
voidterm()
{
factor();
while(syn==15||syn==16)
{
scaner();
factor();
}
}
voidexpression()
{
term();
while(syn==13||syn==14)
{
scaner();
term();
}
}
intstatement()
{
if(syn==10)
{
scaner();
if(syn==18)
{
scaner();
expression();
}
else
{
printf("赋值号错误\n");
kk=Error();
returnkk;
}
}
else
{
printf("语句错误\n");
kk=Error();
returnkk;
}
return0;
}
voidyucu()
{
statement();
while(syn==26)
{
scaner();
statement();
}
}
intError()
{
intk=1;
printf("出错提示:
出错点在第%d",p-1);
printf("个字节附近处!
\n");
returnk;
}
2.6词法实验结果及结果分析
由实验结果可知,上述实例与与教材测试用例结果吻合,“begina:
=9;x:
=2*3;b:
=a+xend#”符合文法,并且词法分析结果正确。
由实验结果可知,上述实例与与教材测试用例结果吻合,“x:
=a+b*cend#”为缺少“begin”错误。
综上所述,该程序能较好的对程序语句进行语法分析。
3实验中遇到的问题及解决
1、词法分析时无法区别关键词与变量,如下
输入“beginx:
=9end”时,正确情况下为
遇到问题时为
解决:
将主函数ch获取字符值得cin流式输入改为scanf直接赋值输入。
2、语法分析时,无法识别缺end错误,如下:
由实验结果可知,“beginx:
=a;#”为语句错误,而不是缺end错误。
解决:
注意字符串区别输入“beginx:
=a#”为缺end错误,错误点在第11个附近,输入“beginx:
=a;#”为语句错误,此为逻辑错误,代码最后一行行末尾不要加“分号”。
3、由于平时练习较少,对于将书上的代码用语言实现有点吃力。
通过学习了词法语法分析,再经过实验,让我对其有了深刻的认识和了解。
递归下降分析法,是一种确定的自顶向下分析技术,它的实现思想是,对文法中分别代表一种语法成分的每个非终结符号编写一个子程序,已完成非终结符号所对应的语法成分的分析任务。
在分析过程中调用一系列过程或函数,对源程序进行语法语义分析直到整个程序处理结束;而词法分析是分析的第一步基础,深入理解有助于后续编程,带来不少便利。
4参考资料
[1]《编译原理》
课程实验的评分:
评分项目
(分值)
完成的功能及使用的算法、技术
(50分)
报告撰写
(50分)
总分
(100分)
得分
指导老师签字:
时间:
年月日
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告
![提示](https://static.bdocx.com/images/bang_tan.gif)