编译实验语法分析.docx
《编译实验语法分析.docx》由会员分享,可在线阅读,更多相关《编译实验语法分析.docx(29页珍藏版)》请在冰点文库上搜索。
编译实验语法分析
语法分析器实验报告
院系:
专业:
小组成员:
学号:
日期:
一、实验目的
根据给出的文法编制LR
(1)分析程序,以便对任意输入的符号串进行分析。
本次实验的目的主要是加深对LR
(1)分析法的理解。
二、实验内容
对已给语言文法,构造LR
(1)分析表,编制语法分析程序,要求将错误信息输出到语法错误文件中,并输出分析句子的过程(显示栈的内容)
LR
(1)分析法的功能:
LR
(1)分析法的功能是利用LR
(1)分析表,对输入符号串自下而上的分析过程。
LR
(1)分析表的构造及分析过程。
三.实验文法
:
:
=.
:
:
=:
:
=const;|ε:
:
==
|,=
:
:
=var;|ε
:
:
=|,
:
:
=procedure;;|ε
:
:
=:
=
|call
|beginend
|ifthen
|whiledo
|ε
:
:
=|;
:
:
=odd|:
:
==|<>|<|>|<=|>=
:
:
=|
|
:
:
=+|-
:
:
=|:
:
=*|/
:
:
=||()
(1)"ε"表示空串。
.
(2)和分别表示标识符和数。
P—>B—>V—>S—>E—>LT—>D—>R—>a—>varb—>begine—>end_—>:
=I—>F—>ifT—>thenW—>whiled—>don—>空串—>@
实验环境:
MicrosoftWindows7
MicrosoftVisualStudio2010
实验原理:
构造LR
(1)项集族的方法
SetofltemsCLOSURE(I)
{
repeat
for(I中的每个项[A—>α·Bβ,a]for(G中的每个产生式B—>γ)for(FIRST(βa)中的每个终结符号b)将[B—>·γ,b]加入到集合I中;
Until不能向I中加入更多的项;
returnI
}
SetofltemsGOTO(I,X){
将J初始化为空集;
for(I中的每一个项[A—>α·Xβ,a])将项[A—>α·Xβ,a]加入到集合J中;
returnCLOSURE(J):
Voiditems(G)
{
将C初始化为{CLOSURE}({[S'—>·S,$]});repeat
for(C中的每一个项集I)for(每一个文法符号X)if(GOTO(I,X)非空且不在C中)将GOTO(I,X)加入C中;until不再有新的项集加入到C中;
}
语法分析表:
8P
82.
8P
U
8P
8P
9L
2LS
9£
8P
忧
LLS
U
OP
OP
2£
6丁
6^
U
92$
OL
8P
69
SI
£声
"S
89
£P
2.9
92
99
S9
on
W
£9
8P
29
££
19
£P
09
9卩
6S
8S
6工
2.S
ZL
IU
82
£is
Sis
in
92
99
U
IP
8l«
2.1$
gi«
IP
9【s
sg
沪
OL
£t>s
DR
2>s
£S
in
ZS
9P
9卩
19
OS
£2
£卩
6D
69
8t
9】
小
S9
2.9
89
99
9b
w
ip
6
8
9s
£s
3
实验流程图:
实验结果:
输入:
beginwhilea=cend.
输出:
输入:
begin
whilea=cend.
输出:
心得体会:
完成本次实验,我们首先要根据题目中给出的文法,构造LR
(1)项集族,之后构造LR
(1)语法分析表。
题目中给出的是pascal语言版的文法,实验开始时我们也稍微学习了一下pascal语言的风格和定义方法。
开发的C程序,把构造好的LR
(1)语法分析表存入,用数组模拟栈的功能。
对词法分析输出的语句,语法分析中,模拟字符的入栈,之后匹配语法分析表匹配出相应的ACTION动作,分析是移入操作还是归约操作。
当为移入操作时需要更新栈中栈顶符号和栈顶状态号;当为归约操作时,要根据相应的产生式,把产生式右边的字符弹出栈,出栈字符的个数要根据产生式的长度来判断,状态号的出栈个数也要匹配出栈字符的个数。
同时归约之后,要把产生式左边的终结符入栈,终结符入栈之后还要进行GOTO跳转。
所谓的入栈操作就是数组的个数增加操作,出栈操作就是数组的减法操作。
当时栈操作是从栈顶开始的,所以每一个数组的最后一位(栈顶)要十分明确的处理好,以免发生模拟入栈、出栈错误。
关键代码:
classactions
public:
charaction;//记录s或r等intnum;//记录下标
}act[80][30];
voidfenxibiao()
{
inti=0,j;
//先全部赋值为
e,代表错误
for(i=0;i<=78;i++)
{
for(j=0;j<=24;j++)act[i][j].action='e';
act[0][0].action=
's',act[0][0].num=4
act[0][1].action=
'r',act[0][1].num=4
act[0][4].action=
'r',act[0][4].num=4
act[0][5].action=
'r',act[0][5].num=4
act[0][7].action=
'r',act[0][7].num=4
act[0][15].action
='r',act[0][15].num=
4;
act[0][16].action
='',act[0][16].num=
1;
act[0][17].action
='',act[0][17].num=
2;
act[0][18].action
='',act[0][18].num=
3;
act[1][15].action
='a',act[1][15].num
=100;
//'a'代表接收状态
act[2][15].action
='r',act[2][15].num=
1;
act[3][1].action=
's',act[3][1].num=7
act[3][4].action=
's',act[3][4].num=6
act[3][5].action=
's',act[3][5].num=8
act[3][7].action=
's',act[3][7].num=9
;
act[3][15].action
='r',act[3][15].num=
11;
act[3][19].action='',act[3][19].num=5;act[4][4].action='s',act[4][4].num=11;act[4][21].action='',act[4][21].num=10;act[5][15].action='r',act[5][15].num=2;act[6][3].action='s',act[6][3].num=12;act[7][1].action='s',act[7][1].num=16;act[7][2].action='r',act[7][2].num=11;act[7][4].action='s',act[7][4].num=15;act[7][5].action='s',act[7][5].num=17;act[7][7].action='s',act[7][7].num=18;act[7][10].action='r',act[7][0].num=11;act[7][19].action='',act[7][19].num=14;act[7][22].action='',act[7][22].num=13;act[8][4].action='s',act[8][4].num=21;act[8][12].action='s',act[8][12].num=23;act[8][14].action='s',act[8][14].num=22;act[8][20].action='',act[8][20].num=20;act[8][23].action='',act[8][23].num=19;act[9][4].action='s',act[9][4].num=21;act[9][12].action='s',act[9][12].num=23;act[9][14].action='s',act[9][14].num=22;act[9][20].action='',act[9][20].num=25;act[9][23].action='',act[9][23].num=24;act[10][9].action='s',act[10][9].num=27;act[10][10].action='s',act[10][10].num=26;act[11][9].action='r',act[11][9].num=5;act[11][10].action='r',act[11][10].num=5;act[12][4].action='s