编译原理课程设计报告

合集下载

编译原理课程设计报告

编译原理课程设计报告

《编译原理》课程设计报告一、课程设计目的通过课程设计进一步理解高级语言在计算机中的执行过程,了解现代编译器的运作机制,加深对编译原理中重点算法和编译技术的理解,提高自己自学和理解的能力。

学会如何利用已有软件JFLex、Java_cup对词法分析器及语法分析器的构造。

二、设计概述本tiger语言编译器的编译过程涉及到编译五个阶段中的二个,即词法分析器、语法分析器。

其中语法分析后还完成了语法树的打印的构造以及类型检查。

词法分析器由JFLex编译正则式生成,词法分析器编译产生式生成,语法分析器由CUP生成。

结果通过GUI界面呈现在使用者面前。

编译程序需要在单词级别上来分析和翻译源程序,所以首先要识别出单词,而词法分析部分的任务是:从左至右扫描源程序的字符串,按照词法规则(正则文法规则)识别出一个个正确的单词,并转换成该单词相应的二元式(种别码、属性值)交给语法分析使用。

因此,词法分析是编译的基础。

执行词法分析的程序称为词法分析器。

语法分析是编译程序的核心部分,其主要任务是确定语法结构,检查语法错误,报告错误的性质和位置,并进行适当的纠错工作。

三、设计过程(一)设计构思程序主要完成三大功能模块:词法分析器、语法分析器、GUI人机交互界面。

词法分析器由JFLex编译正则式生成,其中必须为外界提供一个获取记号流的接口,实验中定为java_cup.runtime.Symbol next_token。

语法分析器是建立在词法分析器上的,故必须包含词法分析器以便获得记号流,next_token为语法分析器提供TOKEN,语法分析器的对外接口是:java_cup.runtime.Symbol debug_parse(),同时返回语法树的根节点。

GUI 界面是提供人机交互的,它能够依次显示词法分析阶段分析得到的所有TOKEN 的信息,语法阶段生成的语法树,另外对于词法和语法阶段出现的错误在“错误提示”文本框中一一列举出来,提供用户改进代码的信息。

编译原理课程设计报告

编译原理课程设计报告

实验要求✧基本内容1)增加单词:保留字ELSE,REPEAT,DOWHILE,RETURN运算符+=,-=,++,--2)修改单词:不等号# 改为<>3)增加条件语句的ELSE子句4)扩充赋值运算:+= 和-=5)扩充语句(Pascal的FOR语句):①FOR <变量>:=<表达式> TO <表达式> DO <语句>②FOR <变量>:=<表达式> DOWNTO <表达式> DO <语句>其中,语句①的循环变量的步长为2,语句②的循环变量的步长为-2。

✧选做内容1)增加运算:++ 和--。

2)增加类型:①字符类型;②实数类型。

3)扩充函数:①有返回值和返回语句;②有参数函数。

4)增加一维数组类型(可增加指令)。

5)其他典型语言设施。

设计方案1.概述:源、目标语言:编译程序编绎的源程序是PL0,程序产生的目标代码是一个假想栈式计算机的汇编语言.称为类PCODE指令代码 ,指令格式格式如下:F L A其中F代表功能码,L表示层次差,A表示位移量,不同指令其含义有所区别。

PL/0语言是Pascal语言的一个子集,这里分析的PL/0的编译程序包括了对PL/0语言源程序进行分析处理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类PCODE代码的功能。

PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。

词法分析和代码生成作为独立的子程序供语法分析程序调用。

语法分析的同时,提供了出错报告和出错恢复的功能。

在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。

实现工具(平台),运行平台:编译器实现工具和运行平台程序用C++语言编写,在C++ Builder平台下运行。

2.结构设计说明:PL/0的编译过程采用一趟扫描方式,以语法分析为核心,词法分析程序和代码生成程序都作为一个独立的过程,当语法分析需要读入单词时就调用词法分析程序,而当语法分析正确需生成相应的目标代码时,则调用代码生成程序。

编译原理课程设计报告

编译原理课程设计报告

2011-2012学年第二学期《编译原理》课程设计报告学院:计算机科学与工程学院班级:学生姓名:学号:成绩:指导教师:时间:2012年5 月目录一、课程设计的目的 ---------------------------------------------------------------- - 1 -二、课堂实验及课程设计的内容 -------------------------------------------------- - 1 -2.1、课堂实验内容-------------------------------------------------------------- - 1 -2.2、课程设计内容-------------------------------------------------------------- - 1 -三、visual studio 2008 简介------------------------------------------------------- - 2 -四、问题分析及相关原理介绍 ----------------------------------------------------- - 3 -4.1、实验部分问题分析及相关原理介绍 ---------------------------------- - 3 -4.1.1、词法分析功能介绍及分析------------------------------------- - 3 -4.1.2、语法分析功能介绍及分析------------------------------------- - 3 -4.1.3、语义分析功能介绍及分析------------------------------------- - 4 -4.2、课程设计部分问题分析及相关原理介绍 ---------------------------- - 5 -4.2.1、编译程序介绍 ----------------------------------------------------- - 5 -4.2.2、对所写编译程序的源语言的描述(C语言) -------------- - 6 -4.2.3、各部分的功能介绍及分析 -------------------------------------- - 7 -4.3、关键算法:单词的识别-------------------------------------------------- - 8 -4.3.1、算法思想介绍 ----------------------------------------------------- - 8 -4.3.2、算法功能及分析 -------------------------------------------------- - 8 -五、设计思路及关键问题的解决方法 ------------------------------------------ - 10 -5.1、编译系统------------------------------------------------------------------ - 10 -5.1.1、设计思路 --------------------------------------------------------- - 10 -5.2、词法分析器总控算法--------------------------------------------------- - 12 -5.2.1、设计思路 --------------------------------------------------------- - 12 -5.2.2、关键问题及其解决方法 --------------------------------------- - 13 -六、结果及测试分析-------------------------------------------------------------- - 14 -6.1、软件运行环境及限制--------------------------------------------------- - 14 -6.2、测试数据说明------------------------------------------------------------ - 14 -6.3、运行结果及功能说明--------------------------------------------------- - 16 -6.4、测试及分析说明--------------------------------------------------------- - 16 -七、总结及心得体会 --------------------------------------------------------------- - 17 -7.1、设计过程------------------------------------------------------------------ - 17 -7.2、困难与收获 ------------------------------------------------------------- - 17 -八、参考文献 ------------------------------------------------------------------------ - 18 -一、课程设计的目的通过设计、编写和调试词法分析程序(又称扫描器),了解扫描器的组成结构,不同种类单词的识别方法,加深了对词法分析作用的理解。

编译原理课程设计报告报告

编译原理课程设计报告报告

编译原理课程设计报告一、目的与要求目的:在分析理解一个教学型编译程序(如PL/0)的基础上,对其词法分析程序、语法分析程序和语义处理程序进行部分修改扩充。

达到进一步了解程序编译过程的基本原理和基本实现方法的目的。

要求:对PL/0作以下修改扩充:基本内容(成绩范围:“中”、“及格”或“不及格”)(1)扩充赋值运算:+= 和-=(2)扩充语句REPEAT<语句序列>UNTIL <条件>其中,<条件>是循环条件,即条件不成立时,重复执行循环体的< 语句序列>;条件成立时,循环结束。

选做内容(成绩评定范围扩大到:“优”和“良”)(1)增加运算:++ 和--。

(2)增加类型:①字符类型;②实数类型。

(3)扩充函数:①有返回值和返回语句;②有参数函数。

(4)增加一维数组类型(可增加指令)。

(5)其他典型语言设施。

二、实验环境与工具(1)计算机及操作系统:PC机,WindowsXP(2)程序设计语言:C(3)教学型编译程序:PL/0三、设计方案(1)概述:源、目标语言,实现工具(平台),运行平台源语言: PL/0目标语言: 目标代码(生成的文件后缀为*.COD)实现平台: VC++ 6.0运行平台: WindowsXP(2)结构设计说明:各功能模块描述Error()出错处理,打印出错位置和错误编码GetCh()漏掉空格,读取一个字符GetSym()词法分析,读取一个单词GEN()目标代码生成过程,本过程用于把生成的目标代码写入目标代码数组,供后面的解释器解释执行TEST()测试当前单词是否合法过程testENTER()登陆符号表过程enterPOSITION() 在符号表中查找指定符号所在位置的函数position,如果找不到就返回0V ARDECLARATION()变量声明LISTCODE()列出目标代码清单;FACTOR()因子处理过程factorTERM()项处理过程term;EXPRESSION()表达式处理过程CONDITION()条件处理过程STATEMENT()语句处理过程BLOCK()语法分析过程BASE(): 通过静态链求出数据区基地址的函数,INTERPRET ():对目标代码解释运行过程(3)主要成分描述①符号表struct tablestruct{char name[al]; /* 名字*/enum object kind; /* 类型:const ,var ,procedure*/int val; /* 数值,仅const 使用*/int level; /* 所处层,仅const 不使用*/int adr; /* 地址,仅const 不使用*/Int size; /* 需要分配的数据区空间*/};struct tablestruct table[txmax]; /* 名字表*/②运行时存储组织和管理由于编译时目标程序运行的数据空间大小已经规定,所以存储组织属于静态存储。

编译原理课程设计 报告 论文

编译原理课程设计 报告 论文

