PL\0编译原理实验(南航)一:实验要求及目标说明

声明

本次实验是对pascal语言的子集PL\0语言进行词法、语法分析、语义分析、中间代码生成和解释器执行中间代码等五个部分

实验采用python编写,优点在于列表和字典数据结构以及简洁的语法使得较少的代码量实现整个功能,如果你采用别的语言也可以参考本教程,我会尽量详细的说明实验的细节

理论和实验参考了以下博客:

http://jcf94.com/2016/02/21/2016-02-21-pl0/  这个和南航的实验有些差别,但包括了主要的实验思路

https://www.cnblogs.com/X-Jun/p/11042544.html#_lab2_2_0 这个详细介绍了符号表和运行时存储组织记录

https://www.jianshu.com/p/de9132228b99 这个介绍了中间代码的规则和地址回填的方法

实验要求

课程设计题目

一个PASCAL语言子集(PL/0)编译器的设计与实现

PL/0语言的BNF描述(扩充的巴克斯范式表示法)

<prog> → program <id>;<block>

<block> → [<condecl>][<vardecl>][<proc>]<body>

<condecl> → const <const>{,<const>};

<const> → <id>:=<integer>

<vardecl> → var <id>{,<id>};

<proc> → procedure <id>([<id>{,<id>}]);<block>{;<proc>}

<body> → begin <statement>{;<statement>}end

<statement> → <id> := <exp>              

                         |if <lexp> then <statement>[else <statement>]

                         |while <lexp> do <statement>

                         |call <id>([<exp>{,<exp>}])

                         |<body>

                         |read (<id>{,<id>})

                         |write (<exp>{,<exp>})

<lexp> → <exp> <lop> <exp>|odd <exp>

<exp> → [+|-]<term>{<aop><term>}

<term> → <factor>{<mop><factor>}

<factor>→<id>|<integer>|(<exp>)

<lop> → =|<>|<|<=|>|>=

<aop> → +|-

<mop> → *|/

<id> → l{l|d}   (注:l表示字母)

<integer> → d{d}

注释:

       <prog>:程序 ;<block>:块、程序体 ;<condecl>:常量说明 ;<const>:常量;<vardecl>:变量说明 ;<proc>:分程

       序 ; <body>:复合语句 ;<statement>:语句;<exp>:表达式 ;<lexp>:条件 ;<term>:项 ; <factor>:因子 ;

<aop>:加法运算符;<mop>:乘法运算符; <lop>:关系运算符。

红色字体为PL\0语言的保留字,| 符号表示候选项只能多个选项选一个,{}表示可以出现多次

中间代码说明

Pcode的指令格式为

F :操作码

L :层次差 (标识符引用层减去定义层)

A :不同的指令含义不同

假想目标机的代码

LIT 0 ,a 取常量a放入数据栈栈顶

OPR 0 ,a 执行运算,a表示执行某种运算

LOD L ,a 取变量(相对地址为a,层差为L)放到数据栈的栈顶

STO L ,a 将数据栈栈顶的内容存入变量(相对地址为a,层次差为L)

CAL L ,a 调用过程(转子指令)(入口地址为a,层次差为L)

INT 0 ,a 数据栈栈顶指针增加a

JMP 0 ,a无条件转移到地址为a的指令

JPC 0 ,a 条件转移指令,转移到地址为a的指令

RED L ,a 读数据并存入变量(相对地址为a,层次差为L)

WRT 0 ,0 将栈顶内容输出

指令具体含义
LIT 0, a取常量a放到数据栈栈顶
OPR 0, a执行运算,a表示执行何种运算(+ - * /)
LOD l, a取变量放到数据栈栈顶(相对地址为a,层次差为l)
STO l, a将数据栈栈顶内容存入变量(相对地址为a,层次差为l)
CAL l, a调用过程(入口指令地址为a,层次差为l)
INT 0, a数据栈栈顶指针增加a
JMP 0, a无条件转移到指令地址a
JPC 0, a条件转移到指令地址a
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从命令行读入一个输入置于栈顶

进一步说明:

INT:为被调用的过程(包括主过程)在运行栈S中开辟数据区,这时A段为所需数据单元个数(包括三个连接数据);L段恒为0。

CAL:调用过程,这时A段为被调用过程的过程体(过程体之前一条指令)在目标程序区的入口地址。

LIT:将常量送到运行栈S的栈顶,这时A段为常量值。

LOD:将变量送到运行栈S的栈顶,这时A段为变量所在说明层中的相对位置。

