词法分析实验报告(实验一)

来源:工作范文网 时间: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语言的许多内容,并且有了更深的理解。

 很好的理解了程序的思想,理淸了词法分析程序的思路。从一开始对程序的陌生,到后来逐 步了解程序的流程,当我耐心的一步一步理解程序思想,一次次的更改测试用例,一迪遍的 调试,最终终于得到了预期的答案。这次实验使我对理论的词法分析的理解更加具体淸晰, 收获很大。