目录1 前言 (1)2 报告主体 (1)2.1 设计目的: (1)2.2设计内容及要求: (1)2.2.1 设计符号表 (1)2.2.2 设计词法分析器 (1)2.2.3 语法分析与中间代码产生器 (2)2.2.4 优化器(选做) (2)2.2.5目标代码生成器(选做) (2)2.2.6 测试范例: (2)2.3 实现原理 (3)2.3.1 符号表的设计 (3)2.3.2 词法分析器的设计 (4)2.3.3 语法/语义分析 (5)2.4 算法实现流程图 (8)2.5 测试数据 (17)2.6结果输出及分析 (19)2.7 软件运行环境及限制 (28)2.8 心得体会 (29)2.9参考文献 (30)3 结论 (30)1 前言在网络世界中,我们往往对功能强大的程序叹为观止。

而这些强大程序的背后是编译这些程序的编译软件,是这些编译软件承托起了这些功能强大的运行程序。

我们有不少的同志致其自身于无尽的运行程序上。

而只有很少的人搞编译程序。

这就是为什么中国的可运行程序满天飞,而编译程序却很少。

本课程设计就是在这方面的探索,为你解读编译程序的奥秘。

课程设计题目选择9个题目中的一个,要求根据自己的兴趣和能力,选择一个对自己意义甚大的题目。

课程设计基本原理是在实践上,实现我们在课程上学习到的理论知识。

通过理论联系实践,更好的掌握课本上的理论知识。

2 报告主体2.1设计目的:本次课程设计是作一个集词法分析、语法分析、语义分析和中间代码生成于一体的编译器,它集中了《编译原理》里的几乎所有的思想。

不但加深了学生对编译方法的理解,而且能对学生的编程能力起到进一步提高的作用,培养学生的程序设计风格。

通过某种可视化编程语言的应用,具备初步的Windows环境下的编程思想。

2.2设计内容及要求:2.2.1 设计符号表确定符号表的组织方式,一般应包括名字栏和信息栏,其中名字栏作为关键字。

要考虑能够存储有关名字的信息,并可以高效地完成如下操作:1.查找:根据给定的名字,在符号表中查找其信息。

编译原理课程设计报告

编译原理课程设计报告

《编译原理》课程设计报告姓名:熊齐超(1208060220)姓名:刘畅(1208060221)姓名:袁青伟(1208060222)姓名:张文(1208060223)班级:软件121班专业:软件工程指导教师:陈晓明时间:2015/6/14项目名称:算术表达式的语法及语义分析贵州大学计算机科学与信息学院目录一、课程设计目的 (3)二、课程设计题目描述和要求 (3)1、算术表达式的文法的描述: (3)2、课程设计的要求描述: (3)3、实现的功能描述: (4)4、分析器的使用描述 (4)三、课程设计实现描述 (4)1、实现平台 (4)2、课程设计的基本思路描述 (5)3、自顶向下与递归下降分析方法的基本原理描述 (5)4、程序运行的最后界面 (6)5、演示分析 (8)四、课程设计总结 (8)五、参考文献及小组分工 (9)六、核心代码 (10)一、课程设计目的通过设计、编制、调试一个算术表达式的语法及语义分析程序,加深对语法及语义分析原理的理解,并实现词法分析程序对单词序列的词法检查和分析。

加深对文法分析器的知识的掌握,掌握计算机语言的语法分析的过程。

以及掌握计算机语言的语法分析程序设计与文法应用的实现方法。

能够熟练运用一种分析方法,自上而下或自下而上的方法分析一个给定的文法,我使用的是自上而下的分析方法。

以及通过思考以及动手制作分析器的过程来锻炼自己的编程能力和逻辑思维能力,体会计算机编译器的奥妙之处。

二、课程设计题目描述和要求1、算术表达式的文法的描述:〈无符号整数〉∷=〈数字〉{〈数字〉}〈标识符〉∷=〈字母〉{〈字母〉|〈数字〉}〈表达式〉∷=〈项〉{〈加法运算符〉〈项〉}〈项〉∷=〈因子〉{〈乘法运算符〉〈因子〉}〈因子〉∷=〈标志符〉|〈无符号整数〉〈加法运算符〉∷=+|-〈乘法运算符〉∷=*|/〈字母〉∷= a | b | … | z〈数字〉∷= 0 | 1 | … | 92、课程设计的要求描述:1)在递归下降法、LL(1)、算符优先分析法或者LR法中选择其中一种方法完成以上任务,中间代码选用四元式。

《编译原理》设计方案报告

《编译原理》设计方案报告

《编译原理》课程设计报告设计题目:pl0编译器设计一、PL0程序的文法及,指令及属性翻译简化c语言文法定义(LL(1)文法)C程序::=void main(){函数体}函数体::=变量定义部分语句列变量定义部分::=变量定义变量定义部分| ɛ变量定义::=int 变量表变量表::=标识符|标识符,变量表语句列::=语句语句列| ɛ语句::=条件语句| 循环语句| 读语句| 写语句| 复合语句| 表达式语句| 空语句条件语句::=if(表达式)语句循环语句::=while(表达式)语句读语句::=read(变量表);写语句::=write(表达式表);复合语句::={语句列};表达式语句::=表达式;空语句::=;表达式定义(算符优先文法)表达式::=变量=表达式| 变量+=表达式| 变量-=表达式| 变量*=表达式| 变量/=表达式| 变量%=表达式| 表达式1表达式1::=表达式1 || 表达式2 | 表达式2表达式2::=表达式2&&表达式3 | 表达式3表达式3::=表达式3==表达式4 | 表达式3!=表达式4 | 表达式3>=表达式4 | 表达式3>表达式4 | 表达式3<=表达式4 | 表达式3<表达式4 | 表达式4表达式4::=表达式4+表达式5 | 表达式4-表达式5 | 表达式5表达式5::=表达式5*表达式6 | 表达式5/表达式6 |表达式5/表达式6 |表达式6表达式6::=!表达式7表达式7::=(表达式) | 变量| 常量PL0文法定义《程序》::=《分程序》.《分程序》::=《常量定义》;《常后分程序》|《常后分程序》《常后分程序》::=《变量定义》;《变后分程序》|《变后分程序》《变后分程序》::=《过程定义》;《变后分程序》|《语句》《常量定义》::=const 《常量定义表》《常量定义表》::=id = number | id = number,《常量定义表》《变量定义》::= var 《变量表》《变量表》::=id | id,《变量表》《过程定义》::=procedure id ;《分程序》《语句》::=《赋值语句》|《条件语句》|《循环语句》|《读语句》|《写语名》|《复合语句》| 《过程调用语句》|ε《赋值语句》::=id := 《表达式》《读语句》::=read(《变量表》)《写语句》::=write(《表达式表》)《表达式表》::=《表达式》| 《表达式》,《表达式表》《条件语句》::=if 《条件表达式》then 《语句》《循环语句》::=while 《条件表达式》do 《语句》《复合语句》::=begin 《语句列》end《过程调用语句》::=call id《参量表》::=《有参表》|ε《有参表》::=《表达式》,《有参表》|《表达式》《表达式》::=+《表达式1》|-《表达式1》|《表达式1》《表达式1》::=《表达式1》+《表达式2》|《表达式1》-《表达式2》|《表达式2》《表达式2》::=《表达式2》*《表达式3》|《表达式2》/《表达式3》| 《表达式2》mod 《表达式3》|《表达式3》《表达式3》::=id | number | (《表达式》)《条件表达式》::=《条件表达式》or 《条件表达式1》|《条件表达式1》《条件表达式1》::=《条件表达式1》and 《条件表达式2》| 《条件表达式2》《条件表达式2》::=not 《条件表达式3》|《条件表达式3》《条件表达式3》::=(《条件表达式》)|《关系表达式》《关系表达式》::=《表达式》>《表达式》《关系表达式》::=《表达式》>=《表达式》《关系表达式》::=《表达式》<《表达式》《关系表达式》::=《表达式》<=《表达式》《关系表达式》::=《表达式》=《表达式》《关系表达式》::=《表达式》#《表达式》PL0栈式机指令指令格式:指令码(f) 所在层数差(l),操作数(a)PL0栈式机指令:LIT:将常数a取到栈顶LOD:将位于(当前层-l)层处的变量a取到栈顶STO:将栈顶处值存储到指定位置,l,a同上CALL 调用当前-l层处的过程aINT:为调用过程在栈中开辟数据区,a为单元个数JMP:无条件转移指令,a目标地址JPC:条件转移指令,栈顶值的布尔值为非真时转移到a处,否则执行下面语句OPR:关系运算或算术运算PL0属性翻译MCONST(const:常量定义开始), V AR(var:变量定义开始), PROCEDURE(procedure:过程定义开始),CALL(call:过程调用语句),BEGIN(begon:复合语句开始),END(end:复合语句结束),IF(if:条件语句开始),THEN(then:条件结束),WHILE(while:循环语句开始), DO(do:循环条件结束), READ(read:读语句),WRITE(write:输出语句), ODD(odd:判奇运算),//分隔符、运算符号DOT(点:.),COMMA(逗号:,), SEMICOLON(分号:;), LPAREN(左括号:(), RPAREN(右括号:)), ASSIGNOP(赋值::=), PLUSOP(加法运算符号:+), MINUSOP(减法运算符:-), MULTOP(乘法运算符:*), DIVOP(除法运算符:/),GT(大于:>),GE(大于等于:>=),LT(小于:<),LE(小于等于:<=),EQ(等于:=),NE(不等:#),ENDF(输入结束符),//分析过程中需要的非终结符号SERVERKEY(保留字), FACTOR(因子),ROP(关系运算), CONSTANT(常量部份定义), V ARIABLE(变量部份定义), IDENT(自定义标识符), NUMBER(常数)二、符号表的结构,组织,填写及查找1、符号表结构const char *pName; //符号名称int kind; //符号类别,由上面单词分类确定int val; //符号表中的位置值int level; //符号的层数int parent; //符号的作用域int size; //过程长度char strBuff[MAXLENSTR]; //符号堆2、符号表的组织符号表的组织方式有:线性表、散列表、树结构等,其必须维持源程序中的作用域信息。

