1 编译程序的分析与验证
1.1实验目的
LR分析表的作用以及语义加工程序的功能。
1.2实验要求
在掌握编译原理的基础上,对编译程序实例进行分析,通过编译程序的运行,检验编译程序输出结果的正确性。理论联系实际,将所学知识用到实处,进而学会怎么写编译程序。
1.3实验内容
1)验证下述程序输出结果的正确性:
while (a>b) do
begin
if m>=n then a:=a+1
else
while k=h do x:=x+2;
m:=n+x*(m+y)
end#~
2)自行设计一程序进行正确性验证,并按二元式序列的注释及状态栈STACK加工分析对应的符号栈内容。
2
2.1实验目的
LR分析表的设计方法和语义加工程序的扩充。
2.2实验要求
LR分析表的设计方法,设计扩充后的算术表达式LR分析表,并对原语义加工程序进行修改,加入新添加的内容。
2.3实验内容
(1)算术表达式文法扩充如下:
E->E+E|E-E|E*E|E/E|(E)|i
“-”,“/”的内部定义以及重新设计LR分析表,并修改语义加工程序,最后验证修改的结果。
(2)待验证程序:
begin
a:=a+b-c*d/e;
while a<c do
while b<d do
while d<e do
if a<e then m:=n else m:=q;
end#~
2.4算法设计
在实验一中已给出编译程序的全部代码,且能识别加、乘算数表达式。而本实验只需根据识别加、乘算数表达式的设计方法来对算数表达式进行扩充以实现对减、除算数表达式的识别及分析。
(1)添加关键字减、除运算符的种别代码
#define sub 35 /* - */
#define div 37 /* / */
(2)重新构造算数表达式的LR分析表
static int action1[14][9]={
{3,-1,-1,-1,-1,2,-1,-1,1},
{-1,4,10,5,11,-1,-1,ACC,-1},
{3,-1,-1,-1,-1,2,-1,-1,6},
{-1,104,104,104,104,-1,104,104,-1},
{3,-1,-1,-1,-1,2,-1,-1,7},
{3,-1,-1,-1,-1,2,-1,-1,8},
{-1,4,10,5,11,-1,9,-1,-1},
{-1,101,101,5,11,-1,101,101,-1},
{-1,102,102,102,102,-1,102,102,-1},
{-1,103,103,103,103,-1,103,103,-1},
{3,-1,-1,-1,-1,2,-1,-1,12},
{3,-1,-1,-1,-1,2,-1,-1,13},
{-1,105,105,5,11,-1,105,105,-1},
{-1,106,106,106,106,-1,106,106,-1}
};
(3)在扫描算法scan中增加对减、除运算符的识别
case '-': buf[count].sy1=sub; /* - */
count++;
break;
case '/': buf[count].sy1=div; /* / */
count++;
break;
(4)实现对减、除算术表达式的规约
case 105: E.pos=newtemp();
gen("-",sstack[ssp-2],sstack[ssp],E.pos+100);
ssp=ssp-2;
sstack[ssp].sy1=tempsy;
sstack[ssp].pos=E.pos;
sp1=sp1-3;
break;
case 106: E.pos=newtemp();
gen("/",sstack[ssp-2],sstack[ssp],E.pos+100);
ssp=ssp-2;
sstack[ssp].sy1=tempsy;
sstack[ssp].pos=E.pos;
sp1=sp1-3;
break;
(5)test算法中增加对减、除运算符的识别
case sub:
case div:
return 1;
default:
return 0;
3
3.1实验目的
通过添加新的程序语句,全面了解一个语句的编译程序设计过程。
3.2实验要求
LR分析表及相应的处理程序,并将其添加到程序语句处理语句中。
3.3实验内容
(1)将计数循环for语句的功能添加到编译程序中。For语句的文法及每个产生式相应的语义子程序如下:
F1→for i:=E(1) {GEN(:=,E(1).PLACE,_,ENTRY(i);
F1.PLACE:=ENTRY(i);
F1.CHAIN:=NXQ;
GEN(j,_,_,0);
F1・QUAD:=NXQ}
F2→F1 step E(2) {F2.QUAD:=F1.QUAD;
F2.PLACE:=F1.PLACE;
GEN(+,F1.PLACE,E(2).PLACE,F1.PLACE);
BACKPATCH(F1.CHAIN,NXQ)}
F3→F2 until E(3) {F3.QUAD:=F2.QUAD;
q:=NXQ;
GEN(j≤,F2.PLACE,E(3).PLACE,q+2);
F3.CHAIN:=NXQ;
GEN(j,_,_,0)}
S→F3 do S(1) {先形成S(1)相应的四元式序列;
GEN(j,_,_,F3.QUAD);
BACKPATCH(S(1).CHAIN,F3.QUAD);
S.CHAIN:=F3.CHAIN}
(2)待验证程序:
begin
for a:=1 to 8 do
begin
if m>=n then a:=a-1
else
while k=h do x:=x+2;
m:=n+x/(m-y);
end
end#~
3.4实验说明
1)实现时可将for语句的文法设计为一个LR分析表,然后将该文法的开始符看作程序语句LR分析表中的一个终结符,即像赋值语句一样处理(当然仍要重新设计程序语句的LR分析表)。另一种方法就是直接将for语句的文法纳入到程序语句文法中(即像if和while语句一样处理),并重新设计程序语言的LR分析表。
2)for语句中产生式的语义动作需要参考编译程序中对if和while语句的处理部分做相应修改。