词法分析实验报告(实验一)
时间:2020-10-22 09:56:26 来源:工作范文网 本文已影响 人
编译原理词法分析实验报告
软工082班
兰洁
200831104044
一、 实验内容
二、 实验目的
三、 实验预期
四、 程序规定
五、 实验原理
?程序流程图
?判别浮点功能扩展流程图
?状态转换图
六、 程序代码与浮点判别功能扩展
七、 测试用例
?扩展功能测试用例;
?普通功能测试用例
八、 输出结果
九、 实验心得
一、 实验内容:
词法分析:
1、 识别简单语言的单词符号;
2、 识别关键字、标识符、数字、运算符等。并扩展浮点识别功能。
二、 实验目的
调试词法分析程序,加深对词法分析原理的理解,掌握编写简单词法分析程序的一般步 骤。
三、 实验预期结果:
经过调试源代码程序,程序能够成功运行编译,对输入的简单字符串,能够别关键字、
标识符、数字、运算符等,并且给岀单词符号的对应编码。
四、 程序规定:
1、 天键子: function , if , then , while , do , endfunc :
2、 算术运算符:” +” , " -”,” *” , ” /” , ”二”:
3、 关系运算符:
4、 界符:"(""、”甘;
5、 标识符规泄以字母开头,字母均为小写;
6、 空格和换行符跳过:
7、 单词对应编码:
单词符号
对应编码
单词符号
对应编码
单词符号
对应编码
function
1
>
23
==
25
if
2
<
20
!二
29
then
3
+
13
26
while
4
—
14
(
27
do
5
*
15
)
28
endfunc
6
/
16
<>
21
标识符
10
>=
24
其他
-1
数字
11
<=
22
浮点数
80
#
0
二
18
十、实验原理:
输入串 〉词法分析程序 〉单词符号串
输入:字符串以#结朿。
输出:单词的二元组(syn, token/sum)
:園辛驱&跟習S黑他嫌导哉埠&
十?―卜? 卜■ r
?- ? r
? ■■?'? V ? ?■■' ? :■ / ? Y :■ / :
■ ■ ? ? ■
■ r ■ 7 :■ /■ / Y :? <"T ? T?~■
■ ? ? a a
I
n?n
p?*?4*?》?i*?》W?l
?-T-T-VT-v-r ?:
r-r-r-t-r-r
十十
「?:厂
炉呃砧他郴匏?4
..
"iWs
I■+
■
gF ?■
?■■?
仪
■PF
w? 吋 w?
IIa
厂厂丁
t-i---
r-t-
十匸
.十十
?r-r-:-r*
瞑4丄解廊
?# ?
?# ?
r-t
r-r-r-t-:-
H
?lZ
- ?
f......T.:
、
r-t-
n
—;
r-T....r.-
F-4--
--4-4---
4
…"卄!
;?;」丄…
ir—-4-vr—
irl^lJ.! r I
L卜
删卿昨S
十卜+
1?>!!!I 、 ?:?!:?:
l4—:?十
Lt~
人一^
p?£p ?号?£,?£ 》?■?£》?£?
r-4-~
J
)
I | : I :
r-r-; r . i I; i; L f~-r~
r-T....f-.
> I : ?:
? ?严
<■?
I : I I : I : I I : I : I I
J fi
广
/?/?▼
厂叮
厂■?叮
>?> ?{*?;
f ?/?▼
/?r**°
? ? ? ■ ?
开始
sumint^O;n=O 仪 Y
sumint-sumint*10+suni l[n]?O:nT :4 〃计算整数部分
Syn=l I;
suml[k] - ch; ch 二 prog[++c];
将数字放Buml这个数
组里
r-i
?
?
:. 1 ? ?:
ch=nrop
4cl:
g ?■ ■
?■■
■ Ct ”
J tcnshu[i]-ch;
i++;
4~N—<
—
? ? 1 ?
?
..U.J
1 ?
...
I ? - ?
*
? ? —r*?.
? ; 1 ?
■Y,
? : f ?
1 ? ?
? ? ?
? 1
I
? ?
调用血呵)函数,用来
判斯浮点数的小数部分
是否充全玻进i&shu这
个数组中
sumf=sumf^0.1 +(fenshu[k 』卜?)检1;竹I?算小数部分
■厂
Syn-80?
N-W sumM): k=i-2
{? ?:
■:
1 ? . ? s
?I..:..;.
? ?
■? ?:
vr ?
B
1 ■ 9 ?
、Syn 80/ >>
调用shU2i()凶埶用来判 断浮点数的整数部分是 否克全放进suml这个数 组巾
X——- fudian-sumini+bumE 浮点数计算syn=80;
状态转换图
六.程序代码:
备注:红色字体部分为程序功能的功能扩展,使程序能够分析浮点数!
我把浮点数的syn设置为80!
/*词法分析源代码柠
#include<stdio. h> #include<string? h>
scaner0;
char prog[80_,token [8」;
char ch;
int syn, p, m, n, sum;
char * rwtab 16] = {,zfunction"*,"辻"then", "while", "do", "endfunc"};
int i=0, k, c, sumint, f;
char fenshu[80], suml[80];
double sumf=0, fudian;
int shuzi () {
if(ch>二'O' && ch<='9‘)
syn=80;
else
syn=_2;
return syn;}
mainO
{p二 0;
printf (z,\n please input string : \n");
do{
scanf (,z%c,z, &ch);
prog[++pj=ch;}
while (ch!二'#');
P 二0;
do
{
scaner0;
switch(syn)
else
else
if(ch>= Of && ch<='9‘)
k=0;
do
{ suml[k]=ch;
ch=prog [++c] ; //ch 取后一个数字
k++;
shuziO;//这个函数用来分析浮点数的整数部分是否
已经输入到数组里
f=syn;
} wh订e(f==80)
辻(ch=‘ ?')
{
for (n=0;n<k;n++)
{
sumint=sumint*10+suml[n]O';
} 〃计算整数部分
i=0;
do
{
ch=prog[++c];
fenshu[i]=ch;
i卄;
shuzi ();〃这个函数用来分析浮点数的小数部分是否已 经输入到数组里
} while(syn==80);
sumf=O;
for(k=i-2;k>=0;k~)
{
sumf=sumf*O. l+(fenshu[k]-' O' )*0. 1;
} //计算浮点数的小数部分
fudian=sumint+sumf; 〃浮点数计算
syn=80;
p= c;
}
else{
ch=prog[p]; //若是整数,ch等于原来的值
sum=O;
while (ch>=' O' && ch<=,9')
{
sum=sum*10+ch-' O';
ch=prog[++p];
}
ch=prog[-一p];syn=ll;
}
}
else
switch(ch) case*:m=0;
token[m++]=ch; ch=progL++p];
辻(ch二二'二')
{syn=22;
token[m++]=ch;
}
else
if(ch=' >')
{
syn=21;
token[m++]二ch;
}
else
{syn=20;ch=prog[―p]:} break;
case* >' : m=0;
token[m++]=ch;
ch二prog[++p];
辻(ch二二'二')
{syn=24;
token =ch;
}
else
{syn=23;
ch=prog[―p];
}
break;
case* :m=0;
token[m++]=ch; ch=progL++p];
if (ch二二'二')
{syn=25;
tokenLm++]=ch;
}
else
{syn=18;
ch二prog-―p];
}
break;
case* !' :m^O:token[m++]=ch;
ch二prog[++p];
辻(ch二二'二')
{syn=22;
token[m++]二ch;
}
else
{
syn=-l;
P—;
}
break;
case* +' :syn=13;token[0]=ch;break:
case* :syn=14;tokenEO]=ch:break:
case* *' :syn=15;token[0]=ch:break:
case*/' :syn=16;tokenEO]=ch;break:
case* :syn=26;token[0]=ch:break:
case* (' : syn=27; tokenEO] =ch: break:
case*)' :syn=28;token EO]=ch:break:
case* :syn=0;token[0]=ch:break:
default:syn=-l;
}
}
七.测试用例^
测试用例1
输岀结果
测试用例2
输出结果
测试用例3
输出结果
1+1=2;#
(11,1)
a*b=c;
(10, a)
function
(1, function)
(13,+)
c=l+s2b;
(15, *)
while(a=l)
(4, wh订e)
(11,1)
(10, b)
if(sb>=2)
(27, 0
(1& =)
(1& 二)
2=s2b;
(10, a)
(11,2)
(10, c)
endfunc
(1& =)
(26,;)
(26,;)
#
(11,1)
(0, #)
(10, c)
(28,))
测试用例4
输岀结果
(1& 二)
(2, if)
error
(11,1)
(27, 0
~!@$好&_#
error
(13, +)
(10, sb)
error
(10, s2b)
(24, >=)
error
(26,;)
(11,2)
error
(0, #)
(28,))
error
(11,2)
error
(18,=)
error
(10, s2b)
error
(26,;)
(0, #)
(6, endfunc)
(0,#)
补充:功能扩展测试用例:
输入数据1
显示结果
输入数据
显示结果
输入数据
显示结果
a+b=l. 1;
(10, a)
a=l+2.2
(10, a)
a=l*2.3;
(10, a)
a=2. 3#
(13, +)
b=3?2;
(18,=)
2*12. 2=24. 4#
(18,=)
(10, b)
1+2. 3=3. 3#
(11,1)
(11,1)
(18,=)
(13, +)
(15, *)
(80,1.100000)
(80, 2. 200000)
(80, 2. 300000)
(26,;)
(10, b)
(26,;)
(10, a)
(18,=)
(11,2)
(18,=)
(80, 3. 200000)
(15, ?)
(80, 2. 300000)
(26,;)
(80,12. 200000)
(0, #)
(11,1)
(18,=)
(13, +)
(80, 24. 400000)
(80, 2. 300000)
(18,=)
(80, 3. 300000)
(o, n)
(o, #)
八、程序输出结果:
功能扩展测试用例输出结果
用例一:
-MH:?译原理\代码记事丰Qebug词法分祈涯代码(wanchenflJ.exB
piease input: stfingr = a*b=l.±;
卜=2?3tt
<10.a>
<13.*>
<10.b>
<18.=>
<80.1?丄0000
<26.;>
<10.a>
<18.=>
<80.2 ?300000A
<0, IDPress any keto cont inue
用例二:
| /?H:晦译原锂'代玛记爭本\Debum词法分靳潭代码佃anulwng)?aca?
plea.se ±npci 七:& 七 i*in^ -
耳=1 +2 .2
b=3.2 ;
1*2.3=3.3#
<10.a>
<18,=>
<11.1>
<13,+>
<80,2.200000>
<10,b)
<18,=)
<80,3.200000>
<26,;)
<11,1)
<13,+)
<80,2.300000> <18,=>
<80^3.300000>
<0^. tt>Press ctnj/ key to coni: inue
用例三:
“ "H:炉译原理玛左l事本gebug阖法分折灌代码tvuanulwngheKe"
pledase: in put st:tiding
L=l*2 -3;
2*±2.2=24.4# <10,
<18,=>
<11,1>
<15,*) <80,2-300000>
;〉
<11,2) <15,*>
<80,12.260003> <18,=>
<80,24.400000) <0,. lt>Pi:*ess a.ny key to conf: in Lie
普通功能测试用例显示结果
九、实验心得
通过编译原理实验一词法分析实验,使得自己对词法分析的流程有了更深刻的了解,虽 然源代码并非由自己设讣,但是在调试程序的过程中,尤其是进行测序功能扩展的过程中, 想了很多种办法,终于找到了最合适的方法,而且还进行了代码的优化,这个过程虽然有时 有些枯燥,但是更多时候是欣喜的,不仅复习了 C语言的许多内容,并且有了更深的理解。
很好的理解了程序的思想,理淸了词法分析程序的思路。从一开始对程序的陌生,到后来逐 步了解程序的流程,当我耐心的一步一步理解程序思想,一次次的更改测试用例,一迪遍的 调试,最终终于得到了预期的答案。这次实验使我对理论的词法分析的理解更加具体淸晰, 收获很大。