PL0编译程序实例资料
- 格式:ppt
- 大小:914.00 KB
- 文档页数:91
PL/0编译程序设计说明书小组组长:李文(00000000)小组成员:******(00000000)******(00000000)******(00000000)******(00000000)2006年1月16日1引言 (3)1.1编写目的 (3)1.2背景 (3)1.3定义 (3)1.4参考资料 (5)2总体设计 (5)2.1需求规定 (5)2.2运行环境 (6)2.3模块流程 (6)2.4模块机理说明 (7)2.5模块设计与实现 (10)2.6人工处理过程 (12)2.7程序的亮点 (13)2.8尚未问决的问题 (13)3程序介绍和使用说明 (13)4程序测试结果分析 (16)概要设计说明书1引言1.1编写目的此文档为VK 1.0版PL/0编译器详细设计说明书,旨在说明该编译器的设计思想和实现。
此说明书可以在阅读本编译器代码时有效地帮助您理解本编译器的设计方法和实现过程,希望能提供给您所需的帮助。
1.2背景名称:VK1.0版PL/0编译器说明:此编译器为北京师范大学信息科学学院计算机科学与技术系2003级2005-2006学年度第一学期编译原理课程实验作业。
本软件由李文小组合作开发,组长李文,同组人员有吕叶、刘晟忻、肖纯、曲文星。
本软件主要用于PL/0程序的编译,软件提供生成中间代码,并执行检测。
本软件为开源软件,故除了用于编译以外还可给编译器开发者提供开发参考。
本软件开发运行在Windows 32位平台上,尚未开发其他平台版本。
1.3定义本软件开发中,用到了一些PL/0语言和PCODE的定义以及编译原理术语,下面给予说明。
●PL/0语言:➢BNF范式:〈程序〉∷=〈分程序〉.〈分程序〉∷=[〈常量说明部分〉][〈变量说明部分〉][〈过程说明部分〉]〈语句〉〈常量说明部分〉∷=CONST〈常量定义〉{,〈常量定义〉};〈常量定义〉∷=〈标识符〉=〈无符号整数〉〈无符号整数〉∷=〈数字〉{〈数字〉}〈变量说明部分〉∷=V AR〈标识符〉{,〈标识符〉};〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}〈过程说明部分〉∷=〈过程首部〉〈分程序〉{;〈过程说明部分〉};〈过程首部〉∷=PROCEDURE〈标识符〉;〈语句〉∷=〈赋值语句〉|〈条件语句〉|〈当型循环语句〉|〈过程调用语句〉|〈读语句〉|〈写语句〉|〈复合语句〉|〈空〉;〈赋值语句〉∷=〈标识符〉∶=〈表达式〉〈复合语句〉∷=BEGIN〈语句〉{;〈语句〉}END〈条件〉∷=〈表达式〉〈关系运算符〉〈表达式〉|ODD〈表达式〉〈表达式〉∷=[+|-]〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标识符〉|〈无符号整数〉|'('〈表达式〉')'〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/〈关系运算符〉∷=#|=|<|<=|>|>=〈条件语句〉∷=IF〈条件〉THEN〈语句〉〈过程调用语句〉∷=CALL〈标识符〉〈当型循环语句〉∷=WHILE〈条件〉DO〈语句〉〈读语句〉∷=READ'('〈标识符〉{,〈标识符〉}')'〈写语句〉∷=WRITE'('〈表达式〉{,〈表达式〉}')'〈字母〉∷=a|b|…|X|Y|Z〈数字〉∷=0|1|2|…|8|9➢PL/0语言允许过程嵌套定义,函数及变量作用于本层。
第二章PL/0编译程序的实现【课前思考】复习第1章介绍的一个高级程序设计语言编译程序的功能和实现的步骤。
编译程序就是一个语言的翻译程序,通常是把一种高级程序设计语言(称源语言)书写的程序翻译成另一种等价功能语言(称目标语言)的程序。
换句话说,编译是指把一种用源语言表示的算法转换到另一种等价的用目标语言表示的算法。
编译程序实现的必要步骤有词法、语法、语义分析和代码生成。
此外必需有符号表管理程序和出错处理程序。
本章介绍的PL/0编译程序的实现是用PASCAL语言书写的【学习目标】本章目的:以PL/0语言编译程序为实例,学习编译程序实现的基本步骤和相关技术,对编译程序的构造和实现得到一些感性认识和建立起整体概念,为后面的原理学习打下基础。
◇了解并掌握用语法图和扩充的巴科斯-瑙尔范式(EBNF)对PL/0语言的形式描述。
◇了解并掌握PL/0语言编译程序构造和实现的基本技术和步骤。
◇了解并掌握PL/0语言编译程序的目标程序在运行时数据空间的组织管理。
【学习指南】◇要求读者阅读PL/0语言编译程序文本,了解一个编译程序构造的必要步骤和实现技术。
一个编译程序的实现比较复杂,读懂一个典型的程序从设计思想到实现技术也有一定难度,特别是入门开始需要耐心。
一但读懂,不仅了解编译程序的实现方法和技术,还可学到许多编程技巧和好的编程风格。
◇阅读PL/0语言编译程序文本时,应从整体结构开始逐步细化,弄清楚每个过程的功能和实现方法及过程之间的相互关系。
◇建议用一个PL/0源程序的例子为导引作为阅读PL/0语言编译程序文本的入门,然后再逐步全面读懂。
◇通过对PL/0语言编译程序某些指定功能的扩充,加深对编译程序构造步骤和实现技术的理解,并能在实践中应用。
【难重点】重点:◇弄清源语言(PL/0)、目标语言(类pcode)与实现语言(C)这3个语言之间的关系和作用。
◇掌握用语法图和扩充的巴科斯-瑙尔范式(EBNF)对一个高级程序设计语言的形式描述。
一、题目:简单PL0编译程序及其扩展表示多行表达式的<表达式序列>文法如下:<表达式序列>-> <表达式> ↙<表达式序列> |<表达式>↙↙<表达式> -> [<变量>=] [+|-]<项>{(+|-)<项>}<项> -> <因子>{(* | /)<因子>}<因子> -> <无符号实数>|<变量>|<标准函数>‘(’<表达式>‘)’|‘(’ <表达式>‘)’<标准函数> -> sin | cos | tan | exp其中的变量无需定义且其作用域为第一次赋值处至最后。
递归下降方式设计其编译程序,生成PL/0栈式指令代码,然后解释执行。
二、编译技术,主要数据结构及算法Class:MyPL0int getch();void error(int n);int gen(string function,int lev,string a);int factor();int term();int expression();void listcode();void interpret();void GetFile();void start();void Check(int i);void run(string str);Class:Code主要数据结构:数组,栈,链表三、测试本程序的测试源程序在test.txt中:a=1+2*3-4/(2*3) //检测是否实现基本文法b=sin2+cos6+tan10 //检测是否扩展标准函数(本组没能实现exp)c=9*(3+ //检测出错纠察—缺少右括号d=x+3 //检测变量无定义e=48*+33 //检测表达式非法用于测试的源代码用户也可以自己定义四、遗留问题及思考没有解决exp的识别和计算,有待考究追加通过对书后标准程序的改造和学习,本小组加深了PL0编译程序的执行过程,了解到栈式目标代码的具体生成过程,。
编译原理实验报告——理解PL/0编译程序原理实验4.1 理解PL/0编译程序原理一、实验目的1.学习使用教学辅助软件THPL0CAI2.掌握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;beginc:=b+10;end;beginread(b);while b#0 dobegincall p;write(2*c);read(b)endend.2.按F9键开始单步编译Test2.pl0 程序(1)观察符号表的构造过程Table.dat 窗口;(2)观察目标代码的构造过程Code.dat 窗口。
3.按F9键开始单步执行编译Test2.pl0 生成的代码(1)观察运行栈的变化过程Stack.dat 窗口;(2)观察数据的输入输出Result.dat 窗口。
四、实验分析1.PL/0编译程序结构(a)PL/0编译程序的结构图(b)PL/0的解释执行结构PL/0语言是PASCAL语言的子集 ----指令功能表2.给出编译过程中符号表的建立过程Code.dat:符号表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的取值取至栈顶。
PL/0语言编译程序分析PL/0语言是Pascal语言的一个子集,我们这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。
PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。
词法分析和代码生成作为独立的子程序供语法分析程序调用。
语法分析的同时,提供了出错报告和出错恢复的功能。
在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。
词法分析子程序分析:词法分析子程序名为getsym,功能是从源程序中读出一个单词符号(token),把它的信息放入全局变量sym、id和num中,语法分析器需要单词时,直接从这三个变量中获得。
(注意!语法分析器每次用完这三个变量的值就立即调用getsym子程序获取新的单词供下一次使用。
而不是在需要新单词时才调用getsym过程。
)getsym过程通过反复调用getch子过程从源程序过获取字符,并把它们拼成单词。
getch过程中使用了行缓冲区技术以提高程序运行效率。
词法分析器的分析过程:调用getsym时,它通过getch过程从源程序中获得一个字符。
如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把sym变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把sym置为ident,把这个单词存入id变量。
查保留字表时使用了二分法查找以提高效率。
如果getch获得的字符是数字,则继续用getch获取数字,并把它们拼成一个整数,然后把sym置为number,并把拼成的数值放入num变量。
如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把sym则成相应的类型。
如果遇到不合法的字符,把sym置成nul。
语法分析子程序分析:语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语意生成相应的代码,并提供了出错处理的机制。
补充: PL/0语言及其编译程序的实现✧PL/0语言的编译程序把PL/0语言程序翻译成为一种称为类pcode的假想的栈式计算机汇编语言程序。
这种汇编语言与机器无关,若要在某一机器上实现PL/0语言程序,只需用机器上配置的任何语言对类pcode语言程序进行解释执行。
✧世界著名计算机科学家N.Wirth编写了"PL/0语言的编译程序"。
✧后面附了PL/0编译程序源代码。
⏹何为PL/0语言-PL/0语言是PASCAL语言的子集. 具备了一般高级语言的必备部分.(如: read,write,if-then,do,while,call,begin-end,赋值语句)☐PL/0语言中的数据类型只有整型,没有浮点数,所以圆周率只能近似为3。
数字最多为14位。
标识符的有效长度是10 ☐PL/0语言允许过程嵌套定义和递归调用的。
过程最多可嵌套三层。
☐过程可以引用自己定义的局部标识符,也可以引用包围在它的外过程(包括主程序)定义的标识符。
以下将用扩充的巴科斯-瑙尔范式(BACKUS-NAUR FORM)和语法图(EBNF)两种形式给出PL/0语言的语法描述。
------------------------------------------------------------------------------------------------------------------------------------------------------- (a) PL/0语言文法的EBNF表示EBNF表示的符号说明1)〈〉:用左右尖括号括起来的中文字表示语法构造成分,或称语法单位,为非终结符。
2)∷= :该符号的左部由右部定义,可读作'定义为'。
3)| :表示'或',为左部可由多个右部定义。
<标识符| 常量> 是不允许的. 因为非终结符作为一个独立的单位,不可分割4){ } :花括号表示其内的语法成分可以重复。
附件1 小组成员:程序清单Main.c#include<stdio.h>#include<stdlib.h>#include<string.h>void error(int n);void getsym();//void enter(enum object k,int *ptx,int lev,int *pdx);int position(char*idt,int tx);int constdeclaration(int *ptx,int lev,int *pdx);int vardeclaration(int *ptx,int lev,int *pdx);int factor(int*ptx,int lev);int term(int *ptx,int lev);int expression(int *ptx,int lev);int statement(int *ptx,int lev);int block();enum object{constant,variable,procedure};struct tab{char name[14];enum object kind;int val;int level;int adr;int size;}table[100];enum symbol{nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,r paren,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,ca llsym,constsym,varsym,procsym,progsym,};enum symbol sym=nul;enum symbol mulop;enum symbol wsym[14];enum symbol ssym[256];char ch=' ';char *str;charword[14][10]={"begin","call","const","do","end","if","odd","procedure","program ","read","then","var","while","write"};//设置保留字名字int num;int lev=0;int tx=0;int k;int *mm;//=(int *)malloc(sizeof(int));char *id,sign[14];char a[14];FILE *fp1,*fp2,*fp3;void error(int n){switch(n){case 1:printf("常数说明中的\"=\"写成了\":=\"。
编译原理课程设计学院计算机学院专业计算机科学与技术班级学号姓名指导教师20 年月日一、课程设计要求基本内容(成绩范围:“中”、“及格”或“不及格”)(1)扩充赋值运算:*= 和/=扩充语句(Pascal的FOR语句):①FOR <变量>:=<表达式> TO <表达式> DO <语句>②FOR <变量>:=<表达式> DOWNTO <表达式> DO <语句>其中,语句①的循环变量的步长为2,语句②的循环变量的步长为-2。
(3)增加运算:++ 和--。
选做内容(成绩评定范围扩大到:“优”和“良”)(1)增加类型:①字符类型;②实数类型。
(2)扩充函数:①有返回值和返回语句;②有参数函数。
(3)增加一维数组类型(可增加指令)。
(4)其他典型语言设施。
二、概述目标:实现PL0某些特定语句实现语言:C语言实现工具平台:VS201运行平台:WIN7三、结构设计说明与功能块描述PL/0编译程序的结构图PL/0编译程序的总体流程图四、主要成分描述1、符号表编译程序里用了一个枚举类型enum symbol,然后定义了enum symbol sym来存放当前的符号,前面讲过,主程序定义了一个以字符为元素的一维数组word,称保留字表,这个保留字表也存放在符号表里,为了识别当前的符号是属于哪些保留字;还有标识符,拼数,拼符合词等的符号名都存放在符号表里,当sym存放当前的符号时,我们可以判断它是属于哪类的符号,然后加以处理。
在运行的过程中,主程序中又定义了一个名字表,也就是符号表,来专门存放变量、常量和过程名的各个属性,里面的属性包括name,kind,val/level,adr,size,我们来举一个PL/0语言过程说明部分的片段:Const a=35,b=49;Var c,d,e;Procedure p;Var g;当遇到标识符的引用时就调用position函数,根据当前sym的符号类型来查table表,看是否有过正确的定义,若已有,则从表中取相应的有关信息,供代码的生成用。
实验一PL0编译程序编译原理上机实验一1.软件准备(1)、pl/0编译程序:pl0 .exe(2)、pl/0编译程序源代码程序(PASCAL程序):pl0.pas(或pl0pl0.pas)(3)、pl/0程序实例(文本文件):text.pl0, text1.pl0, test2.pl0, … text9.pl0共10个例子2.实验要求:(1)阅读pl/0源程序实例(text.pl0,test1.pl0,………text9.pl0共10个例子)理解每个PL0程序的功能;熟悉并掌握pl/0语言相关规则。
(2)用pl/0编译程序,对提供的10个例子逐一进行编译并运行。
熟悉pl/0编译程序使用操作方法。
通过理解每个实例程序的功能,编程思想,进一步理解PL/0语言的语法及其语义;提高阅读程序的能力,应用程序设计语言的编程能力;增强程序语言语法、语义意识。
(3)用pl/0语言编写以下程序,进一步熟悉PL/0语言:a、由三角形的三条边长计算三角形面积。
b、编写一个PL0过程,计算以a为直径的圆的面积。
用主程序确定圆的直径,输出计算结果。
c、编写递归程序,计算n!。
d、计算1000之内的所有素数,并输出结果。
求出1000之内所有素数之和。
(要求编写3个以上的pl/0过程实现)3.文件(软件)使用说明(1)、打开文件目录“PL0编译…”,运行PL/0编译程序(pl0.exe),按提示要求输入PL0源程序文件名(如test1.pl0),┉(2)、打开Fa2.txt文件,可看到当前经过编译并运行后的pl/0程序的目标代码及其执行结果。
(3)、打开out1.txt或out2.txt、┉或out9.txt文件,可看到各个pl/0程序实例的编译、运行、操作过程结果。
4.提交实验报告及要求(1)、简述test4.pl0 …test7.pl0各程序语法含义,执行结果。
(2)、提交实验要求编写的4个PL/0源程序及其执行结果。
(3)、简写本次实验的收获与体会。
PL/0语言编译程序分析PL/0语言是Pascal语言的一个子集,我们这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。
PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。
词法分析和代码生成作为独立的子程序供语法分析程序调用。
语法分析的同时,提供了出错报告和出错恢复的功能。
在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。
词法分析子程序分析:词法分析子程序名为getsym,功能是从源程序中读出一个单词符号(token),把它的信息放入全局变量sym、id和num中,语法分析器需要单词时,直接从这三个变量中获得。
(注意:语法分析器每次用完这三个变量的值就立即调用getsym子程序获取新的单词供下一次使用。
而不是在需要新单词时才调用getsym过程)。
getsym过程通过反复调用getch子过程从源程序过获取字符,并把它们拼成单词。
getch过程中使用了行缓冲区技术以提高程序运行效率。
词法分析器的分析过程:调用getsym时,它通过getch过程从源程序中获得一个字符。
如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到则为保留字,把sym变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把sym 置为ident,把这个单词存入id变量。
查保留字表时使用了二分法查找以提高效率。
如果getch获得的字符是数字,则继续用getch获取数字,并把它们拼成一个整数,然后把sym置为number,并把拼成的数值放入num变量。
如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把sym则成相应的类型。
如果遇到不合法的字符,把sym置成nul。
语法分析子程序分析:语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语意生成相应的代码,并提供了出错处理的机制。