STO:将运行栈S的栈顶内容送入某个变量单元中,A段为变量所在说明层中的相对位置。

JMP:无条件转移,这时A段为转向地址(目标程序)。

JPC:条件转移,当运行栈S的栈顶的布尔值为假(0)时,则转向A段所指目标程序地址;否则顺序执行。

OPR:关系或算术运算,A段指明具体运算,例如A=2代表算术运算“+”;A=12代表关系运算“>”;A=16代表“读入”操作等等。运算对象取自运行栈S的栈顶及次栈顶。

活动记录说明

假想机结构

两个存储器:存储器CODE,用来存放P的代码

                      数据存储器STACK(栈)用来动态分配数据空间

四个寄存器:

一个指令寄存器I:存放当前要执行的代码

一个栈顶指示器寄存器T:指向数据栈STACK的栈顶

一个基地址寄存器B:存放当前运行过程的数据区在STACK中的起始地址

一个程序地址寄存器P:存放下一条要执行的指令地址

该假想机没有供运算用的寄存器。所有运算都要在数据栈STACK的栈顶两个单元之间进行,并用运算结果取代原来的两个运算对象而保留在栈顶。

活动记录

 

RA:返回地址

DL:调用者的活动记录首地址

SL:保存该过程直接外层的活动记录首地址

过程返回可以看成是执行一个特殊的OPR运算

注意:层次差为调用层次与定义层次的差值

### 回答1: PL/0编译是南京航空航天大学计算机科学与技术专业的一门课程,其主要是介绍解释器和编译器的一些概念和实现方法。 PL/0是一种基于Pascal的类似于C的简单编程语言,其语法简单易懂,非常适合用于教学和初学者学习。在PL/0编译这门课程中,学生可以通过理论与实践相结合的方式,深入地了解编译器的整个工作流程,包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等方面。 在实现PL/0编译器的过程中,学生需要使用一些工具和技术,如flex、bison、LLVM等,学生需要对这些工具有一定的了解和应用能力。在课程实践中,学生需要完成自己的PL/0编译器的设计和实现,并进行一系列测试和优化。 总之,PL/0编译是南京航空航天大学计算机科学与技术专业的一门重要课程,对于提高学生的编程能力、理解编译器原理和工程实践能力都有着重要的作用。 ### 回答2: PL0编译是一种编程语言的编译器,它是为了方便程序员编写高效、可读性好的代码而开发的。南京航空航天大学的PL0编译器是由该校计算机科学系开发的,主要用于学生学习编译原理实验课程。 PL0是一种类似于Pascal的结构化编程语言,其语法简单易懂,同时也支持变量、函数、分支等基本的语言结构,使其非常适合初学者使用。而PL0编译器则是将PL0语言翻译成机器可执行的指令,通过编译器的优化,可以大大提升程序的执行效率和运行速度。 南京航空航天大学的PL0编译器可以帮助学生了解编译原理相关的知识和技术,培养学生程序设计的能力和编程思维,同时也为学生提供了一个实践编译原理的机会。学习PL0编译还可以帮助学生更深入地了解计算机底层的工作原理和实现方式,这对于计算机专业的学生来说是非常有价值的。 总之,南京航空航天大学的PL0编译器是一种非常有用的编程工具,它能够帮助学生更好地学习和掌握编译原理相关的知识和技术,同时也为学生提供了实践的机会,让学生更好地理解计算机底层的运作机制。 ### 回答3: PL0是一种编程语言,与Pascal有很多相似之处,并且可以作为编译原理学习的经典案例之一。PL0编译是指将这种编程语言编写的程序转化成计算机可以理解的机器语言的过程,也就是编译器如何将PL0程序转化为可执行文件的过程。 南京航空航天大学是一所工程类综合性大学,拥有优秀的计算机科学与技术专业。在南航学习编译原理时,学生们将会学到编译器设计中的各种技术,如词法分析、语法分析、语义分析、优化和代码生成等。在PL0编译过程中,需要将PL0语言识别为单词,然后解析出语法树,并对语法树进行语义分析。最后将语法树转化为可执行代码。 通过学习PL0编译,可以加深对编程语言底层原理的理解,培养编译器设计和开发的能力,帮助学生更好地理解软件工程系统的设计和实现。南京航空航天大学在编译原理课程中,不仅注重理论知识的教授,也注重实践操作的训练,通过编写PL0编译器实践,培养学生的综合能力,为以后的工作积累实际经验奠定基础。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值