编译原理课程实验报告词法分析器及语法分析器.docx

上传人:b****4 文档编号:3766746 上传时间:2022-11-25 格式:DOCX 页数:32 大小:3.10MB
下载 相关 举报
编译原理课程实验报告词法分析器及语法分析器.docx_第1页
第1页 / 共32页
编译原理课程实验报告词法分析器及语法分析器.docx_第2页
第2页 / 共32页
编译原理课程实验报告词法分析器及语法分析器.docx_第3页
第3页 / 共32页
编译原理课程实验报告词法分析器及语法分析器.docx_第4页
第4页 / 共32页
编译原理课程实验报告词法分析器及语法分析器.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

编译原理课程实验报告词法分析器及语法分析器.docx

《编译原理课程实验报告词法分析器及语法分析器.docx》由会员分享,可在线阅读,更多相关《编译原理课程实验报告词法分析器及语法分析器.docx(32页珍藏版)》请在冰豆网上搜索。

编译原理课程实验报告词法分析器及语法分析器.docx

编译原理课程实验报告词法分析器及语法分析器

 

编译原理实验报告

 

班级:

软件0501班

学号:

**********

*******

 

词法分析器与语法分析器

I.问题描述

设计、编制并调试一个词法分析子程序,完成识别语言单词的任务;

设计、编制、调试一个语法分析程序,并用它对词法分析程序所提供的单词序列进行语法检查和结构分析。

ii.设计简要描述

界面需求:

为了更加形象的模拟过程,此实验使用图形界面。

要求从图形界面上输入输入串,点击词法分析,可以将词法分析后识别的单词符号显示,点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子),清空则可以将所有置空。

功能分析:

1、由用户输入输入串;

2、用户点击“词法分析”,可以将词法分析后识别的单词符号显示。

3、用户点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子)

4、用户点击清空,则将界面所有组件置为空

思路描述:

一、设计构想:

本实验决定编写一个简易C语言的词法分析器和语法分析器。

使其能够识别while,if等关键字,可以判断赋值语句、条件语句、循环语句。

二、文法分析

1、需要识别的关键字及其识别码有:

关键字识别码关键字识别码关键字识别码

main0-11;22

int1*12>23

char2/13<24

if3(14>=25

else4)15<=26

for5[16==27

while6]17!

=28

ID7{18ERROR-1

NUM8}19

=9,20

+10:

21

2、文法

〈程序〉→main()〈语句块〉

〈语句块〉→{〈语句串〉}

〈语句串〉→〈语句〉;〈语句串〉|〈语句〉;

〈语句〉→〈赋值语句〉|〈条件语句〉|〈循环语句〉

〈赋值语句〉→ID=〈表达式〉;

〈条件语句〉→if〈条件〉〈语句块〉

〈循环语句〉→while〈条件〉〈语句块〉

〈条件〉→(〈表达式〉〈关系符〉〈表达式〉)

〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)|ID|NUM

〈运算符〉→+|-|*|/

〈关系符〉→<|<=|>|>=|=|!

转化为符号表示:

S→main()K|空

K→{C}

C→Y;C|空

Y→F|T|X

F→ID=B

T→ifJK

X→whileJK

J→(BGB)

B→BZB|(B)|ID|NUM

Z→+|-|*|/

G→<|<=|>|>=|==|!

表示含义:

S:

程序K:

语句块C:

语句串Y:

语句F:

赋值语句

T:

条件语句X:

循环语句J:

条件B:

表达式I:

项Z:

运算符

G:

关系符

3、LL

(1)分析表

(1),求出first集及follow集:

FIRST(S)={mian}

