编译原理课程实验报告词法分析器及语法分析器.docx
- 文档编号:9286626
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:38
- 大小:3.05MB
编译原理课程实验报告词法分析器及语法分析器.docx
《编译原理课程实验报告词法分析器及语法分析器.docx》由会员分享,可在线阅读,更多相关《编译原理课程实验报告词法分析器及语法分析器.docx(38页珍藏版)》请在冰豆网上搜索。
编译原理课程实验报告词法分析器及语法分析器
编译原理实验报告
班级:
软件0501班
学号:
1303050121
姓名:
张慧娟
词法分析器与语法分析器
I.问题描述
设计、编制并调试一个词法分析子程序,完成识别语言单词的任务;
设计、编制、调试一个语法分析程序,并用它对词法分析程序所提供的单词序列进行语法检查和结构分析。
ii.设计简要描述
界面需求:
为了更加形象的模拟过程,此实验使用图形界面。
要求从图形界面上输入输入串,点击词法分析,可以将词法分析后识别的单词符号显示,点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子),清空则可以将所有置空。
功能分析:
1、由用户输入输入串;
2、用户点击“词法分析”,可以将词法分析后识别的单词符号显示。
3、用户点击语法分析,可以将语法分析的堆栈过程显示,并且显示结果(是否是符合文法的句子)
4、用户点击清空,则将界面所有组件置为空
思路描述:
一、设计构想:
本实验决定编写一个简易C语言的词法分析器和语法分析器。
使其能够识别while,if等关键字,可以判断赋值语句、条件语句、循环语句。
2、文法分析
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清空,而且要注意回退,即当输入串下一个不满足要求的时候,要回退一格。
2、语法分析函数
利用词法分析已经分析出来的单词数组,循环进行每一步的语法分析,每当归并一个单词之后,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.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课程 实验 报告 词法 分析器 语法