编译原理课设报告ll0

编译原理课设报告ll0

编译原理课设报告ll0编译原理课设报告LL(0)。

一、引言。

编译原理是计算机科学与技术领域的重要课程之一,它研究如何将高级程序语言翻译成机器语言。

LL(0)是一种重要的语法分析方法,它是一种自顶向下的分析方法,通过构建语法树来实现对程序语言的分析和翻译。

本报告将介绍LL(0)语法分析的原理、算法以及课设的设计与实现。

二、LL(0)语法分析原理。

LL(0)语法分析是一种基于预测分析表的自顶向下语法分析方法。

它通过预测下一个输入符号,根据文法规则进行推导,最终构建出语法树。

LL(0)的意思是“左侧扫描、左推导、0个向前看符号”。

LL(0)语法分析的关键是构建预测分析表,该表包含了文法的非终结符和终结符的组合,以及对应的产生式。

通过分析输入串和预测分析表,可以确定下一个推导所使用的产生式,从而构建语法树。

三、LL(0)语法分析算法。

1. 构建First集和Follow集。

在LL(0)语法分析中,需要先构建每个非终结符的First集和Follow集。

First集表示该非终结符能够推导出的终结符集合,Follow集表示在该非终结符的右侧能够出现的终结符集合。

2. 构建预测分析表。

根据文法的产生式和First集、Follow集,构建预测分析表。

预测分析表的行表示文法的非终结符,列表示文法的终结符。

表中的每个格子填写对应的产生式。

3. 进行语法分析。

根据输入串和预测分析表,进行语法分析。

从左到右扫描输入串,根据当前输入符号和栈顶符号,在预测分析表中查找对应的产生式。

将产生式右侧的符号入栈,并将输入串向右移动一个位置。

重复这个过程,直到输入串为空或者出现错误。

四、课设设计与实现。

1. 文法设计。

根据课设要求,设计符合LL(0)语法分析方法的文法。

文法应该满足左递归消除、左因子消除等要求,以便于构建预测分析表。

2. 构建预测分析表。

根据设计的文法,构建预测分析表。

根据文法的非终结符和终结符,填写预测分析表中的产生式。

编译原理课程设计报告毕业论文

编译原理课程设计报告毕业论文

编译原理课程设计报告一、课程设计目的通过课程设计,可以进一步了解高级语言在计算机中的执行过程,了解现代编译器的运行机制,加深对编译原理中关键算法和编译技术的理解,提高自学和理解能力。

了解如何利用现有软件JFLex和Java_cup构造词法分析器和解析器。

二、设计概述这个tiger语言编译器的编译过程涉及到编译五个阶段中的两个,即词法分析器和语法分析器。

其中,解析后完成语法树打印的构建,以检查类型。

词法分析器由JFLex 编译器正则公式生成,词法分析器由编译器产生式生成,解析器由CUP生成。

结果通过GUI界面呈现给用户。

编译器需要对源程序进行单词级的分析和翻译,所以首先要做的就是识别单词,而词法分析的任务就是从左到右扫描源程序的字符串,根据词法规则(常规语法规则)识别出正确的单词,并转换成单词对应的二进制形式(类别码,属性值)进行语法分析。

所以词法分析是编译的基础。

执行词法分析的程序叫做词法分析器。

语法分析是编译器的核心部分。

它的主要任务是确定语法结构,检查语法错误,报告错误的性质和位置,并进行适当的纠错。

三、设计程序(一)设计构思该程序主要完成三个功能模块:词法分析器、语法分析器和GUI人机界面。

词法分析器由JFLex编译正则公式生成,其中必须为外界提供一个获取令牌流的接口。

实验中命名为Java _ cup . runtime . symbol next _ token。

解析器是建立在词法分析器上的,所以它必须包含词法分析器来获取令牌流。

next_token为解析器提供了令牌。

解析器的对外接口是:Java _ cup . runtime . symbol debug _ parse(),它返回语法树的根节点。

GUI 提供人机交互。

它可以顺序显示词法分析阶段获得的所有标记信息和语法阶段生成的语法树。

此外,词法和语法阶段的错误会在“错误提示”文本框中列出,为用户提供改进代码的信息。

流程图:鲍·阿布辛Print.java//打印出语法树……//Tiger 的抽象语法类数据包错误消息ErrorMsg.java//用于生成包含详细信息的错误消息为cupparser 打包Java _ cup.runtime//support包解析Grm.java//解析分析器MainInterface.java//图形用户界面Sym.java//令牌的十进制表示Yylex.java//莱克斯分析器包装语义Entry.java//用于值环境中的绑定Env.java//保存一个值、类型环境和一个错误打印机ExpTy.java//持有翻译和类型检查的结果FunEntry.java//用于函数绑定程序输入流 词法分析程序 GUI 界面句法分析程序 代币 语法树 标记流 错误的语法和类词汇错误Semant.java//主类型检查模块VarEntry.java//用于变量绑定包装符号Symbol.java//使字符串成为独特的符号对象Table.java//用示波器做环境包翻译包类型//描述tiger _ languagetypes(二)词法分析程序这部分工作主要是通过正则表达式的编写,熟悉使用JFLex正确编写正则表达式,并生成相应的词法分析器。

《编译原理》设计方案报告

《编译原理》设计方案报告

《编译原理》设计方案报告一、项目概述二、课程目标本课程的主要目标是使学生能够掌握编译器的设计与实现原理,理解编译过程中的各个环节,以及掌握常见的编译器构建工具和技术。

具体目标如下:1.理解编译器的基本原理和工作流程;2.掌握常见的编译器构建工具和技术;3.能够独立设计和实现简单的编译器;4.培养学生的系统设计和问题解决能力。

三、课程内容本课程的主要内容包括:1.编译器的概念和基本原理;2.词法分析器和语法分析器的设计与实现;3.语义分析和中间代码生成;4.优化和目标代码生成;5.编译器构建工具和技术。

四、教学方法本课程采用以学生为中心的教学方法,主要包括以下几种教学手段:1.模块化教学:将课程内容分为多个模块,每个模块进行独立的教学和实践;2.理论与实践相结合:通过理论课、实验课等形式,使学生能够将理论知识应用到实际中;3.项目驱动教学:引入编译器设计与实现的实际项目,让学生能够在实践中巩固所学的知识;4.小组合作学习:将学生分成小组,进行协作学习,增强学生的团队合作能力。

五、评价方式为了评价学生对课程内容的掌握程度,本课程采用以下评价方式:1.平时成绩:包括课堂表现、作业和实验成绩等;2.项目成果:针对编译器设计与实现的项目,评价学生的项目成果和实现质量;3.期末考试:以闭卷考试形式对学生的总体掌握情况进行评价。

六、项目进度安排本课程的项目进度安排如下:1.第1-2周:介绍编译器的概念和基本原理;2.第3-6周:词法分析器和语法分析器的设计与实现;3.第7-9周:语义分析和中间代码生成;4.第10-12周:优化和目标代码生成;5.第13-14周:编译器构建工具和技术;6.第15-16周:项目演示和总结。

七、教学资源支持为了支持本课程的教学,我们将提供以下教学资源:1.教材:选用经典的编译原理教材,如《编译原理》(龙书)等;2.课件:编写详细的课件,包括理论知识和实践案例;3.实验指导:编写实验指导书,引导学生进行编译器设计与实现的实践;4. 实验环境:提供编译器构建工具和开发环境,如Lex/Flex、Yacc/Bison等。

编译原理课程设计报告

编译原理课程设计报告

编译技术课程设计——表达式的小型编译器专业:计算机1201学生姓名:贺茂纯指导教师:年轶完成时间:2015年7月2日一、目的 _________________________________________________ 1二、题目 _________________________________________________ 1三、要求 _________________________________________________ 11.词法分析___________________________________________ 12.语法分析___________________________________________ 13.代码生成___________________________________________ 24.错误处理___________________________________________ 2四、实验环境 _____________________________________________ 2五、系统实现 _____________________________________________ 21.词法分析___________________________________________ 22.语法分析___________________________________________ 43.中间代码___________________________________________ 64.错误处理___________________________________________ 8六、程序运行结果 _________________________________________ 91.准确的语句分析______________________________________ 92.错误的算术表达式___________________________________ 13七、总结 ________________________________________________ 16一、目的<<编译技术>>是理论与实践并重的课程,而其课程设计要综合运用一、二年级所学的多门课程的内容,用来完成一个小型编译程序。

编译课程设计报告

编译课程设计报告

编译课程设计报告一、教学目标本课程的教学目标是使学生掌握编译原理的基本概念、方法和算法,培养学生运用编译原理解决实际问题的能力。

具体目标如下:1.知识目标:(1)了解编译原理的基本概念,如编译器、源语言、目标语言等。

