编译原理实验报告

CASN下载地址:https://download.csdn.net/download/eseszb/10502973


实验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

while b

while d

if a

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语句的处理部分做相应修改。


你可能感兴趣的:(编译原理实验报告)