一个PASCAL语言子集(PL0)编译器的设计与实现_第1页
一个PASCAL语言子集(PL0)编译器的设计与实现_第2页
一个PASCAL语言子集(PL0)编译器的设计与实现_第3页
一个PASCAL语言子集(PL0)编译器的设计与实现_第4页
一个PASCAL语言子集(PL0)编译器的设计与实现_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

编译原理课程设计报告班:姓:2007-12

编译原理课程设计报告目录计任务理框图数说明序代码序测试验体会考资料第1页

编译原理课程设计报告一.设任务课程设计的学基本要求1.巩固和深对编译原理的理解,提高综合运用本课程所学知识的能力。2.培养独思考,深入研究,分析问题、解决问题的能力。3.能够按求编写课程设计报告书,能正确阐述设计和实验结果,正确绘制系统和程序框图。4.通过课设计,培养严肃认真的工作作风。课程设计题目一个语言子集()编译器的设计与实现

PL/0语的BNF描述(扩充的巴斯范式示法)program<id><block><block>→[<condecl>][<vardecl>][<proc>{;<proc>}]<body>const<const>→<id>:=<integer><vardecl>var<id>{,<id>}→<id>{,<id>})];<block><body>begin<statement>{;<statement>}end<statement>→<id>:=<exp>|if<lexp><statement>]do(<exp>{,<exp>})]|<body>|read(<id>{,<id>})|write(<exp>{,<exp>})→<exp>→[+|-]<term>{<aop><term>}<term><factor>{<mop><factor>}<factor><id>|<integer>|(<exp>)→+|-<mop>→*|/<id>→l{l|d}(注:l表示字母)→d{d}注释:<prog>程序<block>块程序体常量说明<const>常量:变量说明<proc>分序;复合语句语<exp>表式;:件;<term>项<factor>因子;:加法运算符<mop>乘法运算符;<lop>:关系运符。

假想目机的代码LIT0,a取常量a放入数据栈栈顶第2页

编译原理课程设计报告OPR0,a执行运算,a表示执行某种运算LODL,a取变量(相对地址为a,层差为)放到数据栈的栈顶STOL,a将数据栈栈顶的内容存入变量(相对地址为,层次差为L)CALL,a调用过程(转子指令入口地址为,层次差为L)INT0,a数据栈栈顶指针增加aJMP0,a无条件转移到地址为a的指令JPC0,a条件转移指令,转移到地址为a指令REDL,a读数据并存入变量(相对地址为,层次差为L)WRT0,0将栈顶内容输出代码的具体形式:FLA其中:F段代表伪操作码L段代表调用层与说明层的层差值A段代表位移量(相对地址)进一步说明:INT:为被调用的过程(包括主过程)在运行栈中开辟数据区,这时为所需数据单元个数(包括三个连接数据段恒为0。CAL:调用过程,这时A为被调用过程的过程体(过程体之前一条指令)在目标程序区的入口地址。LIT:将常量送到运行栈S的栈顶,这时A段为常量值。LOD:将变量送到运行栈S的栈顶,这时A段为变量所在说明层中的相对位置。STO:将运行栈栈顶内容送入某个变量单元中,为变量所在说明层中的相对位置。JMP:无条件转移,这时A段为转向地址(目标程序JPC:条件转移,当运行S的栈顶的布尔值为假0)时,则转A段所指目标程序地址;否则顺序执行。OPR:关系或算术运算,A段指明具体运算。

假机结两个存储器:存储器CODE,用来存放P的代码数据存储器STACK(栈)用来动态分配数据空间四个寄存器:一个指令寄存器I:存放当前要执行的代码一个栈顶指示器寄存器T:指向数据栈STACK栈顶一个基地址寄存器B:存放当前运行过程的数据区在中的起始地址一个程序地址寄存器P:存放下一条要执行的指令地址该假想机没有供运算用的寄存器有运算都要在数据栈的栈顶两个单元之间进行,并用运算结果取代原来的两个运算对象而保留在栈顶。

活动记:第3页

编译原理课程设计报告RADLRA:返回地址DL:调用者的活动记录首地址SL:保存该过程直接外层的活动记录首地址过程返回可以看成是执行一个特殊的OPR运算注意:层次差为调用层次与定义层次的差值程序实要求PL/0语言可以看成PASCAL言的子集,它的编译程序是一个编译解释执行系统。PL/0的目标程序为假想栈式计算机的汇编语言,与具体计算机无关。PL/0的编译程序和目标程序的解释执行程序都是用语言书写的,因此PL/0语言可在配备PASCAL语言的任何机器上实现。其编译过程采用一趟扫描方式,以语法分析程序为核心,词法分析和代码生成程序都作为一个独立的过程,当语法分析需要读单词时就调用词法分析程序,而当语法分析正确需要生成相应的目标代码时,则调用代码生成程序。用表格管理程序建立变量、常量和过程表示符的说明与引用之间的信息联系。用出错处理程序对词法和语法分析遇到的错误给出在源程序中出错的位置和错位性质。当源程序编译正确时PL/0编译程序自动调用解释执行程序对目标代码进行解释执行,并按用户程序的要求输入数据和输出运行结果。第4页

编译原理课程设计报告二.原理与框图一).PL/0编译程功能的框架PL/0的译程序包括了对语源程序进行分析理、编译生成类PCODE代码,并在虚拟机上解释运行生成的类代的功能。PL/0源序PL/0译程类pcode代类pcode解释序输入

