编译原理实验报告
——理解PL/0编译程序原理
编译原理实验报告——理解PL/0编译程序原理
实验4.1 理解PL/0编译程序原理
一、 实验目的
1. 学习使用教学辅助软件THPL0CAI 2. 掌握PL/0源程序的编译和解释过程
二、 实验平台
Windows + THPL0CAI
三、 实验内容
1.运行THPL0CAI 程序
(1)选择0 - Static Link 方式进入;
(2)选择 Open/Create a source file 打开一个PL/0源程序,如Test2.pl0:
const a=10; var b,c;
procedure p; var k; begin
c:=b+10; end; begin read(b);
while b#0 do begin call p; write(2*c); read(b) end end.
2.按F9键开始单步编译Test2.pl0 程序
(1)观察符号表的构造过程 Table.dat 窗口; (2)观察目标代码的构造过程 Code.dat 窗口。
3.按F9键开始单步执行编译Test2.pl0 生成的代码
- 1 -
编译原理实验报告——理解PL/0编译程序原理
(1)观察运行栈的变化过程 Stack.dat 窗口; (2)观察数据的输入输出 Result.dat 窗口。
四、 实验分析
1.PL/0编译程序结构
(a)PL/0编译程序的结构图
(b) PL/0的解释执行结构
PL/0语言是PASCAL语言的子集 ----指令功能表
LIT 0 a LOD l a STO l a CAL l a INT 0 a JMP 0 a JPC 0 a
指令功能表 将常数值取到栈顶,a为常数值 将变量值取到栈顶,a为偏移量,l为层差 将栈顶内容送入某变量单元中,a为偏移量,l为层差 调用过程,a为过程地址,l为层差 在运行栈中为被调用的过程开辟a个单元的数据区 无条件跳转至a地址 条件跳转,当栈顶布尔值非真则跳转至a地址,否则顺序执- 2 -
编译原理实验报告——理解PL/0编译程序原理
行 OPR 0 0 OPR 0 1 OPR 0 2 OPR 0 3 OPR 0 4 OPR 0 5 OPR 0 6 OPR 0 7 OPR 0 8 过程调用结束后,返回调用点并退栈 栈顶元素取反 次栈顶与栈顶相加,退两个栈元素,结果值进栈 次栈顶减去栈顶,退两个栈元素,结果值进栈 次栈顶乘以栈顶,退两个栈元素,结果值进栈 次栈顶除以栈顶,退两个栈元素,结果值进栈 栈顶元素的奇偶判断,结果值在栈顶 次栈顶与栈顶是否相等,退两个栈元素,结果值进栈 OPR 0 9 次栈顶与栈顶是否不等,退两个栈元素,结果值进栈 OPR 0 10 次栈顶是否小于栈顶,退两个栈元素,结果值进栈 OPR 0 11 次栈顶是否大于等于栈顶,退两个栈元素,结果值进栈 OPR 0 12 次栈顶是否大于栈顶,退两个栈元素,结果值进栈 OPR 0 13 次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈 OPR 0 14 栈顶值输出至屏幕 OPR 0 15 屏幕输出换行 OPR 0 16 从命令行读入一个输入置于栈顶 2.给出编译过程中符号表的建立过程
Code.dat:
- 3 -
编译原理实验报告——理解PL/0编译程序原理
符号表table.dat如图所示:
符号表建立过程: (1)运行主程序,“main”存入符号表,类型为procedure,地址:8,大小:6; (2)常量a存入符号表,值为10;
(3)存入b,c,类型为variable,地址分别为3,4;
(4)执行p程序,存入p,类型为procedure,地址为1;
(5)存入k,类型为variable,地址为3;被引用变量或过程所在层次为1;
3.给出运行过程中运行栈的变化过程,只给出部分说明即可
程序开始
(1) 输入b=5,将变量b的取值取至栈顶。
(2) 将常数值0进栈,与b的值作比较;
B≠0,值为true,取至栈顶;
- 4 -
编译原理实验报告——理解PL/0编译程序原理
(3) 调用程序p;
为过程p开辟空间; 取变量b的值到栈顶; 取常数10到栈顶; 次栈顶与栈顶相加;
(4) 栈顶值15送入变量c中;
退栈并返回调用点(16);
(5) 常数值2进栈,次栈顶为15;
次栈顶与栈顶相乘; 栈顶值30输出至屏幕; 换行;
(6) 从命令行读取值0到栈顶;
- 5 -
编译原理实验报告——理解PL/0编译程序原理
栈顶值0送入变量b中;
(7) 取变量值b=0到栈顶;
判断次栈顶与栈顶是否不等,结果为false; 结束退栈。
五、 思考题
1.理解编译和解释的含义,目标代码是按何种方式执行的?
答:目标代码是按解释执行。
PL/0语言可看成是PASCAL语言的子集,它的编译程序是一个编译解释执行系统。PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关。PL/0的编译程序和目标程序的解释执行程序都是用PASCAL语言书写的,因此PL/0语言可在配备PASCAL语言的任何机器上实现。其编译过程采用一趟扫描方式,以语法分析程序为核心,词法分析程序和代码生成程序都作为一个的过程,当语法分析需要读单词时就调用词法分析程序,而当语法分析正确需生成相应的目标代码时,则调用代码生成程序。此外,用表格管理程序建立变量、常量和过程标识符的说明与引用之间的信息联系。用出错处理程序对词法和语法分析遇到的错误给出在源程序中出错的位置和错误性质。当源程序编译正确时,PL/0编译程序自动调用解释执行程序,对目标代码进行解释执行,并按用户程序要求输入数据和输出运行结果。
2.符号表在程序的执行过程中是否依然可用?
答:在编译程序中符号表用来存放语言程序中出现的有关标识符的属性信息,符号表中所登记的信息在编译的不同阶段都要用到。
在语义分析中,符号表所登记的内容将用于语义检查(如检查一个名字的使用和原先的说明是否一致)和产生中间代码。
- 6 -
编译原理实验报告——理解PL/0编译程序原理
在目标代码生成阶段,当对符号名进行地址分配时,符号表是地址分配的依据。对一个多遍扫描的编译程序,不同遍所用的符号表也往往各有不同。因为每遍所关心的信息各有差异。
六、 新递归PL/0程序
程序NEWTEST.PLO: const a=10;
var b,c; procedure p; var d; procedure q; var x; begin
read(x); d:=x;
while x#0 do call p; end; begin
write(d); call q; end; begin
call p;
end. Table.dat
- 7 -
编译原理实验报告——理解PL/0编译程序原理
七、 实验总结
PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。PL/0编译
程序的编译过程是按源程序顺序进行分析的,常量变量说明部分不产生目标代码。通过本次实验,使我加深了对编译理论知识的理解和掌握,并能达到基本上的运用。同时也增强了动手和实践的能力。虽然在遇到了不少困难,但是正因为这些困难,我也学到了更多的东西。通过运行THPL0CAI程序,掌握了符号表的建立过程,及运行过程中运行栈的变化过程。了解了PL/0语言是PASCAL语言的子集和指令功能表。
- 8 -