(2)掌握编译过程中的各个阶段,如词法分析、语法分析、语义分析、中间代码生成、目标代码生成等。

(3)熟悉常见编译优化技术,如代码简化、死代码消除、循环优化等。

(4)了解编译器实现的基本方法,如递归下降分析、LL分析、LR分析等。

2.技能目标:(1)能够使用编译原理相关工具,如lex、yacc等。

(2)具备简单的编译器设计与实现能力。

(3)能够分析程序的性能,并应用编译优化技术进行优化。

3.情感态度价值观目标:(1)培养学生对编译原理的兴趣,提高学生自主学习的积极性。

(2)培养学生团队合作精神,提高学生解决实际问题的能力。

二、教学内容本课程的教学内容主要包括以下几个部分:1.编译原理基本概念:介绍编译器、源语言、目标语言等基本概念。

2.编译过程及其各个阶段:讲解词法分析、语法分析、语义分析、中间代码生成、目标代码生成等阶段。

3.编译优化技术:介绍代码简化、死代码消除、循环优化等优化技术。

4.编译器实现方法:讲解递归下降分析、LL分析、LR分析等实现方法。

5.编译器工具使用:介绍lex、yacc等工具的使用方法。

6.编译器设计与实现:讲解编译器的设计与实现过程。

三、教学方法本课程采用讲授法、讨论法、案例分析法和实验法等多种教学方法,以激发学生的学习兴趣和主动性。

1.讲授法:用于讲解编译原理的基本概念、方法和算法。

2.讨论法:学生针对编译原理中的重点、难点问题进行讨论,提高学生的理解能力。

3.案例分析法:通过分析实际案例,使学生更好地掌握编译原理的应用。

4.实验法:让学生亲自动手实现简单的编译器,提高学生的实践能力。

四、教学资源本课程的教学资源包括教材、参考书、多媒体资料和实验设备等。

1.教材:选用《编译原理》等权威教材,为学生提供系统、科学的学习资料。

编译原理课程设计报告(一个完整的编译器)

编译原理课程设计报告(一个完整的编译器)

编译原理程序设计报告一个简单文法的编译器的设计与实现专业班级:计算机1406班组长姓名:宋世波组长学号: ******** 指导教师:肖桐2016年12月设计分工组长学号及姓名:宋世波20143753 分工:文法及数据结构设计词法分析语法分析(LL1)基于DAG的中间代码优化部分目标代码生成组员1学号及姓名:黄润华20143740 分工:中间代码生成(LR0)部分目标代码生成组员2学号及姓名:孙何奇20143754 分工:符号表组织部分目标代码生成摘要编译器是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能解读、运行的低阶机器语言的程序。

编译是从源代码(通常为高阶语言)到能直接被计算机或虚拟机执行的目标代码(通常为低阶语言或机器语言)的翻译过程。

一.编译器的概述1.编译器的概念编译器是将便于人编写,阅读,维护的高级计算机语言翻译为计算机能解读、运行的低阶机器语言的程序。

编译器将原始程序作为输入,翻译产生使用目标语言的等价程序。

源代码一般为高阶语言如Pascal、C++、Java 等,而目标语言则是汇编语言或目标机器的目标代码,有时也称作机器代码。

2.编译器的种类编译器可以生成用来在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码,这种编译器又叫做“本地”编译器。

另外,编译器也可以生成用来在其它平台上运行的目标代码,这种编译器又叫做交叉编译器。

交叉编译器在生成新的硬件平台时非常有用。

“源码到源码编译器”是指用一种高阶语言作为输入,输出也是高阶语言的编译器。

例如: 自动并行化编译器经常采用一种高阶语言作为输入,转换其中的代码,并用并行代码注释对它进行注释(如OpenMP)或者用语言构造进行注释(如FORTRAN的DOALL指令)。

3.本编译器概述编译程序的工作过程一般可以分为五个阶段:词法分析、语法分析、语义分析与中间代码产生、优化、目标代码生成。

每一个阶段在功能上是相对独立的,它一方面从上一个阶段获取分析的结果来进行分析,另一方面由将结果传递给下一个阶段。

编译原理教程实验报告

编译原理教程实验报告

一、实验目的本次实验旨在使学生通过编译原理的学习,了解编译程序的设计原理及实现技术,掌握编译程序的各个阶段,并能将所学知识应用于实际编程中。

二、实验内容1. 词法分析2. 语法分析3. 语义分析4. 中间代码生成5. 代码优化6. 目标代码生成三、实验步骤1. 词法分析(1)设计词法分析器,识别输入源代码中的各种词法单元;(2)使用C语言实现词法分析器,并进行测试。

2. 语法分析(1)根据文法规则设计语法分析器,识别输入源代码的语法结构;(2)使用C语言实现语法分析器,并进行测试。

3. 语义分析(1)设计语义分析器,检查语法分析后的语法树,确保语义正确;(2)使用C语言实现语义分析器,并进行测试。

4. 中间代码生成(1)设计中间代码生成器,将语义分析后的语法树转换为中间代码;(2)使用C语言实现中间代码生成器,并进行测试。

5. 代码优化(1)设计代码优化器,对中间代码进行优化,提高程序性能;(2)使用C语言实现代码优化器,并进行测试。

6. 目标代码生成(1)设计目标代码生成器,将优化后的中间代码转换为特定目标机的汇编语言;(2)使用C语言实现目标代码生成器,并进行测试。

四、实验结果与分析1. 词法分析实验结果:成功识别输入源代码中的各种词法单元,包括标识符、关键字、运算符、常量等。

2. 语法分析实验结果:成功识别输入源代码的语法结构,包括表达式、语句、程序等。

3. 语义分析实验结果:成功检查语法分析后的语法树,确保语义正确。

4. 中间代码生成实验结果:成功将语义分析后的语法树转换为中间代码,为后续优化和目标代码生成提供基础。

5. 代码优化实验结果:成功对中间代码进行优化,提高程序性能。

6. 目标代码生成实验结果:成功将优化后的中间代码转换为特定目标机的汇编语言,为程序在目标机上运行做准备。

五、实验心得1. 编译原理是一门理论与实践相结合的课程,通过本次实验,我对编译程序的设计原理及实现技术有了更深入的了解。

编译原理课程设计报告

编译原理课程设计报告

编译原理课程设计报告编译原理课程设计——简单编译器的设计与实现班级:组长:组员:指导教师:设计时间: 12月摘要....................................... 错误!未定义书签。

1.概述 ..................................... 错误!未定义书签。

2.课程设计任务及要求 ....................... 错误!未定义书签。

2.1 设计任务............................ 错误!未定义书签。

2.2 设计要求............................ 错误!未定义书签。

3.算法及数据结构 ........................... 错误!未定义书签。

3.1算法的总体思想(流程)............... 错误!未定义书签。

3.2词法分析模块......................... 错误!未定义书签。

3.2.1功能........................... 错误!未定义书签。

3.2.2数据结构 ....................... 错误!未定义书签。

3.2.3算法........................... 错误!未定义书签。

3.3语法分析(含语义分析和中间代码生成)模块错误!未定义书签。

3.3.1功能........................... 错误!未定义书签。

3.3.2数据结构 ....................... 错误!未定义书签。

3.3.3算法........................... 错误!未定义书签。

3.4中间代码优化模块..................... 错误!未定义书签。

3.4.1功能........................... 错误!未定义书签。

3.4.2数据结构 ....................... 错误!未定义书签。

编译原理课程设计报告

编译原理课程设计报告

LL(1) 语法分析器一、课程设计的目的通过课程设计进一步理解高级语言在计算机中的执行过程,加深对编译原理中重点算法和编译技术的理解,提高自己的编程能力,培养好的程序设计风格。

同时通过某种可视化编程语言的应用,具备初步的Windows环境下的编程思想。

解和掌握LL(1)语法分析方法的基本原理;根据给出的LL(1)文法,掌握LL(1)分析表的构造及分析过程的实现。

