《编译原理》实验指导书 2.pdf

上传人:C****o 文档编号:40153668 上传时间:2022-09-08 格式:PDF 页数:37 大小:252.31KB
返回 下载 相关 举报
《编译原理》实验指导书 2.pdf_第1页
第1页 / 共37页
《编译原理》实验指导书 2.pdf_第2页
第2页 / 共37页
点击查看更多>>
资源描述

《《编译原理》实验指导书 2.pdf》由会员分享,可在线阅读,更多相关《《编译原理》实验指导书 2.pdf(37页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、编 译 原 理实验指导书上海大学计算机学院编译原理课程组2010 年 10 月名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组1 of 37目录一、课程简介.2二、实验目的.2三、实验环境.2四、实验任务.2五、PL0 语言简介 .21PL/0 语言文法的EBNF.32PL/0 语言的词汇表.4六、实验项目.5实验一.词法分析 .5实验二.语法分析 .8实验三.词法、语法分析.10实验四.语义分析 .11实验五.中间代码生成 .12七、考核方式.13八、参考文献.14九、附录 PL0 语言编译源程序清单 .15名师资料

2、总结-精品资料欢迎下载-名师精心整理-第 2 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组2 of 37编译原理实验指导一、课程简介1.课程名称:编译原理(Principle of Compiler)2.课程编码:083050133.课程总学时:60学时 理论:40 学时;实验:20 学时4.课程总学分:5 学分二、实验目的编译原理是计算机类专业特别是计算机软件专业的一门重要专业课。设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现技术,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序

3、等方面的初步能力。编译原理是一门理论性和实践性都比较强的课程。进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。同时培养学生实际动手能力。三、实验环境微机 CPUP4以上,256M 以上内存,安装好C语言,或 C+,或 Visual C+开发环境。四、实验任务用 C/C+/Visual C+语言编写 PL0语言的词法分析程序、语法分析程序、语义分析程序、中间代码生成程序。五、PL0 语言简介PL0语言功能简单、结构清晰、可读性强,而又具备了一般高级程序设计语言的必须部分,因而 PL0语言的编译程序能充分体现一个高级语言编译程序实现名师资料总结-精品资料欢迎下载-名师精心整

4、理-第 3 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组3 of 37的基本方法和技术。1PL/0 语言文法的EBNF:=.:=:=CONST,;:=:=:=VAR,;:=|:=;:=PROCEDURE;:=|:=:=:=BEGIN ;END :=|ODD :=+|-:=:=|():=+|-:=*|/:=|#|=名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组4 of 37:=IF THEN :=CALL 标识符:=WHILE DO :=READ(,):=WRITE(,):=a|b|X|Y|Z

5、:=0|1|8|92PL/0 语言的词汇表序号类别单词编码1 基本字begin,call,const,do,end if,odd,procedure,read then,var,while,write beginsym,callsym,constsym dosym,endsym,ifsym,oddsym proceduresym,readsym,thensym varsym,whilesym,writesym 2 标识符ident 3 常数number 4 运算符+,-,*,/,odd=,=,:=plus,minus,times,slash,oddsym eql,neq,lss,leq,gtr

6、,geq,becomes 5 界符(),;.Lparen,rparen,comma,semicolon period 名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组5 of 37六、实验项目实验一.词法分析1.实验目的根据 PL/0 语言的文法规范,编写PL/0 语言的词法分析程序。通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的法。掌握词法分析的实现方法。上机调试编出的词法分析程序。2.实验

7、准备微机 CPU P4以上,256M 以上内存,安装好 C语言,或 C+,或 Visual C+.3.实验时间4 学时4.实验内容已给 PL/0 语言文法,输出单词符号(关键字、专用符号以及其它标记)。5.实验要求确定编译中使用的表格、标识符与关键字的区分方法等。把词法分析器设计成一个独立一遍的过程。词法分析器的输出形式采用二元式序列,即:(单词种类,单词的值)6.输入输出输入:PL/0 源程序。例:const a=10;名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组6 of 37var b,c;begin read

8、(b);c:=a+b;write(c)end.输出:(constsym,const)(ident ,a)(eql ,=)(number,10)(semicolon,;)(varsym,var)(ident,b)(comma,)(ident,c)(semicolon,;)(beginsym,begin)(readsym,read)(lparen,()(ident,b)(rparen,)(semicolon,;)(ident,c)(becomes,:=)(ident,a)(plus,+)(ident,b)(semicolon,;)(writesym,write)名师资料总结-精品资料欢迎下载-名师

9、精心整理-第 7 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组7 of 37(lparen,()(ident,c)(rparen,)(endsym,end)(period,.)名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组8 of 37实验二.语法分析1.实验目的给出 PL/0 文法规范,要求编写PL/0 语言的语法分析程序。通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。选择最有代表性的语法分析方法,如递归

10、子程序法;选择对各种常见程序语言都具备的语法结构,如赋值语句,特别是表达式,作为分析对象。2.实验准备微机 CPU P4以上,256M 以上内存,安装好 C语言,或 C+,或 Visual C+.3.实验时间4 学时4.实验内容已给 PL/0 语言文法,构造表达式部分的语法分析器。分析对象算术表达式的BNF定义如下::=+|-:=:=|():=+|-:=*|/:=|#|=5.实验要求名师资料总结-精品资料欢迎下载-名师精心整理-第 9 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组9 of 37将实验一“词法分析”的输出结果,作为表达式语法分析器的输入,进 行语 法解

11、析,对 于 语法 正 确 的 表达 式,报告“语 法正 确”;对于语法错误的表达式,报告“语法错误”,指出错误原因。把语法分析器设计成一个独立一遍的过程。语法分析器的编写方法采用递归子程序法。6.输入输出输入:PL/0 表达式,用实验一的输出形式作为输入。例如:对于 PL/0 表达式,(a+15)*b 用下列形式作为输入:(lparen,()(ident,a)(plus,+)(number,15)(rparen,)(times,*)(ident,b)输出:对于语法正确的表达式,报告“语法正确”;对于语法错误的表达式,报告“语法错误”,指出错误原因。有余力的同学,可适当扩大分析对象。譬如:算术表

12、达式中变量名可以是一般标识符,还可含一般常数、数组元素、函数调用等等。除算术表达式外,还可扩充分析布尔、字符、位等不同类型的各种表达式。加强语法检查,尽量多和确切地指出各种错误。名师资料总结-精品资料欢迎下载-名师精心整理-第 10 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组10 of 37实验三.词法、语法分析1.实验目的给出 PL/0 文法规范,要求结合编写PL/0 语言的词法、语法分析程序。2.实验准备微机 CPU P4以上,256M 以上内存,安装好 C语言,或 C+,或 Visual C+.3.实验时间4 学时4.实验内容已给 PL/0 语言文法,构造表达

13、式部分的词法和语法分析器。5.实验要求将实验一“词法分析器”与实验二“语法分析器”之间的衔接方式由独立一遍改为独立子程序。语法分析器的编写方法采用递归子程序法。6.输入输出输入:PL/0 表达式源语言,例如:(a+15)*b 作为输入。输出:对于语法正确的表达式,报告“语法正确”;对于语法错误的表达式,报告“语法错误”,指出错误原因。名师资料总结-精品资料欢迎下载-名师精心整理-第 11 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组11 of 37实验四.语义分析1.实验目的通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的

14、语义翻译方法。掌握目前普遍采用的语义分析方法语法制导翻译技术。给出 PL/0 文法规范,要求在语法分析程序中添加语义处理,对于语法正确的算术表达式,输出其计算值。2.实验准备微机 CPU P4以上,256M 以上内存,安装好 C语言,或 C+,或 Visual C+.3.实验时间4 学时4.实验内容已给 PL/0 语言文法,在表达式的语法分析程序里,添加语义处理部分。5.实验要求语义分析对象重点考虑经过语法分析后已是正确的语法范畴,实习重点是语义子程序。在实验三“语法分析器”的里面添加PL/0 语言“表达式”部分的语义处理。计算表达式的语义值。6.输入输出输入:PL/0 算术表达式,例如:2+

15、3*5作为输入。输出:17名师资料总结-精品资料欢迎下载-名师精心整理-第 12 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组12 of 37实验五.中间代码生成1.实验目的给出 PL/0 文法规范,要求在语法分析程序中添加语义处理,对于语法正确的表达式,输出其中间代码。2.实验准备微机 CPU P4以上,256M 以上内存,安装好 C语言,或 C+,或 Visual C+.3.实验时间4 学时4.实验内容已给 PL/0 语言文法,在实验三的表达式语法分析程序里,添加语义处理部分输出表达式的中间代码,用四元式序列表示。5.实验要求在实验三“语法分析器”的里面添加PL/

16、0 语言“表达式”部分的语义处理,输出表达式的中间代码。中间代码用四元式序列表示。6.输入输出输入:PL/0 表达式,例如:a*(b+c)。输出:(+b c t1)(*a t1 t2)名师资料总结-精品资料欢迎下载-名师精心整理-第 13 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组13 of 37七、考核方式1.实验报告实验采用分组的形式,每个实习小组交一份实验报告,应包括 以下内容:题目设计思想算法调试数据(输入/输出)2.评分标准由指导教师根据实验验收情况并结合实验报告质量及学习态度等采用 5 级记分制评分。实验成绩占期终综合测评成绩的30%.名师资料总结-精品

17、资料欢迎下载-名师精心整理-第 14 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组14 of 37八、参考文献1 编译原理(第二版),张素琴、吕映芝、蒋维杜,清华大学出版社,2005年出版。2 编译程序设计原理,杜书敏、王永宁,北京大学出版社,1988 年出版。3 计算机编译原理,张幸儿,科学出版社,1999 年出版。4 编译程序原理与技术,李赣生等,清华大学出版社,1997 年 10 月出版。名师资料总结-精品资料欢迎下载-名师精心整理-第 15 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组15 of 37九、附录 PL0 语言编译源程序清

18、单(部分)源代码pl0c.h/*关键字个数 */#define norw 13/*名字表容量 */#define txmax 100/*所有的 add1用于定义数组 */#define txmaxadd1 101/*number 的最大位数 */#define nmax 14/*符号的最大长度*/#define al 10/*地址上界 */#define amax 2047/*最大允许过程嵌套声明层数*/#define levmax 3/*最多的虚拟机代码数*/#define cxmax 200#define cxmaxadd1 201/*当函数中会发生fatal error时,返回-1告知调

19、用它的函数,最终退出程序*/#define getsymdo if(-1=getsym()return -1#define getchdo if(-1=getch()return -1#define testdo(a,b,c)if(-1=test(a,b,c)return -1#define gendo(a,b,c)if(-1=gen(a,b,c)return -1#define expressiondo(a,b,c)if(-1=expression(a,b,c)return -1#define factordo(a,b,c)if(-1=factor(a,b,c)return -1#defin

20、e termdo(a,b,c)if(-1=term(a,b,c)return -1#define conditiondo(a,b,c)if(-1=condition(a,b,c)return -1#define statementdo(a,b,c)if(-1=statement(a,b,c)return -1#define constdeclarationdo(a,b,c)if(-1=constdeclaration(a,b,c)return -1#define vardeclarationdo(a,b,c)if(-1=vardeclaration(a,b,c)return -1 typede

21、fenum false,true bool;/*符号 */enum symbol nul,ident,number,plus,minus,times,slash,oddsym,eql,neq,lss,leq,gtr,geq,lparen,rparen,comma,semicolon,period,becomes,beginsym,endsym,ifsym,thensym,whilesym,writesym,readsym,dosym,callsym,constsym,varsym,procsym;#define symnum 32/*名字表中的类型*/enum object constant,

22、variable,procedur;名师资料总结-精品资料欢迎下载-名师精心整理-第 16 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组16 of 37/*虚拟机代码 */enum fct lit,opr,lod,sto,cal,inte,jmp,jpc;#define fctnum 8/*虚拟机代码结构*/struct instruction enum fct f;/*虚拟机代码指令 */int l;/*引用层与声明层的层次差*/int a;/*根据 f 的不同而不同 */;FILE*fas;/*输出名字表 */FILE*fa;/*输出虚拟机代码 */FILE*fa

23、1;/*输出源文件及其各行对应的首地址*/FILE*fa2;/*输出结果 */bool listswitch;/*显示虚拟机代码与否*/bool tableswitch;/*显示名字表与否 */char ch;/*获取字符的缓冲区,getch 使用 */enum symbol sym;/*当前的符号 */char idal;/*当前 ident*/int num;/*当前 number*/int cc,ll,kk;/*getch使用的计数器,cc表示当前字符(ch)的位置 */int cx;/*虚拟机代码指针*/char line81;/*读取行缓冲区 */char aal;/*临时符号 */

24、struct instruction codecxmaxadd1;/*存放虚拟机代码的数组*/char wordnorwal;/*保留字 */enum symbol wsymnorw;/*保留字对应的符号值*/enum symbol ssym256;/*单字符的符号值*/char mnemonicfctnum5;/*虚拟机代码指令名称*/bool declbegsyssymnum;/*表示声明开始的符号集合*/bool statbegsyssymnum;/*表示语句开始的符号集合*/bool facbegsyssymnum;/*表示因子开始的符号集合*/*名字表结构 */struct tabl

25、estruct char nameal;/*名字 */enum object kind;/*类型:const,var or procedure*/int val;/*数值,仅 const 使用 */int level;/*所处层,仅 const 不使用 */int adr;/*地址,仅 const 不使用 */int size;/*需要分配的数据区空间,仅procedure 使用 */;struct tablestruct tabletxmaxadd1;/*名字表 */名师资料总结-精品资料欢迎下载-名师精心整理-第 17 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组

26、17 of 37FILE*fin;FILE*fout;char fnameal;int err;/*错误计数器 */void error(int n);int getsym();int getch();void init();int gen(enum fct x,int y,int z);int test(bool*s1,bool*s2,int n);int inset(int e,bool*s);int addset(bool*sr,bool*s1,bool*s2,int n);int subset(bool*sr,bool*s1,bool*s2,int n);int mulset(bool

27、*sr,bool*s1,bool*s2,int n);int block(int lev,int tx,bool*fsys);void interpret();int factor(bool*fsys,int*ptx,int lev);int term(bool*fsys,int*ptx,int lev);int condition(bool*fsys,int*ptx,int lev);int expression(bool*fsys,int*ptx,int lev);int statement(bool*fsys,int*ptx,int lev);void listcode(int cx0)

28、;int vardeclaration(int*ptx,int lev,int*pdx);int constdeclaration(int*ptx,int lev,int*pdx);int postion(char*idt,int tx);void enter(enum object k,int*ptx,int lev,int*pdx);int base(int l,int*s,int b);pl0c.c/*Windows 下c语言 PL/0编译程序在Visual C+6.0和Visual C.NET 上运行通过使用方法:运行后输入 PL/0源程序文件名回答是否输出虚拟机代码回答是否输出名字表

29、fa.tmp 输出虚拟机代码fa1.tmp 输出源文件及其各行对应的首地址fa2.tmp 输出结果fas.tmp 输出名字表*/#include#include pl0c.h#include string.h/*解释执行时使用的栈*/名师资料总结-精品资料欢迎下载-名师精心整理-第 18 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组18 of 37#define stacksize 500 int main()bool nxtlevsymnum;init();/*初始化 */fas=fopen(fas.tmp,w);fa1=fopen(fa1.tmp,w);print

30、f(Input file?);fprintf(fa1,Input file?);scanf(%s,fname);/*输入文件名 */fin=fopen(fname,r);if(fin)fprintf(fa1,%sn,fname);printf(List object code?(Y/N);/*是否输出虚拟机代码*/scanf(%s,fname);listswitch=(fname0=y|fname0=Y);printf(List symbol table?(Y/N);/*是否输出名字表*/scanf(%s,fname);tableswitch=(fname0=y|fname0=Y);err=0

31、;cc=cx=ll=0;ch=;kk=al-1;if(-1!=getsym()fa=fopen(fa.tmp,w);fa2=fopen(fa2.tmp,w);addset(nxtlev,declbegsys,statbegsys,symnum);nxtlevperiod=true;if(-1=block(0,0,nxtlev)/*调用编译程序 */fclose(fa);fclose(fa1);fclose(fin);printf(n);return 0;fclose(fa);fclose(fa1);if(sym!=period)error(9);if(err=0)interpret();/*调

32、用解释执行程序*/else 名师资料总结-精品资料欢迎下载-名师精心整理-第 19 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组19 of 37 printf(Errors in pl/0 program);fclose(fin);else printf(Cant open file!n);fprintf(fa1,Cant open file!n);fclose(fa1);fclose(fas);printf(n);return 0;/*在适当的位置显示错误*/void error(int n)char space81;memset(space,32,81);spac

33、ecc-1=0;/*出错时当前符号已经读完,所以cc-1*/printf(*%s!%dn,space,n);fprintf(fa1,*%s!%dn,space,n);err+;/*词法分析,获取一个符号*/int getsym()int i,j,k;while(ch=|ch=10|ch=9)/*忽略空格、换行和TAB*/getchdo;if(ch=a&ch=z)/*名字或保留字以a.z 开头 */k=0;do if(k=a&ch=0&ch=9);ak=0;strcpy(id,a);i=0;j=norw-1;do/*搜索当前符号是否为保留字*/k=(i+j)/2;if(strcmp(id,wor

34、dk)=0)i=k+1;while(ij)sym=wsymk;else sym=ident;/*搜索失败则,是名字或数字*/else if(ch=0&ch=0&chnmax)error(30);else if(ch=:)/*检测赋值符号 */getchdo;if(ch=)sym=becomes;getchdo;名师资料总结-精品资料欢迎下载-名师精心整理-第 21 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组21 of 37 else sym=nul;/*不能识别的符号 */else if(ch=)/*检测大于或大于等于符号*/getchdo;if(ch=)sym=g

35、eq;getchdo;else sym=gtr;else sym=ssymch;/*当符号不满足上述条件时,全部按照单字符符号处理 */getchdo;名师资料总结-精品资料欢迎下载-名师精心整理-第 22 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组22 of 37 return 0;/*编译程序主体 */int block(int lev,/*当前分程序所在层*/int tx,/*名字表当前尾指针*/bool*fsys/*当前模块后跟符号集合*/)int i;int dx;/*名字分配到的相对地址*/int tx0;/*保留初始 tx*/int cx0;/*保留初

36、始 cx*/bool nxtlevsymnum;/*在下级函数的参数中,符号集合均为值参,但由于使用数租实现,传递进来的是指针,为防止下级函数改变上级函数的集合,开辟新的空间传递给下级函数,之后所有的nxtlev 都是这样 */dx=3;tx0=tx;/*记录本层名字的初始位置*/tabletx.adr=cx;gendo(jmp,0,0);if(levlevmax)error(32);do if(sym=constsym)/*收到常量声明符号,开始处理常量声明*/getsymdo;do constdeclarationdo(&tx,lev,&dx);/*dx 的值会被 constdeclara

37、tion改变,使用指针*/while(sym=comma)getsymdo;constdeclarationdo(&tx,lev,&dx);if(sym=semicolon)getsymdo;else error(5);while(sym=ident);名师资料总结-精品资料欢迎下载-名师精心整理-第 23 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组23 of 37 if(sym=varsym)/*收到变量声明符号,开始处理变量声明*/getsymdo;do vardeclarationdo(&tx,lev,&dx);while(sym=comma)getsymdo

38、;vardeclarationdo(&tx,lev,&dx);if(sym=semicolon)getsymdo;else error(5);while(sym=ident);while(sym=procsym)/*收到过程声明符号,开始处理过程声明*/getsymdo;if(sym=ident)enter(procedur,&tx,lev,&dx);/*记录过程名字 */getsymdo;else error(4);/*procedure后应为标识符 */if(sym=semicolon)getsymdo;else error(5);/*漏掉了分号 */memcpy(nxtlev,fsys,

39、sizeof(bool)*symnum);nxtlevsemicolon=true;if(-1=block(lev+1,tx,nxtlev)return -1;/*递归调用 */if(sym=semicolon)getsymdo;memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);nxtlevident=true;nxtlevprocsym=true;testdo(nxtlev,fsys,6);名师资料总结-精品资料欢迎下载-名师精心整理-第 24 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组24 of 37 else erro

40、r(5);/*漏掉了分号 */memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);nxtlevident=true;testdo(nxtlev,declbegsys,7);while(inset(sym,declbegsys);/*直到没有声明符号*/codetabletx0.adr.a=cx;/*开始生成当前过程代码*/tabletx0.adr=cx;/*当前过程代码地址*/tabletx0.size=dx;/*声明部分中每增加一条声明都会给dx增加 1,声明部分已经结束,dx就是当前过程数据的size*/cx0=cx;gendo(inte,0,dx)

41、;/*生成分配内存代码*/*语句后跟符号为分号或end*/memcpy(nxtlev,fsys,sizeof(bool)*symnum);/*每个后跟符号集和都包含上层后跟符号集和,以便补救 */nxtlevsemicolon=true;nxtlevendsym=true;statementdo(nxtlev,&tx,lev);gendo(opr,0,0);/*每个过程出口都要使用的释放数据段指令*/memset(nxtlev,0,sizeof(bool)*symnum);/*分程序没有补救集合*/testdo(fsys,nxtlev,8);/*检测后跟符号正确性*/listcode(cx0)

42、;/*输出代码 */return 0;/*初始化 */void init()int i;/*设置单字符符号*/for(i=0;iamax)error(31);/*数值越界 */num=0;table(*ptx).val=num;break;名师资料总结-精品资料欢迎下载-名师精心整理-第 27 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组27 of 37case variable:/*变量名字 */table(*ptx).level=lev;table(*ptx).adr=(*pdx);(*pdx)+;break;case procedur:/*过程名字*/table

43、(*ptx).level=lev;break;/*查找名字的位置*/*找到则返回在名字表中的位置,否则返回0*/int postion(char*idt,/*要查找的名字 */int tx/*当前名字表尾指针*/)int i;strcpy(table0.name,idt);i=tx;while(strcmp(tablei.name,idt)!=0)i-;return i;/*常量声明处理 */int constdeclaration(int*ptx,int lev,int*pdx)if(sym=ident)getsymdo;if(sym=eql|sym=becomes)if(sym=becom

44、es)error(1);/*把=写成了:=*/getsymdo;if(sym=number)enter(constant,ptx,lev,pdx);getsymdo;else error(2);/*常量说明=后应是数字 */else error(3);/*常量说明标识后应是=*/名师资料总结-精品资料欢迎下载-名师精心整理-第 28 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组28 of 37else error(4);/*const后应是标识 */return 0;/*变量声明处理 */int vardeclaration(int*ptx,int lev,int*p

45、dx)if(sym=ident)enter(variable,ptx,lev,pdx);/*填写名字表 */getsymdo;else error(4);/*var后应是标识 */return 0;/*语句处理 */int statement(bool*fsys,int*ptx,int lev)/*参数意义见 block 和enter 函数 */int i,cx1,cx2;bool nxtlevsymnum;/*意义见 block 函数 */if(sym=ident)/*准备按照赋值语句处理*/i=postion(id,*ptx);if(i=0)error(11);/*变量未找到 */else

46、 if(tablei.kind!=variable)error(12);/*赋值语句格式错误*/i=0;getsymdo;if(sym=becomes)getsymdo;else error(13);/*检测赋值符号 */memcpy(nxtlev,fsys,sizeof(bool)*symnum);expressiondo(nxtlev,ptx,lev);/*处理赋值符号右侧表达式*/if(i!=0)gendo(sto,lev-tablei.level,tablei.adr);/*expression将执行一系列指令,但最终结果将会保存在栈顶,执行sto 命令完成赋值 */名师资料总结-精品

47、资料欢迎下载-名师精心整理-第 29 页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组29 of 37 else if(sym=readsym)/*准备按照 read 语句处理 */getsymdo;if(sym!=lparen)error(34);/*格式错误,应是左括号*/else do getsymdo;if(sym=ident)i=postion(id,*ptx);/*查找要读的变量*/else i=0;if(i=0)error(35);/*read()中应是声明过的变量名*/else gendo(opr,0,16);/*生成输入指令,读取值到栈顶*/gendo(

48、sto,lev-tablei.level,tablei.adr);/*储存到变量 */getsymdo;while(sym=comma);/*一条 read 语句可读多个变量*/if(sym!=rparen)error(33);/*格式错误,应是右括号*/while(!inset(sym,fsys)/*出错补救,直到收到上层函数的后跟符号*/getsymdo;else getsymdo;else if(sym=writesym)/*准备按照 write 语句处理,与 read 类似 */getsymdo;if(sym=lparen)do 名师资料总结-精品资料欢迎下载-名师精心整理-第 30

49、页,共 37 页 -编译原理实验指导书上海大学计算机学院编译原理课程组30 of 37getsymdo;memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlevrparen=true;nxtlevcomma=true;/*write的后跟符号为)or,*/expressiondo(nxtlev,ptx,lev);/*调用表达式处理,此处与read 不同,read 为给变量赋值 */gendo(opr,0,14);/*生成输出指令,输出栈顶的值*/while(sym=comma);if(sym!=rparen)error(33);/*write()中应为完整表

50、达式*/else getsymdo;gendo(opr,0,15);/*输出换行 */else if(sym=callsym)/*准备按照 call 语句处理 */getsymdo;if(sym!=ident)error(14);/*call后应为标识符 */else i=postion(id,*ptx);if(i=0)error(11);/*过程未找到 */else if(tablei.kind=procedur)gendo(cal,lev-tablei.level,tablei.adr);/*生成call 指令 */else error(15);/*call后标识符应为过程*/getsym

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com