编译原理课程词法分析器及语法分析器Word格式文档下载.docx
- 文档编号:22024239
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:32
- 大小:3.05MB
编译原理课程词法分析器及语法分析器Word格式文档下载.docx
《编译原理课程词法分析器及语法分析器Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《编译原理课程词法分析器及语法分析器Word格式文档下载.docx(32页珍藏版)》请在冰豆网上搜索。
〈表达式〉→〈表达式〉〈运算符〉〈表达式〉|(〈表达式〉)|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
K
2
C
4
3
Y
6
7
5
F
8
T
9
X
10
J
11
B
12
13
14
B'
16
15
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;
}
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){
publicStringgetStrToken(){
returnstrToken;
publicvoidsetStrToken(StringstrToken){
this.strToken=strToken;
//将下一输入字符读到ch中,搜索知识器前移一个字符位置
publicintGetChar(){
this.ch=this.input.charAt(index);
index++;
return0;
//检查ch中的字符是否为空白。
若是,则调用GetChar直至不是字符为止
publiccharGetBC(){
while(ch=='
'
||ch=='
\n'
\r'
){
GetChar();
//将ch中的字符连接到strToken之后
publicStringConcat(){
strToken=strToken.concat(String.valueOf(ch));
//判断ch中的字符是否为字母
publicbooleanIsLetter(){
booleanflag=false;
if(ch>
='
a'
&
&
ch<
z'
||ch>
A'
Z'
){
flag=true;
returnflag;
//判断ch中的字符是否为数字
publicbooleanIsDigit(){
0'
9'
//对strToken中的字符创查找保留字表,若是则返回它的编码,否则返回0
//注:
在编写保留字表的时候要从1开始编号,不能从0开始编号!
publicintReserve(){
WordListwl=newWordList();
intf=wl.Reserve(strToken);
returnf;
//将搜索指示器回调一个字符位置
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];
returninput;
this.input=input;
publicintwordAnalysis(){
inti=0;
basicFunctionbf=newbasicFunction(input);
intlo=input.length();
while(bf.index<
lo){
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='
f=1;
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 课程 词法 分析器 语法
![提示](https://static.bdocx.com/images/bang_tan.gif)