FIRST(K)={{}

FIRST(C)=FIRST(Y)={ID,if,while,空};

FIRST(Y)=FIRST(F)+FIRST(T)+FIRST(X)={ID,if,while};

FIRST(F)={ID};

FIRST(T)={if};

FIRST(X)={while};

FIRST(J)=FIRST(B)={};

FIRST(B)={(,ID,NUM};

FIRST(Z)={+,-,*,/}

FIRST(G)={<,<=,>,>=,==,!

=};

FOLLOW(S)={#};

FOLLOW(K)={;};

FOLLOW(C)={}};

FOLLOW(Y)={;}

FOLLOW(F)={;};

FOLLOW(T)={;};

FOLLOW(X)={;};

FOLLOW(J)={{,;};

FOLLOW(B)={+,-,*,/,),<,<=,>,>=,==,!

=,;};

FOLLOW(B’)={+,-,*,/,),<,<=,>,>=,==,!

=,;};

FOLLOW(Z)={(,ID,NUM};

FOLLOW(G)={(,ID,NUM};

(2)消除左递归,拆分文法关系并编号

0、S→空

1、S→main()K

2、K→{C}

3、C→Y;C

4、C→空

5、Y→F

6、Y→T

7、Y→X

8、F→ID=B

9、T→ifJK

10、X→whileJK

11、J→(BGB)

12、B→(B)B'

13、B→IDB'

14、B→NUMB'

15、B'→BZBB'

16、B'→空

17、Z→+

18、Z→-

19、Z→*

20、Z→/

21、G→<

22、G→<=

23、G→>

24、G→>=

25、G→==

26、G→!

=

 

(3)构造LL

(1)分析表

(注:

在表中用上一步的编号表示所需要的产生式)

main

{

}

;

=

if

while

ID

num

+

-

*

/

<

<=

>

>=

==

!

=

#

S

1

0

K

2

C

4

4

3

3

3

Y

6

7

5

F

8

T

9

X

10

J

11

B

12

13

14

B'

16

15

16

16

15

15

16

16

16

16

16

16

16

16

16

16

Z

17

18

19

20

G

21

22

23

24

25

26

iii.详细设计描述

项目构架:

各函数功能介绍:

1、word.wordList包(存储了关键字):

word:

此类是定义了存储关键字的结构:

包括String型的关键字,和int型的识别符。

wordList:

此类存储了29个关键字,在构造函数中初始化。

2、word包(进行词法分析)中:

basicFunction:

此类定义了做词法分析的基本函数:

GetChar()将下一输入字符读到ch中,搜索知识器前移一个字符位置

GetBC();检查ch中的字符是否为空白。

若是,则调用GetChar直至不是字符为止

Concat();将ch中的字符连接到strToken之后

IsLetter();判断ch中的字符是否为字母

IsDigit();判断ch中的字符是否为数字

Reserve();对strToken中的字符创查找保留字表,若是则返回它的编码,否则返回0

Retract();将搜索指示器回调一个字符位置

RetractStr();将strToken置空

lexAnalysis:

此类是用来进行词法分析,将分析后的单词存入word数组中,(注:

在词法分析中,若是一串字母,则认为是ID,若是数字,则认为是NUM。

存储的时候识别符分别存ID与NUM的识别符,但是内容仍然是自己的内容)

其中的wordAnalysis函数就是词法分析函数(具体实现请看后面的重要函数分析)

3、stack包(定义栈)中:

栈是通过链表来定义的,因此

StringListElement:

次类定义了链表的每一个节点

StringStrack:

此类定义了栈,其中有长度属性,有函数:

Top();用来取得栈顶Push();压栈Pop();出栈

4、sentence包(语法分析)中:

juzi:

定义了文法的句子的结构:

key(左边部分)content[](右边推出的部分)lo(长度)

grammar:

存储了文法的27个关系式

AnalysisFB:

定义了分析表的存储结构

AnalysisF:

存储分析表

SentenceAnalysis:

语法分析

JuProduction(wordw):

此函数是用来判断在当前栈与输入串的情况下,用哪一个产生式,返回产生式在数组中的下标

若输入串的第一个字符与栈顶字符相同则表示可以规约,则返回-1;若不能过用产生式,则返回-2;

AnalysisBasic(wordw):

此函数是分布进行语法分析,对栈操作

*根据所需要的产生式对符号栈进行操作

*返回0表示规约;返回1表示移进;否则表示输入串不是文法的句子

5.Main包(主界面)中

Main:

此类定义了图形界面

重要函数分析:

一、词法分析函数:

当搜索指示器小于输入串长度是,就循环执行如下操作:

得到当前char,如果是字母,判断下一个,如是数字或字母,继续直至不是字母或者是数字,将此时的单词与关键字比较,获得识别符,存入word数组中

如果是数字,循环看下一个是否为数字,继续直至不是数字为止,将单词存入数组中

如果是+、-、*、/、(、)、[、]、{、}、,、:

、;与关键字比较,直接存入数组中

如果是>、<、=、!

时,要判断下一个,是否构成了>=、<=、==、!

=。

然后在存入数组中

如果下一个字符是空,换行,则跳过去下一个字符。

在做词法分析的时候,注意每一次判断结束之后要将strToken清空,而且要注意回退,即当输入串下一个不满足要求的时候,要回退一格。

二、语法分析函数

利用词法分析已经分析出来的单词数组,循环进行每一步的语法分析,每当归并一个单词之后,index指示器加一,直至index等于单词数组长度,循环结束。

在每一次循环中,根据当前指示器指示的单词及堆栈的栈顶判断:

若相同,则表示要归并,将index++;栈顶弹出

若不相同,在分析表中查找所需要的产生式,并将栈顶弹出,将产生式逆向堆栈。

在查询的过程中,如果不能够移进也不能够归并,表示输入串不符合文法,在提示栏中提示。

如果循环结束,直至栈中是由#,输入串中只剩#,表示分析完毕,输入串是符合文法的句子。

iv.结果分析(原始图示)

图形界面:

输入句子:

main(){}//空的main函数,运行结果

1、点击词法分析之后,在右侧的词法分析结果中显示分析后的单词:

2、点击语法分析之后,在中间的表中显示堆栈过程:

3、语法分析结束,该语句是符合文法的句子,因此在提示栏中显示“该句子是符合文法的语句!

输入复杂一点的句子:

main(){

If(zhj==zhj){

Zhj=good;

};

}

则结果是:

则他输出的单词是:

(1,main)(14,()(15,))(18,{)(4,if)(14,()(7,zhj)

(27,==)(7,zhj)(15,))(18,{)(7,zhj)(9,=)(7,good)

(22,;)(19,})(22,;)(19,})

语法分析经过了从0到37的38步,分析结束:

(在下图中将语法分析的全过程拼合)

分析结束后的输出结果是:

下图为此次语法分析的堆栈全过程:

 

输出更加复杂的句子:

Main()

{

While(lsq<=zhj){

If(zhj==zhj){

Zhj=good;

};

};

}

 

则结果是:

右侧的单词符号序列为:

语法分析过程为:

输入串是符合文法的句子,因此,正常结束

 

输入一个不符合文法的句子:

Main(){zhanghuijuanisagoodstudent;}//zhanghuijuanisagoodstudent语句即不是赋值,条件,也不是循环,因此不符合文法

输出结果是:

词法分析仍然可以进行,但是语法分析中发现进行不下去了,因此输出错误提示:

“此输入串不是一个语句,不符合文法!

iiv.调试报告:

程序在编写的过程中有很多小的地方并没有注意,在不断的调试的过程当中逐渐发现:

1、在文法中有A-->空的情况,在文法产生式的存储过程中就用空格代替了空,但是当需要用这样的产生式移进的时候,如果跟其他的产生式一样处理,则会在堆栈中将空格压栈,因此使语法分析不能继续进行下去。

因此,我们在压栈之前要先进行判断,若是这种情况,则只是弹出栈顶,而不对其进行压栈。

2、由于在此程序中应用了多个数组,因此很容易出现数组越界的情况,所以这里就要多加注意才行。

3、在堆栈过程输出的时候,要输出当前栈中的元素,以及剩余的输入串,一定要注意要将输入串的输出放在index的增加之后,否则就是输出上一次的执行时的输入串了

 

附:

程序原代码

************************packageword.wordList;**********************************

//////////////////////////////////////fileword.java/////////////////////////////////////

publicclassword{

Stringvalue;

intID;

publicintgetID(){

returnID;

}

publicvoidsetID(intid){

ID=id;

}

publicStringgetValue(){

returnvalue;

}

publicvoidsetValue(Stringvalue){

this.value=value;

}

}

//////////////////////////////////////fileword.java/////////////////////////////////////

publicclassWordList{

//此类定义了语言单词符号种别码

word[]w=newword[30];

publicWordList(){

w[0]=newword();w[0].setID

(1);w[0].setValue("main");

w[1]=newword();w[1].setID

(2);w[1].setValue("int");

w[2]=newword();w[2].setID(3);w[2].setValue("char");

.........................................................................//省略

w[27]=newword();w[27].setID(28);w[27].setValue("!

=");

w[28]=newword();w[28].setID(29);w[28].setValue("ERROR");

}

publicintReserve(Stringvalue){

for(inti=0;i<28;i++){

if(value.equals(w[i].getValue())){

returnw[i].getID();

}

}

return0;//返回0表示不在保留字之中。

}

}

************************packageword;;**********************************

//////////////////////////////////////filebasicFunction.java/////////////////////////////////////

importword.wordList.WordList;

//在此类中定义了一组全局变量和过程,将它们作为实现转换图的基本成分

publicclassbasicFunction{

publicStringinput="";//输入的源程序

publiccharch;//存放最新读进的源程序的字符

publicStringstrToken="";//存放构成单词符号的字符串

publicintindex=0;//存放此时搜索指示器指向的字符位置

publicintindex_buf;//buffer中搜索指示器指向的字符位置

basicFunction(Stringinput){

this.input=input;

}

publicchargetCh(){

returnch;

}

publicvoidsetCh(charch){

this.ch=ch;

}

publicStringgetInput(){

returninput;

}

publicvoidsetInput(Stringinput){

this.input=input;

}

publicStringgetStrToken(){

returnstrToken;

}

publicvoidsetStrToken(StringstrToken){

this.strToken=strToken;

}

//将下一输入字符读到ch中,搜索知识器前移一个字符位置

publicintGetChar(){

this.ch=this.input.charAt(index);

index++;

return0;

}

//检查ch中的字符是否为空白。

若是,则调用GetChar直至不是字符为止

publiccharGetBC(){

while(ch==''||ch=='\n'||ch=='\r'){

GetChar();

}

returnch;

}

//将ch中的字符连接到strToken之后

publicStringConcat(){

strToken=strToken.concat(String.valueOf(ch));

returnstrToken;

}

//判断ch中的字符是否为字母

publicbooleanIsLetter(){

booleanflag=false;

if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z'){

flag=true;

}

returnflag;

}

//判断ch中的字符是否为数字

publicbooleanIsDigit(){

booleanflag=false;

if(ch>='0'&&ch<='9'){

flag=true;

}

returnflag;

}

//对strToken中的字符创查找保留字表,若是则返回它的编码,否则返回0

//注:

在编写保留字表的时候要从1开始编号,不能从0开始编号!

publicintReserve(){

WordListwl=newWordList();

intf=wl.Reserve(strToken);

returnf;//返回0表示不在保留字之中。

}

//将搜索指示器回调一个字符位置

publicvoidRetract(){

ch='';

intl=strToken.length();

if(l>1){

strToken=strToken.substring(0,l-1);

}

index--;

}

//将strToken置空

publicvoidRetractStr(){

strToken="";

}

}

//////////////////////////////////file:

lexAnalysis.java;//////////////////////////////////

importword.wordList.word;

publicclasslexAnalysis{

Stringinput;

publicword[]word=newword[1000];

publicStringgetInput(){

returninput;

}

publicvoidsetInput(Stringinput){

this.input=input;

}

publicintwordAnalysis(){

inti=0;

basicFunctionbf=newbasicFunction(input);

intlo=input.length();

while(bf.index

word[i]=newword();

bf.GetChar();

bf.Concat();

if(bf.IsLetter()){

intf=0;

if(bf.index

bf.GetChar();

bf.Concat();

while(bf.IsLetter()||bf.IsDigit()){

if(bf.index

bf.GetChar();

bf.Concat();

}else{

bf.ch=

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1