二、课程设计的要求及其方法语法分析程序要求实现sample语言中几种最常见的、基本的语法单位的分析:算术表达式,逻辑表达式,赋值语句,if语句,for语句,while语句,repeat 语句等,各个语法单位的定义如下:Sample语言的定义<字符>::=<字母>|<数字>|<界符><字母>::=a|b|c…|z|A|B|C…|Z<数字>::=0|1|2|3…|9<单界符>::=+|-|*|/|=|<|>|(|)|[|]|:\;|,|’|_|.单词集的定义(1) <单词集>::=<保留字>|<双界符>|<标识符>|<常数>|<单界符>(2) <保留字>::=and|array|begin|bool|call|case|case|char|const|do|dlse|end|false|for|if|input|integer|not |of|or|output|program|read|real|repeat|set|then|to|true|until|var|while|write(3)<双界符>::=/*|*/|<=|>=|<>|:=(4)<标识符>::=<字母>|<标识符><数字>|<标符><字母>(5)<常数>::=<整数>|<布尔常数>|<字符常数>|常数标识符>|<实数>(6)<整数>::=<数字>|<整数><数字>(7)<布尔常数>::=true|false(8)<字符常数>::=’除’以外的任意字符串’(9)<常数标识符>::=<标识符>(10)<实数>::=<整数>.<整数>数据类型的定义(1)<简单类型>:==integer|bool|char|real表达式的定义(1)<表达式>::=<算术表达式>|<逻辑表达式>(2)<算术表达式>::=<项>+-<算术表达式>|+-<项>|<项>(3)<项>:==<项>*<因子>|<项>/<因子>|<因子>(4)<因子>::=<算术量>(5)<算术量>::=<标识符>|<整数>(6)<逻辑表达式>::=<布尔项>or<逻辑表达式>|<布尔项>(7)<布尔项>::=<布尔因子>and<布尔项>|<布尔因子>(8)<布尔因子>::=<布尔量>|not<布尔因子>(9)<布尔量>::=<逻辑表达式>|<布尔常数>|<标识符>|<算术表达式><关系符><算术表达式>(10)<关系符>::=<|>|<>|<=|>=|=语句的定义(1)<语句>::=<说明语句>|<执行语句>(2)<说明语句>::=<常数说明><变量说明>(3)<常量说明>::=const<常数定义>|ε(4)<常数定义>::=标识符=<常数>;<常数定义>|标识符=<常数>;<变量说明>::=var<变量定义>|ε<变量定义>::=<标识符表>:<类型>;|<标识符表>:<类型>;<变量定义><标识符表>::=<标识符>,<标识符表>|<标识符><执行语句>::=<简单句>|<结构句><简单句>::=<赋值句><赋值句>::=<变量>:=<表达式><变量>::=<标识符><结构语句>::=<复合句>|<if语句>|<while语句>|<for语句>|<repeat语句><复合句>::=begin<语句表>end<语句表>::=<执行句>;<语句表>|<执行句><if语句>::=if<布尔表达式>then<执行句><if语句>::=if<布尔表达式>then<执行句1>else<执行句2><while语句>::=while<布尔表达式>do<执行句><for语句>::=for<标识符>::=<算术表达式1>to<算术表达式2>do<执行句> <repeat语句>::=repeat<执行句>until<布尔表达式>程序定义(1)<程序>::=program<标识符>;<分程序>(2)<分程序>::=<常量说明><变量说明><复合句>本次语法分析器课程设计采用LL(1)自顶向下析法来实现。

编译原理课程设计报告

编译原理课程设计报告

编译原理课程设计报告一、分析通过设计,编制,调试一个语法及语义分析程序,加深对语法及语义分析原理的理解。

IF 〈布尔表达式〉THEN 〈赋值语句〉ELSE 〈赋值语句〉其中(1)、可以选择递归下降法、LL(1)、算符优先分析法、LR法完成以上任务,中间代码选用四元式。

(2)、写出符合分析方法要求的文法,给出分析方法的思想,完成分析程序设计。

(3)、编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

二、算法设计程序要求有三部分组成,即词法分析、语法分析、以及语义分析。

其中词法分析部分要求完成对输入程序的关键字、标识符、常数、运算符进行识别;并分析词法分析的结果,检查程序输入的关键字是否为符合设计文法的关键字,检查标志符是否是合法标志符,识别运算符的种类。

语法分析部分主要是以算符优先文法的设计思想和步骤完成对词法分析结果的的语法分析工作,判断输入的程序是否符合设计的IF-THEN-ELSE文法。

在语法分析通过的基础上进行语义分析,其主要任务是完成对语法分析后的程序的语义分析,根据语法制导翻译去翻译输入的程序,从而得到程序的中间代码表示形式——四元式。

词法分析、语法分析和语义分析的流程图如下:(1)词法分析A 词法分析器的功能和输出形式输入:所给文法的源程序字符串输出:二元组(单词种别,单词符号的属性值)构成的序列B. 待分析的简单语言的词法因为是模拟简单编译器, 所以就以C语言的小型子集作为模拟编译器的词法.模拟程序语言的单词符号可分为下列五种;关键字: { (相当于Pascal语言中的begin) , if ,else , while , }(相当于Pascal语言中的end ) 所有的关键字都是小写字母 .运算符: + , - , * , / , = , < , <= , == , > , >= ,<> , && ,|| , !界符: 逗号 ,分号 ,左圆括号 , 右圆括号 , #常数: 在这里只涉及到int型常量其他单词是标识符(ID)和整形常数(NUM),通过以下正规式定义:ID = letter(letter|digit)*NUM = digit digit *空格由空白,制表符和换行符组成,空格一般用来分隔ID,NUM,运算符,界符和关键字,词法分析阶段通常会被过滤掉。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

武汉纺织大学编译原理课程设计实验报告学院:数学与计算机专业:计算机姓名:班级:学号:constdccl rtrfilri onVEM'decl OTIli-expression to ftnconditionintet'prct函数:)过程或曲数名功能简蔑说咽pio主程序error出错处理*打印出错位苫和错误编码gdsym词济分祈,煤取一t单詞秦理空格,读収「牛字苻生止目标优码.井送入目林序区test義试当前单诵符是否合法block务析程启噩理讨稈enterpnwfiion(画慰)查找标识符在名字丢中肿位置constdeclaratiDn常虽定克牲理TardeclaratiDn变虽主兗魁理listccxle列出目掃诧码詩单statemeiitespressiiMi盂这式处理tennfactorcrnidiiicn条件辿埋iiiteipret刖日标吒码购解释执厅程序通过静蠱穆求;L数据仅的宰地圳编译原理课设报告一、实验目的加强对编译程序的整体认识和了解,巩固《编译原理》课程所学知识。

通过本次课程设计掌握编译程序调试技巧和设计编译程序一般的原则,加深对词法分析、语法分析、语义分析等编译阶段及实用编译系统的认识。

使学生能将编译理论与实际应用结合起来,提高学生软件开发的能力。

二、实验内容1)仔细阅读PL/O编译程序文本(编译原理(第二版)张素琴吕映芝蒋维杜戴桂兰主编清华大学出版社),并上机调试通过。

2)对PL/0语言进行下列扩充(1)扩充一维整型数组。

扩充var数组:VAR <数组标识名>(<下界>:<上界>)〈下界〉和〈上界〉可用常量标识名。

(2)扩充条件语句的功能使其为:IF<条件>THEN齬句>[ELSE语句>](3)增加repeat重复语句:REPEAT<语句>{;<语句>}UNTIL<条件>可根据自己具体情况从中选择2个以上题目进行扩充。

三、实验原理PL/0语言可以看成PASCALS言的子集,它的编译程序是一个编译解释执行系统。

PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关。

PL/0的编译程序和目标程序的解释执行程序都是用PASCAL语言书写的,因此PL/0语言可在配备PASCAL语言的任何机器上实现。

其编译过程采用一趟扫描方式,以语法分析程序为核心,词法分析和代码生成程序都作为一个独立的过程,当语法分析需要读单词时就调用词法分析程序,而当语法分析正确需要生成相应的目标代码时,则调用代码生成程序。

用表格管理程序建立变量、常量和过程表示符的说明与引用之间的信息联系。

当源程序编译正确时,PL/0编译程序自动调用解释执行程序,对目标代码进行解释执行,并按用户程序的要求输入数据和输出运行结果。

编译原理errortest隔麺功能说阴孟:四、实验分析PL/O语言编译程序采用以语法分析为核心、一遍扫描的编译方法。

词法分析和代码生成作为独立的子程序供语法分析程序调用。

语法分析的同时,提供了出错报告和出错恢复的功能。

在源程序没有错误编译通过的情况下,调用类PCODE解释程序解释执行生成的类PCODE代码。

词法分析子程序分析:词法分析子程序名为GETSYM功能是从源程序中读出一个单词符号(TOTAKEN,把它的信息放入全局变量SYM ID和NUM中,字符变量放入CH中,语法分析器需要单词时,直接从这三个变量中获得。

Getch过程通过反复调用Getch子过程从源程序过获取字符,并把它们拼成单词。

GETCH过程中使用了行缓冲区技术以提高程序运行效率。

词法分析器的分析过程:调用GETSYM时,它通过GETCH过程从源程序中获得一个字符。

如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把SYM变量赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字),把SYM置为IDENT,把这个单词存入ID变量。

查保留字表时使用了二分法查找以提高效率。

如果Getch获得的字符是数字,则继续用Getch获取数字,并把它们拼成一个整数或实数,然后把SYM置为INTEGER或REAL并把拼成的数值放入NUM变量。

如果识别出其它合法的符号(比如:赋值号、大于号、小于等于号等),则把SYM则成相应的类型。

如果遇到不合法的字符,把SYM 置成NUL。

语法分析子程序分析:语法分析子程序采用了自顶向下的递归子程序法,语法分析同时也根据程序的语义生成相应三元代码,并提供了出错处理的机制。