输出)编程的体计PL/0语言编译程序采用以语法分析为核心、一遍扫描的编译方法。词法析和代码生成作为独立的子程序供语法分析程序调用语分析需要读单词时就调用词法分析程序当语法语义分析正确要成应的目标代码时调用代码生成程序法析的同时,提供了出错报告和出错恢复的功能。在源程序没有错误编译通过的情况下,调用类解释程序解释执行生成的类代。PL/0源序法程格理序

法分序码程标第5页

Y编译原理课程设计报告Y()法析程分:SYM:存放单词的类别ID:存放用户所定义的标识的值:存放用户定义的数词法分析子程序名为GetSym能是从源程序中读出一个单词符号它的信息放入全局变量symid和num中,语法分析器需要单词时,接从这三个变量中获得过通过反复调用子程从源程序过获取字,并把它们拼成单词。采用循环分支法。词法分析器的分析过程:调用getsym时它通过过程从源程序中获得一个符。如果这个字符是字母,则继续获取字符或数字,最终可以拼成一个单词,查保留字表,如果查到为保留字,则把sym变赋成相应的保留字类型值;如果没有查到,则这个单词应是一个用户自定义的标识符(可能是变量名、常量名或是过程的名字sym置ident,把这个单词存入id量查留字表时使用了二分法查找以提高效率果获的字符是数字,则继续用获取数字,并把它们拼成一个整数,然后把sym置,并把拼成的数值放入num变量。如果识别出其它合法的符号(比如:赋值号、大号、小于等于号等把sym则相应的类型。如果遇到不合法的字符,把sym置成nul。通过三个全程量SYMID和NUM将识别出的单词信息传递给语法分析程序。*词法源程序Y

输入缓冲区获取一个字符是否为空格

读入一个字符是否为字母或数字N

YN是否是字母

Y

退回一个字符N

判断获取的字符串是否为保留字

Y

返回保留字读入一个字符

Y

是否是数字

N插入符号表、返回标志符Y

是否为数字

N是否是=

类型及在符号表中的指针返回=N退回一个字符插入常数表返回整数数据类型及在常数表中的指针

N是否是+N

YY

返回+读入一个字符是否是*N...NERROR

是否为*N退回一个字符返回*

Y

返回**循环和分支方法实现简单语言词法分析器的程序流程示意图第6页

编译原理课程设计报告说明:为枚举类型,定义如下enumsymbol{/*枚举类型*//*1*/SYM_const=2,/*2*//*3*/SYM_procedure,/*4*//*5*//*6*//*7*//*8*/SYM_then,/*9*/SYM_else,SYM_while,SYM_read,SYM_write,/*16标符*SYM_number,/*17数字*,/*:=*//*+*//*-*/,/***/SYM_div,/*/*/SYM_lpar/*(*/SYM_rpar/*)*//*;*/SYM_comma,/*,*/SYM_lss/*<*//*28*//*<=*/SYM_gtr,/*>*//*>=*//*=*//*<>*/}SYM;()语分子序析语法分析子程序采用了自顶向下的递归子程序法分同时也根据程序的语意生成相应的代码,并提供了出错处理的机制。语法分析主要由分程序分析过程block量定义分析过(变量定义分析程(语句析程(达处理过程(expression处理过程term子理过程()和条件处理过(构成这过程在结构上构成一个嵌套的层次结构此外,还有出错报告过程error码成过程试词合法性及出错恢复过程test登录名字表过字表函position及出类PCODE代码过)作过语法分析的辅助过程。下面按各语法单元分析PL/0编程序的运行机制。()程序使用到的产生式:program<id>;<block>注:这里加符号表时,类型为;第7页

编译原理课程设计报告program

ident;

分程()程序理程block相应的产生式有:<block>→[<condecl>][<vardecl>][<proc>]<body>const<const>→<id>:=<integer><vardecl>var<id>{,<id>}→<id>{,<id>})];<block>{;<proc>}<body>begin<statement>{;<statement>}end语法分析开始后,首先调用分程序处理过程block处理分程序。过程入口参数置为:、符号表位置0、出错恢复单词集合为句号、明符或语句开始符。进入过后,首先把局部数据段分配指针设为3,准备分配3个单元运行期存放静态链SL、动态链和返回地址RA然后用tx0记录下当前符号表位置并产生一条指,准备跳转到主序的开始位置,由于当前还没有知到主程序究竟在何处开始,所以jmp的标暂时填为0稍后再改时在符号表的当前位置记录下这个指在码段中的位置先判断是否遇到了常量声明如果遇到则开常量定义常量存入符号表接去用同样的方法分析变量声明,变量定义过程中会用dx变记录下局部数据段分配的空间个数。然后如遇到保字则进行过程声明和定义,声明的方法是把过程的名字和所在的层次记入符号表,过程定义的方法就是通过递归调用block过程,因为个过程都是一个分程序。由于这是分程序中的分程序,因此调用时需把当前的层次号加传递给block过。分程序声明部分完成后,即将进入语句的处理,这时的代码分配指针的正好指语句的开始位置个置正是前面jmp指需要跳转到的位置是过前面记录来的地址值,把这个指的跳转位置改成当前位置。并在符号表中记录下当前的代码段分配地址和局部数据段要分配的大小的成条int指,分配dx空间,作为这个分程序段的第一条指令。下面就调用语句处理过程statement分析语句。分析完成后,生成操作数为的指,用于分程序返回(对于层的主程序来说,就是程序运行完成,退出分程序处理过程阶段分为以下步骤,按顺序执行:1.常量定义过程(通过循环反获得标识符和对的值存入符号表符表中记录下标识符的名字和它对应的值。2.变量定义过程(与常量定义类似,通过循环,反复获得标识符,存入符号表。符号表中记录下标识符的名字、它所在的层及它在所在层中的偏移地址。过声明和定义proc把过程的名字和所在的层次记入符号表义的方法就是通过递归调用block程,因为每个过程都是一个分程序里主要要考虑过程大小的定方法size的定需要等到过程里变量等分析完之后才可确定下来。通过记录偏移地址确定值。注:处程义,为带数过程的合语句分析。第8页

编译原理课程设计报告:=,

var,(

形式参数表

);过程

;复合语句()Body分:begin

语)

语statement

;第9页

编译原理课程设计报告()句理程statememt:语句处理过程是一个嵌套子程序过调用表达式处理项处理因处理等过程及递归调用自己来实现对语句的分析。语句处理过程可以识别的语句包括赋值语句语、write语句call语、if语、while语。当遇到语时,就递归调用己来分析。分析的同时生成相应的类指令。赋值语句的处理:首先获取赋值号左边的标识符符号表中找到它的信息确认这个标识符确为变量名通过调用表达式处理过程算得赋值号右部的表达式的值并生成相应的指令保证这个值放在运行期的数据栈顶后过前面查到的左部变量的位置信息成应的sto指令,把栈顶值存入指定的变量的空间,实现了赋值操作。使用的产生式:<statement>→<id>:=ident

=

表达式(exp)句的处理:使用的产生式:<statement>→,<id>})确定read语语法合理的前提下(否则报错成应的指(ident),write语句的处理:使用的产生式:<statement>→(<exp>{,<exp>})与语句相似。在语法正确的前提下,生指令:通过循环调用表达式处理过程分析write语括号中的每一个表达式,生成相应指。write(),call语句的处理:从符号表中找到call语右部的标识符获得其所在层次和偏移地址后生成相应的指。至于调用子过程所需的保护现场等工作是由类PCODE解释程序在解释执行cal指令时自动完成的。使用的产生式:<statement>→(<exp>{,<exp>})]第10页

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

)if句的处理:按if语的语法,首先调用逻辑表达式处理过程处理if语的条件,把相应的真假值放到数据栈顶。接下去记录下代码段分配位置(即下面生成的jpc指令的位置后成条件转移(0或遇假转移地未知暂时填0然后调用语句处理过程处理语后面的语句或语句块then后语句处理完后当前代码段分配指针的位置就应该是上面的jpc指令的转移位置。通过前面记录下的指的位置,把它的跳转位置改成当前的代码段指针位置当存在else语时则将真出口的语句块执行完之后添加一条jmp指令,假出口的语句地址为jmp代之后的句,即比原先的跳转地址加而jmp的转地址需要分析完后语句得到的当前cx。即做到执行完真出口的语句之后程序能够自动跳过条件语句假出口对应的语句块。使用的产生式:<statement>→if<lexp>thenif

statement

statementbegin/end句的处理:通过循环遍历语句块中的每一个语句,过递归调用语句分析过程分析并生成相应代码。使用的产生式:<statement>→<body>begin

statement;语句的处理:首先用cx1变记下当前代码段分配位置,作为循环的开始位置。然后处理while语中的条件表达式生成相应代码把结果放在数据栈顶用cx2量记下当前位置成条件转移指令,转移位置未知,填。通过递归调用语句分析过程分析语后的语句或句块并生成相应代码。最后生成一条无条件跳转指令jmp跳转到cx1所位置,并把所指的条件跳转指令的跳转位置改成当前代码段分配位置。使用的产生式:<statement>→while<statement>第

编译原理课程设计报告

statement表达式项因处:使用产生式表式

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

项-项

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

*/因

→<id>|<integer>|(<exp>)ident表达式(

)逻表式处理首先判断是否为一元逻辑表达式奇偶如是则通过调用表达式处理过程分析计算表达式的值,然后生成判奇指令。如果不是,则肯定是二元逻辑运算符,通过调用表达式处理过程依次分析运算符左右两部分的值在栈顶的两个空间中后不同的逻辑运算符,生成相应的逻辑判断指令,放入代码段。使用产生式<<lop><exp>|odd<exp>第12页

编译原理课程设计报告表达式()符表理

关系运算符表达式

(lop

表达式在声明常量,变量,过程的同时,需要进行符号表的登记操作(enter(在语句执行的时候,在遇到标识符则要通过对符号表的查询(position(得该标识符的相关信息,提供给目标代码生成使用。号定:enumobject{constant=1,variable=2,procedur=3};struct{name[ID_MAX_NUM];enumobjectkind;int/*次/值*intint}table[txmax];对常量,变量,过程三种不同的类型使用同一种存储空间类型,三者主要kind相区别。符号表:其中为CONSTANTlv代Kind为VARIABLE时lv代表:

:35……

……

:49:::::LEV+1……

……

()目代的成1.目标代码终形:LIT0,a取常量a入数据栈栈顶OPR执运算,示执行某种运算LODL,a取变量(相对地址为a层差为L放到数据栈的栈顶L,a将据栈栈顶的内容存入变量(相对地址为a层次差为LCALL,a调过程(转子指令口地址为a层次差为L数据栈栈顶指针增加0,a无件转移到地址为a的指令第13页

编译原理课程设计报告JPC0,a条件转移指,转移到地址为的指令L,a读数据并存入变量(相对地址为,层次差为),0将顶内容输出OPR同取值时:OPR0过调用结束,回调用点并退栈OPR,1栈元素取反OPR,2次顶与栈顶相加,两个栈元素,结果值进栈OPR,3次顶减去栈顶,退个栈元素,结果值进栈OPR,4次顶乘以栈顶,退个栈元素,结果值进栈OPR,5次顶除以栈顶,退个栈元素,结果值进栈OPR,6栈元素的奇偶判断结果值在栈顶OPR,8次顶与栈顶是否相,退两个栈元素,结果值进栈OPR,9次顶与栈顶是否不,退两个栈元素,结果值进栈OPR,次栈顶是否小于栈顶,退两个栈元素,结果值进栈OPR,栈顶是否大于等于栈顶,退两个栈元素,结果值进栈OPR,次栈顶是否大于栈顶,退两个栈元素,结果值进栈OPR,次栈顶是否小于等于栈顶,退两个栈元素,结果值进栈

目标代生成过程函数名

:功能gen

产生中间代码()于语法单元:表达式)、项term)以及因子)它们的翻译规则可以用规则(1)至()式表示,其中(A)表示对符号串A进翻译:T(″term)=T()(1)T(-″term)Tterm)-()T(″+)()()″()T(-)=Tterm1T()″-(4T(*)=T()(factor2)*(5T(″factor2)=()()(6T((″expression))=T)(7有了这些翻译规则,可以使过程将表达式转换为后缀表达式的任务大大简化。赋语句的翻译处理赋值语句的翻译处理规则:T(∶=″expression)T(expression),,adr)其中,(expression完成对表达式的翻译,会得到相应的一串代指令,第14页

编译原理课程设计报告执行这一串代码指令得到的表达式计算结果最终会存放在栈顶lev-level,adr)是将栈顶数据存入到“lev-level”确定的栈地址单元识ident的量中。其中,lev是值语句所在程序的静态级level是量ident被明时的静态级别;adr是变量的移地址。上述赋值语句的翻译处理规则与赋值语句语义分析完全一致,因而实现了对赋值语句的翻译。while语的翻译处理下式表示while语的翻译处理规则:T(″while″condition″do″statement):T()Gen(JpcL2)Tstatement)Gen(JmpL1)L2„其中,()完成对关系式condition的译,会得到相应的一串代码指令。执行这一串代码指令得到的关系式计算结果会存放在栈顶。若关系式成立,计算结果为;若关系式不成立,结果为0Jpc”是零条件转移指令,即,遇到栈顶数据是零,关系式不成立,就跳过由Tstatement翻译的指令程序,转向执行标号所的指令。反之关系式成立果1不向命令标号L2按次序执行由()翻译得到的指令程序。JmpL1”是无条件转向执行L1的令,开始第2次环。这与while语的语义分析是完全一致的。语句的翻译处理下式表示call语的译处理规则:T(″call″ident=,lev-levelcall语句的翻译得到一条过程调用指令cal,,”。其中lev是call语所在程序的静态级别level是程名ident被说明时的静态级别,两者之差lev-level”作为base函的实参用来计算出被调用过程在数据栈对应的过程段的态链接地址SL,以保证变量的正确存取是调用过程的起始地址(5)

if句的翻译处理下式表示if句的翻译处理规则:T(″condition″then″statement)=T(condition)JpcL1Tstatement)L1„其中()成对关系式的译,会得到相应的一串代码指令,执行这一串代码指令得到的关系式计算结果最终会存放在栈顶关系式成立计算结果为1若第15页

:编译原理课程设计报告:关系式不成立,结果为。“JpcL1”是零条件转移指令,即,遇到栈数据是零,也就是说关系式不成立跳过由(翻的指令程序向行号L1所在的指。反之,若关系式成立,结果为1,则不转向命令标号L1,仍按次序执行由T()翻译得到的指令程序。If语句还有另一种形式即带有else语句T“if”condition“thenstatement1“else=T(Gen(JpcL1)T()Gen(jmpL2)L1T()L2即在执行完statement1之后cx代码指针能够跳过执行L2(6)read语句与write语句Read(id,{id})=gen(RED,adr)„„Write(exp,{exp})=gen(WRT,adr)„„()目代的行函数名

功能interpretbase

对目标代码的解释执行程序通过静态链求出动态运行栈中的基址,返回值即该基址第16页

解释执行的流程图

编译原理课程设计报告Interpret3个存赋值主序L,DL,赋值执指

主程序的RA主程序看成0分程序相返Y返

N

回调用主程序的断点,即执行结束。()出处能够处理的错误类型:词错误*parsing_ERROR(-1);/*除数为0*/parsing_ERROR(0);/*丢一个;*/parsing_ERROR(1);/*这应该为主程序*parsing_ERROR(2);/*整不能用作标识*parsing_ERROR(3);/*关字不能用作标识*parsing_ERROR(4);/*标符错误这里必须是一个标识*parsing_ERROR(5);/*缺;'*/parsing_ERROR(6);/*缺,'*/parsing_ERROR(7);/*多;'*/parsing_ERROR(8);/*函与函数之间缺';'*/parsing_ERROR(11);/*该标识符没有说明*该识符不是变量*赋号错误*第17页

编译原理课程设计报告该程未定*调(call)个常数或变量是不允许*“”后必须跟一个标识*缺then*/parsing_ERROR(18);/*缺少end*/丢左括号*丢右括号*语里不正确的符*该件判断语句开始符号不正*表式不能以此符号开*parsing_ERROR(26);/*block程语句定义部分不能以此符号开始*常定义后有非法符*变定义后有非法符*程结尾处有多余符*该程使用了比它层次低的过程里面的变*程序中并未设置单独的函数来用作出错后的错误处理在种出错的地方加上出错恢复处理。注:其中-1号错误只能在目标代执行的时候检查出来。三.函数说明/*词法分析部分函数*/int/*取原程序中下一个字符过程*/int/*略过原程序的空格,换行符*/Concat();/*将当前读到字符接至strToken*/int/*文件指针后退一个*Retract();/*查找关键字表*法错误处理*int*string);/*字符串转为整形*intGetSym();/*件结束返回-1,读成功回失败返回0*//*语法分析部分函数*//*语法分析主函数*/parsing_block(intparsing_statement();parsing_condition();parsing_exp();第18页

编译原理课程设计报告parsing_ter

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论