词法分析实施报告.docx
《词法分析实施报告.docx》由会员分享,可在线阅读,更多相关《词法分析实施报告.docx(13页珍藏版)》请在冰点文库上搜索。
词法分析实施报告
《编译原理》课程
实验报告
题目词法分析器的设计与实现
专业软件工程
班级20122012
学号2012201225
姓名杨帆
指导教师曹雪
哈尔滨工程大学软件学院
2015年5月
实验1:
词法分析
一、实验目的
1.巩固对词法分析的基本功能和原理的认识。
2.能够应用自动机的知识进行词法分析。
3.理解并处理词法分析中的异常和错误。
二、实验内容
要求:
对如下工作进行展开描述
(1)给出语言的词法规则描述
<字母>→a…z|A…Z
<标识符>→<字母>|<数字>|<字母><数字>
<关键字>→while|do|break|if|goto|continue
<数字>→0|1|2|3|4|5|6|7|8|9
<单界符>→<|>|:
|*|/|+|-|=|;|)|(|#|\n
<双界符>→:
=|==|>=|<=|<>
(2)针对这种单词的状态转换图和程序框图
状态转换图
程序框图
(3)核心数据结构的设计
单词符号
种别编码
单词符号
种别编码
\n
-2
-
16
#
0
:
17
while
1
:
=
18
do
2
>
20
if
3
<>
21
continue
4
<=
22
goto
5
<
23
break
6
>=
24
标识符
10
=
25
数字
11
;
26
*
13
(
27
/
14
)
28
+
15
(4)错误处理
A.输入的字符串为数字,数字大于32767,在对应的数字段显示”Errorinrowa!
”(a为字符串的队列号)。
B.输入的字符不在定义中,输出结果会显示”Errorinrowa!
”(a为字符串的队列号)。
三、实验结果
要求:
将实验获得的结果进行描述,基本内容包括:
(1)针对某测试程序输出其词法分析结果;
(2)输出针对此测试程序对应的词法错误报告;
(3)输出针对此测试程序对应的符号表。
注:
其中的测试样例自行产生。
A.代码及分析
代码:
#include"iostream"
usingnamespacestd;
charprog[100],token[20];
charch;
intsyn,p,m=0,n,row,sum=0;
char*rwtab[6]={"while","do","if","continue","goto","break"};
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;
}
else
switch(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=23;
p--;
}
break;
case'>':
m=0;
token[m++]=ch;
ch=prog[p++];
if(ch=='=')
{
syn=24;
token[m++]=ch;
}
else
{
syn=20;
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;
case'\n':
syn=-2;
break;
default:
syn=-1;
break;
}
}
voidmain()
{
p=0;
row=1;
cout<<"请输入字符串:
"<do
{
cin.get(ch);
prog[p++]=ch;
}
while(ch!
='#');
cout<<"字符串输出结果为:
"<p=0;
do
{
scaner();
switch(syn)
{
case11:
cout<<"("<break;
case-1:
cout<<"Errorinrow"<"<break;
case-2:
row=row++;
break;
default:
cout<<"("<break;
}
}
while(syn!
=0);
system("pause");
}
输出结果:
分析如下:
运行程序后,首先显示一行“请输入字符串:
”,然后在光标显示处输入想要输入的字符串,点击回车后,显示一行“字符串输出结果为:
”,紧接着便是结果。
如上图所示的例子进行分析。
首先判断第一个字符是否为数字或字母,同理再判断第二个字符,判断后再找下一个字符,遇到字符为’\0’,结束当前单词判断,确定为标识符后,将syn赋值10,然后判断刚才判断的单词是否为给定的关键字,恰好if为关键字,则将syn赋值关键字对应的3号;继续判断余下的字符,’(’对应的syn为27,i为字母,不是关键字即为标识符,对应的syn为10,同理余下的字符都可找到对应的syn值,最后输入’#’,表示字符串结束。
将结果用统一的队形表示得到上面的结果。
B.错误分析
a.输入的字符串为数字,数字大于32767。
由于计算机对应处理数据是二进制,并且为16位,其对应的最大值为十进制的32767,因此如果输入数据为大于32767的数,则会产生溢出现象。
为此,进行错误处理,即在对应的数字段显示”Errorinrowa!
”(a为字符串的队列号)。
具体如下图1所示。
图1
b.输入的字符不在定义中。
由于计算机中的字符有很多,在代码中并没有罗列全部的字符,如果输入的字符不在本次实验的代码定义中,则输出结果会显示”Errorinrowa!
”(a为字符串的队列号)。
具体如下图2所示。
图2
C.符号表
单词符号
种别编码
单词符号
种别编码
\n
-2
-
16
#
0
:
17
while
1
:
=
18
do
2
>
20
if
3
<>
21
continue
4
<=
22
goto
5
<
23
break
6
>=
24
标识符
10
=
25
数字
11
;
26
*
13
(
27
/
14
)
28
+
15
四、实验中遇到的问题总结
要求:
主要阐述两方面的问题
(一)实验过程中遇到的问题如何解决的?
本次实验中主要有以下两方面。
1.代码编写困难
自己的代码基础不好,因此在自己编写的过程中不清楚如何下手,出现了很多错误,对输入的字符不能够很好的处理,对标识符的判断以及关键字的定义都出现了很多问题,因此在老师的建议下,进行了网上浏览与查找分析,最后使用了网络上的已写好的代码进行实验分析。
2.代码分析不够
在使用网络上下载的代码后,由于不是自己编写的代码,自己分析就有些困难,有一些细节的处理不能及时思考清晰,一知半解。
在老师的帮助下,充分理解了代码中的问题。
(二)思考题的思考与分析
思考题1:
你编写的程序是如何体现自动机的,这样做有什么好处?
将词的类型作为状态,每个字符作为状态转换的条件。
好处为不必考虑特殊情况,可以将整个输入文本作为一个字符串直接处理得到结果。
思考题2:
符号表是怎么处理的,可不可以提出改进方法?
符号表中罗列了每一个显示的符号。
改进为可以将长度为2和1的符号区分在两个表里,采用贪心匹配法,对于两个连续的符号,即先考虑它是否在长度为2的符号表里,在考虑是否在长度为1的符号表里。
五、实验体会
通过进行本次词法分析器的实验,我基本能够应用自动机的知识进行词法分析,并能够理解以及处理词法分析器中的异常和错误,这次实验让我对词法分析的基本功能和原理进行了知识的巩固。
当然在实验的过程中,出现了很多问题。
比如代码的书写、词法的错误判断等。
本次实验我也清楚了自己的词法分析的知识掌握程度还是不够,同时由于自己的不细心,使很多细节的问题都没有及时处理。
本次实验使我懂得理论只是一定要学习扎实才能够进行顺利的实验操作,并且需要细心严谨的实验态度,才能将实验做得更好。
|