语法分析主要由分程序分析过程(BLOCK、参数变量分析过程(ParaDeclaration、、参数变量处理过程(ParaGetSub)、数组处理过程(ParaGetSub)、常量定义分析过程(ConstDeclaration、、变量定义分析过程(Vardeclaration、、语句分析过程(Stateme nt )、表达式处理过程(Expressio n)、项处理过程(Term)、因子处理过程(Factor、和条件处理过程(Condition、构成。

这些过程在结构上构成一个嵌套的层次结构。

除此之外,还有出错报告过程(Error)、代码生成过程(Gen)、测试单词合法性及出错恢复过程(Test)、登录名字表过程(Enter、、查询名字表函数(Position)以及列出类PCODE 代码过程(Listcode、作过语法分析的辅助过程。

由PL/0的语法图可知:一个完整的PL/0程序是由分程序和句号构成的。

因此,本编译程序在运行的时候,通过主程序中调用分程序处理过程block来分析分程序部分(分程序分析过程中还可能会递归调用block过程),然后,判断最后读入的符号是否为句号。

如果是句号且分程序分析中未出错,则是一个合法的PL/0程序,可以运行生成的代码,否则就说明源PL/0程序是不合法的,输出出错提示即可。

if-then-else语句的处理:按if语句的语法,首先调用逻辑表达式处理过程处理if语句的条件,把相应的真假值放到数据栈顶。

接下去记录下代码段分配位置(即下面生成的jpc指令的位置),然后生成条件转移jpc指令(遇0或遇假转移),转移地址未知暂时填0。

然后调用语句处理过程处理then 语句后面的语句或语句块。

then后的语句处理完后,如果遇到else,就调用语句处理过程处理else语句后面的语句或语句块,这时当前代码段分配指针的位置就应该是上面的jpc指令的转移位置。

通过前面记录下的jpc指令的位置,把它的跳转位置改成当前的代码段指针位置,否则没遇到else,那么此时的当前代码段分配指针的位置也是上面jpc指令的转移位置,也是通过前面记录下的jpc位置指令的位置,把它的跳转到当前的代码段指针位k-i/ii■< !-|XVh luDotlWh kidraidJlRepeat 语句的处理:首先用CX1变量记下当前代码段分配位置,作为循环的开始位置。

然后通过递归调用语句 分析过程分析,直到遇到until 保留字,如果未对应 until 则出错。

调用条件表达式处理过程生成相应代码把结果放在数据栈顶,再生成条件转移指令,转移位置为上面记录的CX1。

tSkl宝 £ 丿 .2」实验代码;PLO.h 代码: #in elude <stdio.h> #in elude <set> #in elude <stri ng> #in elude <iostream> #in elude <iostream> #in elude <veetor> #ifndef WIRTH ZYC #define WIRTH ZYC using n amespaee std;〃 no. of reserved words 保留字的个数// le ngth of ide ntifier table 标示符表的长度(容量)// le ngth of ide ntifiers 标示符的最大长度// max. no. of digits in nu mbers 数字的最大长度 // maximum address 寻址空间 // maximum depth of block nest ing最大允许的块嵌套层数// size of code array 类PCODE 目标代码数组长度 (可容纳代 const int lineLength = 82; // 行缓冲区长度T 二)<Z>m五、 相关代码及运行结果 con st i nt norw = 16; con st i nt txmax = 100; const int al = 10; con st i nt nmax = 14; con st i nt amax = 2047;con st i nt levmax = 3; con st i nt exmax =typedef enum{NUL,IDENT,NUMBER,PLUS,MINUS,TIMES,SLASH,ODDSYM,EQL,NEQ,LSS,LEQ,GTR,GEQ,LPAREN,RPAREN,COMMA,SEMICOLON,PERIOD,BECOMES,BEGINSYM,ENDSYM,IFSYM,THENSYM,WHIL ESYM,WRITESYM,READSYM,DOSYM,CALLSYM,CONSTSYM,VARSYM,PROCSYM,ELSESYM,REPEATSY M,UNTILSYM} symbol; // symobl 类型标识了不同类型的词汇typedef char alfa[al+1]; // alfa 类型用于标识符typedef enum {CONSTANT,VARIABLE,PROCEDURE,ARRAY} obj0; // 三种标识符的类型typedef enum {LIT,OPR,LOD,STO,CAL,INT,JM,JPC} fct; // functionstypedef set<symbol> symset;struct instruction{fct f; // function codeint l; // level,cann't big than levmaxint a; // displacement address,cann't big than amax}; //类PCODE指令类型,包含三个字段:指令f、层差I和另一个操作数a/******************************************** Iit 0,a: Ioad constant a* opr 0,a: execute operation a* Iod I,a: Ioad variabIe I,a* sto I,a: store variabIe I,a* caI I,a: caII procedure a at IeveI I* int 0,a: increment t-register by a* jmp 0,a: jump to a* jpc 0,a: jump conditionaI to a *******************************************/typedef struct{aIfa name;obj0 kind;union {struct{int IeveI,adr,size;}inOther; int vaI;}other;} TabIe;cIass PL0{protected:bool listswitch,sourceEnd; char ch; symbol sym; II last character read II last symbol read II last identifier read II last number readalfa int id; num;int cc; II character count int ll;II line lengthint kk,err;int cx;II code allocation index int codeNo;II code line no.// error string// code line// error array// 词法分析器中用于临时存放正在分析的词// destination code array // 保留字表// 保留字表中每一个保留字对应的 symbol // 一些符号对应的 symbol 类型表II 类PCODE 指令助记符表symset declbegsys,statbegsys,facbegsys; // 声明开始、表达式开始和项开始符号集个字符static string errStr[]; char line[lineLength];vector<string> errorString; alfa a;instruction code[cxmax+1]; alfa word[norw+1];symbol wsym[norw+1]; 类型 symbol ssym[100]; char mnemonic[8][6];合Table table[txmax+1]; FILE* fin,*fout; public:PL0(char* source,char*destination); ~PL0(){fclose(fin),fclose(fout);}void error(int n);位置和出错代码void getsym();个单词void getch();II 符号表II 构造函数 II 析构函数II 出错处理, 打印出错II 词法分析,读取一 II 漏掉空格, 读取一void gen(fct x,int y,int z); II 生成目标代码,并送入目标void test(symset s1,symset s2,int n);合法void block(int lev,int tx,symset fsys); //分程序分析处理过程void enter(obj0 k,int &tx,int &dx,int lev); //登入名字表int position(alfa id,int tx);// 查找标示符在名字表中的位置void constdeclaration(int&tx,int&dx,int lev); // 常量定义处理void vardeclaration(int&tx,int&dx,int lev);//变量说明处理void listcode(int cx0);// 列出目标代码清单void statement(symset fsys,int tx,int lev); //语句部分处理void expression(symset fsys,int tx,int lev); // 表达式处理void term(symset fsys,int tx,int lev); // 项处理void factor(symset fsys,int tx,int lev);//因子处理void condition(symset fsys,int tx,int lev);// 条件处理void arraydeclaration(int& tx,int& dx,int lev);// 数组说明处理void interpret();// 对目标代码的解释执行程序int base(int l,int b,int s[]);// 通过静态链求出数据区的基地址void SaveCode();// 保存代码};#endifPL0.cpp 代码: #include "pl0.h" // 错误字符串数组string PL0::errStr[]={" ","error 0001: 常数说明中“ =”写成“: =” ", "error 0002: 常数说明中的“ =”后应为数字 ","error 0003: 常数说明中的标识符后应是“ =” ", "error 0004: const,var,procedure 后应为标识符 ", "error 0005: 漏掉了‘ ,'或‘ ;' ","error 0006: 过程说明后的符号不正确(应是语句开始符或过程开始符) "error 0007: 应是语句开始符 ","error 0008: 过程体内语句部分的后跟符不正确 ", "error 0009: 程序皆为丢了句号‘ .' ", "error 0010: 语句之间漏了‘ ;' ", "error 0011: 标识符没说明 ","error 0012: 赋值语句中,赋值号左部标识符属性应是变量 ", "error 0013: 赋值语句左部标识符应是赋值号 :=",程序区// 测试当前单词符号是否"error 0014: call 后应为标识符","error 0015: call 后标识符属性应为过程","error 0016: 条件语句中丢了then","error 0017: 丢了end 或;","error 0018: while 型循环语句中丢了do","error 0019: 语句后的标识符不正确","error 0020: 应为关系运算符","error 0021: 表达式内标识符属性不能是过程","error 0022: 表达式中漏掉了右括号‘ )' ","error 0023: 因子后的非法符号","error 0024: 表达式开始符不能是此符号","error 0025: 文件在不该结束的地方结束了","error 0026: 结束符出现在不该结束的地方","error 0027: ","error 0028: ","error 0029: ","error 0030: " "error 0031: 数越界","error 0032: read 语句括号中标识符不是变量","error 0033: else 附近错误" ,"error 0034: repeat 附近错误"};// PL0 构造函数PL0::PL0(char* source,char*destination) {listswitch=true,sourceEnd=false;strcpy(word[1],"begin"); strcpy(word[2],"call");// 初始化存储保留字strcpy(word[3],"const"); strcpy(word[4],"do"); strcpy(word[5],"else"); strcpy(word[6],"end");strcpy(word[7],"if"); strcpy(word[8],"odd"); strcpy(word[9],"procedure");strcpy(word[10],"read"); strcpy(word[11],"repeat"); strcpy(word[12],"then");strcpy(word[13],"until"); strcpy(word[14],"var"); strcpy(word[15],"while");strcpy(word[16],"write");wsym[1]= BEGINSYM; wsym[2]= CALLSYM;// 初始化保留字表中每一个保留字对应的symbol 类型wsym[3]= CONSTSYM; wsym[4]= DOSYM;wsym[5]= ELSESYM; wsym[6]= ENDSYM;wsym[7]= IFSYM; wsym[8]= ODDSYM;wsym[9]= PROCSYM; wsym[10]= READSYM;wsym[11]= REPEATSYM; wsym[12]=THENSYM;wsym[13]= UNTILSYM; wsym[14]= VARSYM; wsym[15]= WHILESYM; wsym[16]=WRITESYM;memset(code,0,sizeof(code)); memset(ssym,0,100*sizeof(symbol));memset(table,0,sizeof(table));memset(line,0,sizeof(line));ssym['+']= PLUS; // 初始化一些符号对应的symbol 类型表ssym['-']= MINUS;ssym['*']= TIMES;ssym['/']= SLASH;ssym['(']= LPAREN;ssym[')']= RPAREN;ssym['=']= EQL;ssym[',']= COMMA;ssym['.']= PERIOD;ssym['#']= NEQ;ssym['<']= LSS;ssym['>']= GTR;ssym[';']= SEMICOLON;strcpy(mnemonic[LIT]," lit"); // 初始化类PCODE指令助记符表strcpy(mnemonic[OPR]," opr "); strcpy(mnemonic[LOD]," lod "); strcpy(mnemonic[STO]," sto"); strcpy(mnemonic[CAL]," cal "); strcpy(mnemonic[INT]," int ");strcpy(mnemonic[JMP]," jmp "); strcpy(mnemonic[JPC]," jpc ");declbegsys.insert(CONSTSYM),declbegsys.insert(VARSYM),declbegsys.insert(PROCSYM); // 初始化声明开始符号集合statbegsys.insert(BEGINSYM),statbegsys.insert(CALLSYM),statbegsys.insert(IFSYM),statb egsys.insert(WHILESYM); // 初始化表达式开始符号集合facbegsys.insert(IDENT),facbegsys.insert(NUMBER),facbegsys.insert(LPAREN); // 初始化项开始符号集合err= 0;cc= 0;cx= 0;置生成新的代码ll= 0;ch= ' ';kk= al;codeNo=0;fin=fopen(source,"r");fout=fopen(destination,"w");}// 行缓冲区指针// 代码分配指针,代码生成模块总在// 行缓冲区长度// last character read// 引入此变量是出于程序性能考虑// code line no.// 出错处理,打印出错位置和出错代码void PL0::error(int n){char s[10];sprintf(s," 第%d 行:",codeNo); errorString.push_back(s+errStr[n]); err=err+1;//error count}//error end// 词法分析,读取一个单词void PL0::getsym(){if(sourceEnd)return;int i,j,k;while (ch ==' '||ch==9)getch(); // cls space and tab if(isalpha(ch)) // id or reserved word {k=0;memset(a,0,al+1);// 检测一个单词长度do{if (k < al){a[k]= ch; k= k+1;cx 所指位}getch();if(sourceEnd)return; }while(isalpha(ch)||isdigit(ch)); if(k >= kk) kk = k;else{do{a[kk]= ' ';kk= kk-1;}while(kk > k);}strcpy(id,a);i= 1;j= norw;// 判断是否是关键字(二分搜索) do{k= (i+j) / 2;if(strcmp(id, word[k])<=0) j= k-1;if(strcmp(id,word[k])>=0)i= k+1;}while(i<=j);if(i-1 > j)sym= wsym[k];elsesym= IDENT;}else if(isdigit(ch)) // number{k= 0;num= 0;sym= NUMBER;do{num= 10 * num + ch - '0';k= k+1;getch();}while(isdigit(ch));if(k > nmax)error(30);}else if (ch == ':'){getch();if( ch == '='){sym= BECOMES;getch();}elsesym= NUL;}else if(ch == '<') // extra stuff added to support <={getch();if (ch== '='){sym= LEQ;getch();}elsesym= LSS;}else if (ch == '>'){getch();if( ch == '='){sym= GEQ;getch();}elsesym= GTR;}else // end of extra stuff{sym= ssym[ch]; // 其它符号的赋值getch();}}// 漏掉空格,读取一个字符void PL0::getch(){if(cc == ll){if(feof(fin)){}if(sym!=PERIOD)error(25); sourceEnd=true; return; }cc= 0; fgets(line,lineLength,fin); codeNo++; ll=strlen(line);if(line[ll-1]==10) ll--;}ch= line[cc];cc= cc+1;}// 生成目标代码,并送入目标程序区void PL0::gen(fct x,int y,int z){if (cx > cxmax){cout<<"Program too long\n";return;}code[cx].f= x;code[cx].l= y;code[cx].a= z;cx= cx+1;}//gen end// 测试当前单词符号是否合法void PL0::test(symset s1,symset s2,int n){if(sourceEnd) return;if (s1.find(sym)==s1.end()){error(n);symset::iterator it;for(it=s2.begin();it!=s2.end();it++) s1.insert(*it);//s1=s1+s2 while(s1.find(sym)==s1.end()) getsym();}//test end// 分程序分析处理过程void PL0::block(int lev,int tx,symset fsys){ if(sourceEnd) return;int dx; // data allocation index int tx0; // initial table index int cx0; // initial code index dx= 3; // 变量的个数tx0= tx; // 表指针table[tx].other.inOther.adr= cx; gen(JMP,0,0);if( lev>levmax) error(32);do{if( sym == CONSTSYM) // 处理常量声明{getsym(); do{constdeclaration(tx,dx,lev); while (sym == COMMA) {getsym(); constdeclaration(tx,dx,lev);}if (sym ==SEMICOLON)getsym();else error(5);}while(sym==IDENT);}if( sym == VARSYM) // 处理变量声明{getsym(); do{vardeclaration(tx,dx,lev); while( sym == COMMA){ getsym();vardeclaration(tx,dx,lev);}if( sym ==SEMICOLON)getsym();elseerror(5);}while(sym==IDENT);}while( sym ==PROCSYM) // 处理过程的声明{getsym();if (sym ==IDENT){ enter(PROCEDURE,tx,dx,lev); getsym();}elseerror(4);if( sym ==SEMICOLON)getsym();elseerror(5);symset tmp = fsys;tmp.insert(SEMICOLON);block(lev+1,tx,tmp);if (sym == SEMICOLON){ getsym(); symset tmp = statbegsys; for(int i=IDENT;i<=PROCSYM;i++) tmp.insert((symbol)i);test(tmp,fsys,6);}elseerror(5);}symset tmp=statbegsys;tmp.insert(IDENT); test(tmp,declbegsys,7);}while(declbegsys.find(sym)!=declbegsys.end());code[table[tx0].other.inOther.adr].a= cx; table[tx0].other.inOther.adr= cx; // start adr of code table[tx0].other.inOther.size=dx;cx0= cx;gen(INT,0,dx);symset tmp=statbegsys;for(int i=SEMICOLON;i <= ENDSYM;i++)tmp.insert((symbol)i);statement(tmp,tx,lev);gen(OPR,0,0); // returnsymset s2;test(fsys,s2,8);listcode(cx0);}// block end// 登入名字表void PL0::enter(obj0 k,int &tx,int &dx,int lev){tx= tx+1;strcpy(table[tx].name,id);table[tx].kind=k;switch(k){case CONSTANT:if(num>amax){error(31);num=0;}table[tx].other.val=num;break;case VARIABLE: table[tx].other.inOther.level=lev; table[tx].other.inOther.adr=dx; dx++;break;case PROCEDURE: table[tx].other.inOther.level=lev; break;case ARRAY:table[tx].other.inOther.size = lev;break;}}//enter end// 查找标示符在名字表中的位置int PL0::position(alfa id,int tx)//find identifier id in table { int i; strcpy(table[0].name, id);i= tx;while (strcmp(table[i].name,id)!=0)i--;return i;}//position end// 常量定义处理void PL0::constdeclaration(int&tx,int&dx,int lev){if(sym == IDENT){getsym();if(sym>=EQL&&sym<=BECOMES){if( sym ==BECOMES)error(1);getsym();if( sym == NUMBER){enter(CONSTANT,tx,dx,lev); getsym();}elseerror(2);}elseerror(3);}elseerror(4);}// constdeclaration end// 变量说明处理void PL0::vardeclaration(int&tx,int&dx,int lev){if( sym == IDENT){enter(VARIABLE,tx,dx,lev);getsym();}elseerror(4);}//vardeclaration end// 数组说明处理void PL0::arraydeclaration(int&tx,int&dx,int lev){int upscript=0,downscript=0; getsym();if(sym == NUMBER || sym == CONSTSYM){if(num == 0){ upscript = num; getsym();}else error(32);} if(sym == COMMA) getsym();elseerror(32);if(sym == NUMBER || sym == CONSTSYM){downscript = num; getsym();} if(sym != RPAREN)error(32);else{ enter(ARRAY,tx,dx,downscript+1); getsym();}}// 列出目标代码清单void PL0::listcode(int cx0)//list code generated for this block {int i; if(listswitch)for (i= cx0;i<cx;i++) cout<<" "<<i<<" "<<mnemonic[code[i].f] <<" "<<code[i].l<<""<<code[i].a<<endl;}// listcode end// 语句部分处理void PL0::statement(symset fsys,int tx,int lev){ if(sourceEnd) return;int i,cx1,cx2;if(sym ==IDENT){i= position(id,tx);if (i == 0)error(11);else if (table[i].kind!=VARIABLE){error(12);i= 0;}getsym();if(sym ==BECOMES)getsym();elseerror(13);expression(fsys,tx,lev);if(sym != SEMICOLON)error(10);if( i!= 0)gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr); }else if( sym == READSYM){getsym();if( sym!=LPAREN)error(34);elsedo{getsym();if (sym==IDENT)i=position(id,tx);elsei=0;if( i==0 )error(35);else{gen(OPR,0,16); gen(STO,lev-table[i].other.inOther.level,table[i].other.inOther.adr);}getsym();}while(sym == COMMA);if (sym != RPAREN){error(33);while (fsys.find(sym)!=fsys.end()) getsym();}elsegetsym();}else if( sym == WRITESYM ){getsym();if (sym==LPAREN){do{getsym();symset tmp=fsys;for(int t=RPAREN;t<=COMMA;t++)tmp.insert((symbol)t);expression(tmp,tx,lev);gen(OPR,0,14);}while(sym==COMMA);if (sym!=RPAREN)error(33);elsegetsym();}gen(OPR,0,15);}else if( sym ==CALLSYM){getsym();if( sym!=IDENT)error(14);else{i= position(id,tx);if (i == 0)error(11);else if (table[i].kind = PROCEDURE)gen(CAL,lev-table[i].other.inOther.level,table[i].other.inOther.adr);else error(15);getsym();}}else if( sym ==IFSYM){getsym();symset tmp=fsys;for(int i = THENSYM;i<= DOSYM;i++)tmp.insert((symbol)i); condition(tmp,tx,lev); if( sym == THENSYM)getsym();elseerror(16); cx1= cx; gen(JPC,0,0); tmp.insert(ELSESYM); statement(tmp,tx,lev);getsym(); code[cx1].a= cx;if(sym == ELSESYM){getsym();cx2=cx; gen(JMP,0,0); code[cx1].a=cx; statement(fsys,tx,lev); code[cx2].a=cx;}}else if( sym ==BEGINSYM){getsym();symset tmp=fsys;for(int i=SEMICOLON;i<=ENDSYM;i++)tmp.insert((symbol)i); statement(tmp,tx,lev); tmp=statbegsys;tmp.insert(SEMICOLON); while( tmp.find(sym)!=tmp.end()) {if(sourceEnd)return;if (sym ==SEMICOLON||sym ==ENDSYM) getsym();else if(sym=PERIOD){error(26);getsym();}elseerror(10);tmp=fsys;for(i=SEMICOLON;i<=ENDSYM;i++)tmp.insert((symbol)i); if(sourceEnd)return; if(sym==ENDSYM)break;statement(tmp,tx,lev);}if( sym ==ENDSYM) getsym();else if(!sourceEnd) error(17);}else if(sym ==WHILESYM) {cx1= cx;getsym();symset tmp=fsys;tmp.insert(DOSYM);condition(tmp,tx,lev); cx2= cx;句的开始位置gen(JPC,0,0);if(sym ==DOSYM) getsym();elseerror(18); statement(fsys,tx,lev); gen(JMP,0,cx1); code[cx2].a= cx;} else if(sym == REPEATSYM) {symset temp1, temp2; temp1=fsys,temp1.insert(SEMICOLON),temp1.insert(UNTILSYM); cx1= cx;getsym(); statement(temp1,tx,lev); temp2 = statbegsys;temp2.insert(SEMICOLON); while(temp2.find(sym) != temp2.end()){if(sym == SEMICOLON) getsym();else error(34);statement(temp1,tx,lev);}if(sym == UNTILSYM){ getsym(); condition(fsys,tx,lev); gen(JPC,0,cx1);}else error(34);} symset setT; test(fsys,setT,19);}//statement end// 记下当前代码分配位置, 这是 while 循环的开始// 记下当前代码分配位置, 这是 while 的 do 中的语// 表达式处理void PL0::expression(symset fsys,int tx,int lev){symbol addop;symset tmp=fsys;for(int t=PLUS;t<=MINUS;t++) tmp.insert((symbol)t);if( sym>=PLUS&&sym<=MINUS){ addop= sym; getsym();term(tmp,tx,lev);if( addop ==MINUS)gen(OPR,0,1);}elseterm(tmp,tx,lev);while (sym >=PLUS&&sym<=MINUS){addop= sym;getsym(); term(tmp,tx,lev); if (addop ==PLUS) gen(OPR,0,2);elsegen(OPR,0,3);}}// expression end// 项处理void PL0::term(symset fsys,int tx,int lev){if(sourceEnd)return;symbol mulop;symset tmp=fsys;for(int t=TIMES;t<=SLASH;t++)tmp.insert((symbol)t);factor(tmp,tx,lev);while( sym>=TIMES && sym<=SLASH){mulop= sym;getsym();factor(tmp,tx,lev);if (mulop ==TIMES)gen(OPR,0,4);elsegen(OPR,0,5);}}// term end// 因子处理void PL0:: factor(symset fsys,int tx,int lev){int i;test(facbegsys,fsys,24);while(facbegsys.find(sym)!=facbegsys.end()) {if( sym ==IDENT) {i= position(id,tx);if( i == 0)error(11);elseswitch(table[i].kind){case CONSTANT: gen(LIT,0,table[i].other.val); break;case VARIABLE: gen(LOD,lev-table[i].other.inOther.level,table[i].other.inOther.adr); break;case PROCEDURE: error(21); break;}getsym();}else if (sym ==NUMBER){if (num>amax){error(31);num= 0;}gen(LIT,0,num);getsym();}else if( sym ==LPAREN){getsym();symset tmp=fsys;tmp.insert(RPAREN);expression(tmp,tx,lev);if (sym == RPAREN)getsym();elseerror(22);} test(fsys,facbegsys,23);}}//factor end// 条件处理void PL0::condition(symset fsys,int tx,int lev){symbol relop;symset tmp=fsys;tmp.insert(EQL),tmp.insert(NEQ),tmp.insert(LSS),tmp.insert(LEQ),tmp.insert(GTR),tmp.i nsert(GEQ);if( sym == ODDSYM){expression(fsys,tx,lev);gen(OPR,0,6);}else{expression(tmp,tx,lev);if(tmp.find(sym)==tmp.end())error(20);else{relop= sym;getsym();expression(fsys,tx,lev);switch(relop){case EQL: gen(OPR,0,8);break;case NEQ: gen(OPR,0,9);break;case LSS: gen(OPR,0,10);break;case GEQ: gen(OPR,0,11);break;case GTR: gen(OPR,0,12);break;case LEQ: gen(OPR,0,13);break;}}}}//condition end// 对目标代码的解释执行程序void PL0::interpret(){int err1=errorString.size(); if(err1>0){cout<<"存在%d 个错误:"<<err1<<endl;for(int i=0;i<err1;i++) cout<<errorString[i]<<endl;//return;}const int stacksize = 500;int p=0,b=1,t=0;//program-,base-,topstack-registersinstruction i;// instruction registerint s[stacksize+1]={0};// datastorecout<<" Start PL/0\n";do{i= code[p];p= p+1;{case LIT:t= t+1;s[t]= i.a; break;case OPR: switch(i.a) //operator {case 0:// return t= b-1; p= s[t+3]; b= s[t+2]; break;case 1:s[t]= -s[t]; break;case 2:t= t-1;s[t]= s[t]+s[t+1]; break;case 3:t= t-1;s[t]= s[t]-s[t+1]; break;case 4:t= t-1;s[t]= s[t]*s[t+1];break;case 5:t= t-1;s[t]= s[t] / s[t+1];break;case 6:if(s[t]%2) s[t]=1;elses[t]=0;break;case 8:t= t-1;if(s[t]==s[t+1]) s[t]=1;elses[t]=0;break;case 9:t= t-1;if(s[t]==s[t+1]) s[t]=0;elses[t]=1;break;case 10:t= t-1;if(s[t]<s[t+1]) s[t]=1;elses[t]=0;break;case 11:t= t-1;if(s[t]>=s[t+1]) s[t]= 1;else s[t]=0;break;case 12:t= t-1;if(s[t]>s[t+1]) s[t]= 1;else s[t]=0;break;case 13:t= t-1;if(s[t]<=s[t+1])s[t]= 1;elses[t]=0;break;case 14:cout<<" "<<s[t];t=t-1;break;case 15:cout<<endl;break;case 16:t=t+1;cout<<"?";s[t]=0;cin>>s[t];break;};break;case LOD:t= t+1;s[t]= s[base(i.l,b,s)+i.a]; break; case STO:s[base(i.l,b,s)+i.a]= s[t];t= t-1;break;case CAL:// generate new block marks[t+1]= base(i.l,b,s);s[t+2]= b;s[t+3]= p;b= t+1;p=i.a;break;case INT:t= t+i.a;break; case JMP:p= i.a;break; caseJPC:if (s[t] == 0)p= i.a; t= t-1; break;}//switch end }while(p!=0); cout<<" End PL/0\n";} // interpret end// 通过静态链求出数据区的基地址int PL0::base(int l,int b,int s[]) {int b1;b1= b;//find base l levels down while(l>0){b1= s[b1];l= l-1;}return b1;}// 保存代码void PL0::SaveCode(){ if(fout)for (int i=0;i<cx;i++)fprintf(fout,"%d %s %d %d\n ",i,mnemonic[code[i].f],code[i].l,code[i].a);}TestPLO.cpp 代码:#include "pl0.h"void main(){PL0 cp("testPas2.txt","nasm.txt");symset fsys;fsys.insert(PERIOD); fsys.insert(CONSTSYM),fsys.insert(VARSYM),fsys.insert(PROCSYM); fsys.insert(BEGINSYM),fsys.insert(CALLSYM),fsys.insert(IFSYM),fsys.insert(WHILESYM);cp.getsym();cp.block(0,0,fsys); cp.SaveCode(); cp.interpret();// 词法分析,分析一个词// 分程序分析处理功能// 保存代码// 对目标代码的解释执行程序}实验运行结果:运行的的文件见下图右侧:实验中我是固定了文件名的,可以是改写成动态输入,由于在测试中我把所有的测试语句都放在同一个文件中了,没有太多的必要。

相关文档
最新文档