跳至正文

编译原理lab7

内容目录

编译原理lab7

1. 对如下PL/0源程序,编译器分析到f:=(a+b)/3时候,符号表中的信息是怎样的?请以表格形式列出,并附上调试执行到该点时候的监视窗口截图。

const a=27,b=80;
var x,y,z;
procedure p;
 var f;
 begin
  f:=(a+b)/3;
 end;
begin
  x:=3; call p;
end.

当编译器分析到f:=(a+b)/3时,

符号表中信息如下:

name kind val/level addr size
a constant 27
b constant 80
x variable 0 3
y variable 0 4
z variable 0 5
p procedure 0 2 4
f variable 1 3

监视窗口截图如下:

img

2. 对如下PL/0源程序,编译器分析到x:=0;时候,符号表中的信息是怎样的?请以表格形式列出,并附上调试执行到该点时候的监视窗口截图。对procedure类型的标识符,其在符号表中的adr字段的含义是什么?这个adr值何时生成和更新?(指出相应代码片段并简要说明)

const a=25;
var x,y;
procedure  p;
    var  z;
    begin
         y:=0;
         z:=y;
    end;
procedure  r;
    var x, s;
    procedure t;
         var  v;
         begin
            v:=1
         end;
    begin        
         x:=0;
    end;
begin
    x:=1;
end.

当编译器分析到x:=0时,

符号表中信息如下:

name kind val/level addr size
a constant 25
x variable 0 3
y variable 0 4
p procedure 0 2 4
r procedure 0 14 5
x variable 1 3
s variable 1 4
t procedure 1 10 4

监视窗口截图如下:

img

对于procedure类型的标识符,其在符号表中的adr字段的含义是:该过程在代码中的入口地址

adr值在block函数中生成和更新,

adr值生成在以下代码段由table[tx].adr = cx;语句完成,先为adr赋当前层代码开始位置作为初值

...
dx = 3;                 /* 三个空间用于存放静态链SL、动态链DL和返回地址RA  */
tx0 = tx;         /* 记录本层标识符的初始位置 */
table[tx].adr = cx;     /* 记录当前层代码的开始位置 */
gen(jmp, 0, 0);         /* 产生跳转指令,跳转位置未知暂时填0 */
...

img

而adr值更新在以下代码段由table[tx0].adr = cx;语句完成,由gen函数生成虚拟代码并持续更新cx后,在声明结束以后便可以知道过程的入口地址,于是将cx赋给adr更新其值即是该过程对应虚拟代码中入口地址

...
code[table[tx0].adr].a = cx; /* 把前面生成的跳转语句的跳转位置改成当前位置 */
table[tx0].adr = cx;         /* 记录当前过程代码地址 */
table[tx0].size = dx;         /* 声明部分中每增加一条声明都会给dx增加1,声明部分已经结束,dx就是当前过程数据的size */
cx0 = cx;
gen(ini, 0, dx);             /* 生成指令,此指令执行时在数据栈中为被调用的过程开辟dx个单元的数据区 */
...

img

代码链接

https://gitee.com/WilliamSamShen/complier-concepts/tree/master/Lab/lab7