《编译原理》实验指导书2016_第1页
《编译原理》实验指导书2016_第2页
《编译原理》实验指导书2016_第3页
《编译原理》实验指导书2016_第4页
《编译原理》实验指导书2016_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

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

文档简介

1、编译原理实验指导书编 译 原 理实验与课程设计指导书2016年10月目录一、课程简介2二、实验目的2三、实验环境2四、实验任务2五、实验项目3实验一. 词法分析3实验二. 自顶向下语法分析8实验三. 自底向上语法分析10实验四. 语义分析11实验五. 中间代码生成12六、课程设计13七、考核方式13八、参考文献14九、附录PL0语言编译源程序清单(部分)15编译原理实验与课程设计指导一、课程简介1. 课程名称:编译原理(Principle of Compiler)2. 课程总学时: 64 学时理论: 48 学时;实验: 16 学时3. 课程总学分: 4 学分二、实验目的编译原理是计算机类专业特

2、别是计算机软件专业的一门重要专业课。设置该课程的目的在于系统地向学生讲述编译系统的结构、工作流程及编译程序各组成部分的设计原理和实现技术,使学生通过学习既掌握编译理论和方法方面的基本知识,也具有设计、实现、分析和维护编译程序等方面的初步能力。编译原理是一门理论性和实践性都比较强的课程。进行上机实验的目的是使学生通过完成上机实验题目加深对课堂教学内容的理解。同时培养学生实际动手能力。三、实验环境微机CPU P4以上,256M以上内存,安装好C语言,或C+,或Visual C+开发环境。四、实验任务用C/C+/Visual C+语言编写某语言的词法分析程序、语法分析程序、语义分析程序、中间代码生成

3、程序。五、实验项目实验一. 词法分析1. 实验目的l 根据PL/0语言的文法规范,编写PL/0语言的词法分析程序。l 通过设计调试词法分析程序,实现从源程序中分出各种单词的方法;加深对课堂教学的理解;提高词法分析方法的实践能力。l 掌握从源程序文件中读取有效字符的方法和产生源程序的内部表示文件的法。 l 掌握词法分析的实现方法。 l 上机调试编出的词法分析程序。2. 实验准备微机CPU P4以上,256M以上内存,安装好C语言,或C+,或Visual C+.3. 实验时间4学时4. 实验内容(1) 试用手工编码方式构造识别以下给定单词的某一语言的词法分析程序。(2) 语言中具有的单词包括五个有

4、代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。参考实现方法简述如下。(3) 单词的分类:构造上述语言中的各类单词符号及其分类码表。表1 语言中的各类单词符号及其分类码表单词符号类别编码类别码的助记符单词值begin1BEGINend2ENDif3IFthen4THENelse5ELSE标识符6ID字母打头的字母数字串整常数7INT数字串<8LT<=9LE=10EQ<>11NE>12GT>=13GE:=14IS+15PL-16MI*17MU/18DI5、 实验方法与处理过程在一个程序设

5、计语言中,一般都含有若干类单词符号,为此可首先为每类单词建立一张状态转换图,然后将这些状态转换图合并成一张统一的状态图,即得到了一个有限自动机,再进行必要的确定化和状态数最小化处理,最后据此构造词法分析程序。在此为了使词法分析程序结构比较清晰,且尽量避免某些枝节问题的纠缠,假定要编译的语言中,全部关键字都是保留字,程序员不得将它们作为源程序中的标识符;在源程序的输入文本中,关键字、标识符、整常数之间,若未出现关系和算术运算符以及赋值符,则至少须用一个空白字符加以分隔。作了这些限制以后,就可以把关键字和标识符的识别统一进行处理。即每当开始识别一个单词时,若扫视到的第一个字符为字母,则把后续输入的

6、字母或数字字符依次进行拼接,直至扫视到非字母、数字字符为止,以期获得一个尽可能长的字母数字字符串,然后以此字符串查所谓保留字表(此保留字表已事先造好),若查到此字符串,则取出相应的类别码;反之,则表明该字符串应为一标识符。采用上述策略后,针对表I中部分单词可以构造一个如图1所示的有限自动机(以状态转换图表示)。在图1中添加了当进行状态转移时,词法分析程序应执行的语义动作。根据图1,可用C语言编写出符合以上几项要求的一个相应的扫描器程序,如程序一所示。图1 识别表I所列语言中的部分单词的DFA及相关的语义过程图1及程序一中所出现的语义变量及语义函数的含义和功能说明如下。函数GETCHAR:每调用

7、一次,就把扫描指示器当前所指示的源程序字符送入字符变量ch,然后把扫描指示器前推一个字符位置。字符数组TOKEN:用来依次存放一个单词词文中的各个字符。函数CAT:每调用一次,就把当前ch中的字符拼接于TOKEN中所存字符串的右边。函数LOOKUP:每调用一次,就以TOKEN中的字符串查保留字表,若查到,就将相应关键字的类别码赋给整型变量c;否则将c置为零。函数RETRACT:每调用一次,就把扫描指示器回退一个字符位置(即退回多读的那个字符)。函数OUT:一般仅在进入终态时调用此函数,调用的形式为OUT(c,VAL)。其中,实参c为相应单词的类别码或其助记符;当所识别的单词为标识符和整数时,实

8、参VAL为TOKEN(即词文分别为字母数字串和数字串),对于其余种类的单词,VAL均为空串。函数OUT的功能是,在送出一个单词的内部表示之后,返回到调用该词法分析程序的那个程序。程序一 根据图1编写的扫描器# include <stdio.h># include <ctype.h># include <string.h># define ID 6# define INT 7# define LT 8# define LE 9# define EQ 10# define NE 11# define GT 12# define GE 13char TOKEN20

9、;extern int lookup (char*);extern void out (int, char*);extern report_error (void);void scanner_example (FILE *fp)char ch; int i, c;ch=fgetc (fp);if (isalpha (ch) /*it must be a identifer!*/TOKEN0=ch; ch=fgetc (fp); i=1;while (isalnum (ch)TOKENi=ch; i+;ch=fgetc (fp);TOKENi= 0fseek(fp,-1,1); /* retra

10、ct*/c=lookup (TOKEN);if (c=0) out (ID,TOKEN); else out (c," ");elseif(isdigit(ch)TOKEN0=ch; ch=fgetc(fp); i=1;while(isdigit(ch)TOKENi=ch; i+;ch=fgetc(fp);TOKENi= 0;fseek(fp,-1,1);out(INT,TOKEN);elseswitch(ch)case : ch=fgetc(fp);if(ch=)out(LE," ");else if(ch=) out (NE," "

11、;);elsefseek (fp,-1,1);out (LT," ");break;case =: out(EQ, " "); break;case : ch=fgetc(fp);if(ch=)out(GE," ");elsefseek(fp,-1,1);out(GT," ");break;default: report_error( ); break;return;提示:扫描器所用的若干函数以及主程序有待于具体编写,并需事先建立好保留字表,以备查询。另外,在扫描源程序字符串时,一旦识别出关键字、标识符、整常数以及

12、运算符中之一,即以二元式形式(类别编码,值)输出单词。每次调用词法分析程序,它均能自动继续扫描下去,形成下一个单词,直至整个源程序全部扫描完毕,并形成相应的单词串形式的源程序。6、 输出结果:以文件形式输入的例子至少应包含两行以上的源代码,并以对照的形式将扫描器的分析结果输出,必要时给出正误信息。例:以下例题说明运行时的输入输出效果:输入:const a=10;var b,c;beginread(b);c:=a+b;write(c)end.输出:(constsym ,const )(ident , a)(eql , =)(number, 10)(semicolon , ;)(varsym ,

13、var )(ident, b)(comma, , )(ident, c )(semicolon , ;)(begins ym,begin)(readsym, read )(lparen , ( )(ident, b)(rparen , ) )(semicolon , ;)(ident, c )(becomes , := )(ident, a )(plus , + )(ident, b )(semicolon , ;)(writesym ,write )(lparen , ( )(ident, c )(rparen , ) )(endsym , end )实验二. 自顶向下语法分析1. 实验目的

14、(1)通过设计、编制、调试一个典型的语法分析程序,实现对词法分析程序所提供的单词序列进行语法检查和结构分析,进一步掌握常用的语法分析方法。(2)选择最有代表性的语法分析方法递归子程序法;选择对各种常见程序语言都具备的语法结构,如赋值语句,特别是表达式,作为分析对象。2. 实验准备微机CPU P4以上,256M以上内存,安装好C语言,或C+,或Visual C+.3. 实验时间4学时4. 实验内容l 构造递归下降LL(1)语法分析器。完成P87,例4.125. 实验要求l 语法分析器的编写方法采用递归子程序法。扩充完整例4.12的程序部分。l 输入文法的句子,作为表达式语法分析器的输入,进行语法

15、解析,对于语法正确的表达式,报告“语法正确”;l 对于语法错误的表达式,报告“语法错误”, 指出错误原因。l 把语法分析器设计成一个独立一遍的过程。6. 输入输出输入:至少找到2个句子,其中一个是文法的句子,另一个不是,分别输入。输出:对于语法正确的表达式,报告“语法正确”;对于语法错误的表达式,报告“语法错误”, 指出错误原因。实验三. 自底向上语法分析1. 实验目的给出算符优先关系表的构造方法,将FIRSTVT集合和LASTVT集合的算法扩充成程序。2. 实验准备微机CPU P4以上,256M以上内存,安装好C语言,或C+,或Visual C+.3. 实验时间4学时4. 实验内容构造求FI

16、RSTVT集合和LASTVT集合的程序。5. 实验要求l 扩充P113求FIRSTVT集合的算法。l 完成LASTVT集合的算法。6. 输入输出输入:文法。输出:FIRSTVT集合和LASTVT集合。实验四. 语义分析1. 实验目的l 通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译方法。l 掌握目前普遍采用的语义分析方法语法制导翻译技术。l 要求在语法分析程序中添加语义处理,对于语法正确的算术表达式,输出其计算值。2. 实验准备微机CPU P4以上,256M以上内存,安装好C语言,或C+,或Visual C+.3. 实验时间4学时4. 实

17、验内容在表达式的语法分析程序里,添加语义处理部分。5. 实验要求l 语义分析对象重点考虑经过语法分析后已是正确的语法范畴,实习重点是语义子程序。l 在实验三“语法分析器”的里面添加PL/0语言“表达式”部分的语义处理。l 计算表达式的语义值。6. 输入输出输入:算术表达式,例如: 2 + 3 * 5作为输入。输出:17实验五. 中间代码生成1. 实验目的要求在语法分析程序中添加语义处理,对于语法正确的表达式,输出其中间代码。2. 实验准备微机CPU P4以上,256M以上内存,安装好C语言,或C+,或Visual C+.3. 实验时间4学时4. 实验内容在实验三的表达式语法分析程序里,添加语义

18、处理部分输出表达式的中间代码,用四元式序列表示。5. 实验要求l 在实验三“语法分析器”的里面添加PL/0语言“表达式”部分的语义处理,输出表达式的中间代码。l 中间代码用四元式序列表示。6. 输入输出输入:表达式,例如: a * (b + c)。输出:( + b c t1 )( * a t1 t2 )六、课程设计1、选题(四选一):(1)构造递归下降分析程序语法分析器(2)构造预测分析表语法分析器(3)构造算符优先分析语法分析器(4)构造LR(0)分析法语法分析器2、设计方法: 小组分工,合作完成。从小到大,逐步扩展。按照文法和程序的特点,逐步完成设计和测试。3、设计报告: 应包括:报告标题

19、、主要工作概述、具体内容(算法部分)、开发经验等。七、考核方式1、实验报告和课程设计报告实验独立完成,提交实验报告;课程设计采用分组的形式,3人一组,每个实习小组交一份课程设计报告,格式要求绝对规范!内容应包括以下内容:l 题目l 设计思想l 算法l 调试数据(输入/输出)2、评分标准l 由指导教师根据实验验收情况并结合实验报告质量及学习态度等进行评分。l 课程设计作为独立考查课,学分为1。八、参考文献 编译原理课程组 35 of 371编译原理(第二版),张素琴、吕映芝、蒋维杜,清华大学出版社,2005年出版。2编译程序设计原理,杜书敏、王永宁,北京大学出版社,1988年出版。3计算机编译原

20、理,张幸儿,科学出版社,1999年出版。4编译程序原理与技术,李赣生等,清华大学出版社,1997年10月出版。九、附录PL0语言编译源程序清单(部分)源代码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/*

21、最多的虚拟机代码数 */#define cxmax 200#define cxmaxadd1 201/* 当函数中会发生fatal error时,返回-1告知调用它的函数,最终退出程序 */#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

22、=expression(a,b,c)return -1#define factordo(a,b,c) if(-1=factor(a,b,c)return -1#define 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(

23、a,b,c)return -1#define vardeclarationdo(a,b,c) if(-1=vardeclaration(a,b,c)return -1typedef enum 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,read

24、sym,dosym,callsym,constsym,varsym,procsym;#define symnum 32/* 名字表中的类型 */enum object constant,variable,procedur;/* 虚拟机代码 */enum fct lit,opr,lod,sto,cal,inte,jmp,jpc;#define fctnum 8/* 虚拟机代码结构 */struct instructionenum fct f; /* 虚拟机代码指令 */int l; /* 引用层与声明层的层次差 */int a; /* 根据f的不同而不同 */;FILE* fas;/* 输出名字

25、表 */FILE* fa; /* 输出虚拟机代码 */FILE* fa1; /* 输出源文件及其各行对应的首地址 */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

26、 cx; /* 虚拟机代码指针 */char line81; /* 读取行缓冲区 */char aal; /* 临时符号 */struct instruction codecxmaxadd1; /* 存放虚拟机代码的数组 */char wordnorwal; /* 保留字 */enum symbol wsymnorw; /* 保留字对应的符号值 */enum symbol ssym256; /* 单字符的符号值 */char mnemonicfctnum5; /* 虚拟机代码指令名称 */bool declbegsyssymnum; /* 表示声明开始的符号集合 */bool statbegs

27、yssymnum; /* 表示语句开始的符号集合 */bool facbegsyssymnum; /* 表示因子开始的符号集合 */* 名字表结构 */struct tablestructchar nameal;/* 名字 */enum object kind;/* 类型:const,var or procedure */int val; /* 数值,仅const使用 */int level; /* 所处层,仅const不使用 */int adr; /* 地址,仅const不使用 */int size; /* 需要分配的数据区空间,仅procedure使用 */;struct tablestr

28、uct tabletxmaxadd1; /* 名字表 */FILE* 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*

29、 s1,bool* s2,int n);int mulset(bool* 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(bo

30、ol* fsys,int* ptx,int lev);void listcode(int cx0);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和V

31、isual C.NET上运行通过使用方法:运行后输入PL/0源程序文件名回答是否输出虚拟机代码回答是否输出名字表fa.tmp输出虚拟机代码fa1.tmp输出源文件及其各行对应的首地址fa2.tmp输出结果fas.tmp输出名字表*/#include <stdio.h>#include "pl0c.h"#include "string.h"/* 解释执行时使用的栈 */#define stacksize 500 int main()bool nxtlevsymnum;init();/* 初始化 */fas=fopen("fas.tmp

32、","w");fa1=fopen("fa1.tmp","w");printf("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)");/* 是否输出

33、虚拟机代码 */scanf("%s",fname);listswitch=(fname0='y'|fname0='Y');printf("List symbol table?(Y/N)");/* 是否输出名字表 */scanf("%s",fname);tableswitch=(fname0='y'|fname0='Y');err=0;cc=cx=ll=0;ch=' 'kk=al-1;if(-1!=getsym()fa=fopen("fa.tmp&

34、quot;,"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();/*

35、调用解释执行程序 */elseprintf("Errors in pl/0 program");fclose(fin);elseprintf("Can't open file!n");fprintf(fa1,"Can't open file!n");fclose(fa1);fclose(fas);printf("n");return 0;/* 在适当的位置显示错误 */void error(int n)char space81;memset(space,32,81);spacecc-1=0; /*

36、出错时当前符号已经读完,所以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;doif(k<al)ak=ch;k+;getchd

37、o;while(ch>='a'&&ch<='z'|ch>='0'&&ch<='9');ak=0;strcpy(id,a);i=0;j=norw-1;do /* 搜索当前符号是否为保留字 */k=(i+j)/2;if(strcmp(id,wordk)<=0)j=k-1;if(strcmp(id,wordk)>=0)i=k+1;while(i<=j);if(i-1>j)sym=wsymk; else sym=ident; /* 搜索失败则,是名字或数字 *

38、/elseif(ch>='0'&&ch<='9')/* 检测是否为数字:以0.9开头 */k=0;num=0;sym=number;donum=10*num+ch-'0'k+;getchdo;while(ch>='0'&&ch<='9'); /* 获取数字的值 */k-;if(k>nmax)error(30);elseif(ch=':')/* 检测赋值符号 */getchdo;if(ch='=')sym=becomes;g

39、etchdo;elsesym=nul;/* 不能识别的符号 */elseif(ch='<')/* 检测小于或小于等于符号 */getchdo;if(ch='=')sym=leq;getchdo;elsesym=lss;elseif(ch='>')/* 检测大于或大于等于符号 */getchdo;if(ch='=')sym=geq;getchdo;elsesym=gtr;elsesym=ssymch;/* 当符号不满足上述条件时,全部按照单字符符号处理 */getchdo;return 0;/* 编译程序主体 */int

40、 block(int lev, /* 当前分程序所在层 */ int tx, /* 名字表当前尾指针 */ bool* fsys /* 当前模块后跟符号集合 */ )int i;int dx; /* 名字分配到的相对地址 */int tx0; /* 保留初始tx */int cx0; /* 保留初始cx */bool nxtlevsymnum; /* 在下级函数的参数中,符号集合均为值参,但由于使用数租实现, 传递进来的是指针,为防止下级函数改变上级函数的集合,开辟新的空间 传递给下级函数,之后所有的nxtlev都是这样 */dx=3; tx0=tx;/* 记录本层名字的初始位置 */tabl

41、etx.adr=cx;gendo(jmp,0,0);if(lev>levmax)error(32);doif(sym=constsym)/* 收到常量声明符号,开始处理常量声明 */getsymdo;doconstdeclarationdo(&tx,lev,&dx);/* dx的值会被constdeclaration改变,使用指针 */while(sym=comma) getsymdo;constdeclarationdo(&tx,lev,&dx);if(sym=semicolon)getsymdo;else error(5);while(sym=iden

42、t);if(sym=varsym)/* 收到变量声明符号,开始处理变量声明 */getsymdo;dovardeclarationdo(&tx,lev,&dx);while(sym=comma) getsymdo;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

43、,&dx);/* 记录过程名字 */getsymdo;else error(4);/* procedure后应为标识符 */if(sym=semicolon)getsymdo;else error(5);/* 漏掉了分号 */memcpy(nxtlev,fsys,sizeof(bool)*symnum);nxtlevsemicolon=true;if(-1=block(lev+1,tx,nxtlev)return -1;/* 递归调用 */if(sym=semicolon)getsymdo;memcpy(nxtlev,statbegsys,sizeof(bool)*symnum);nx

44、tlevident=true;nxtlevprocsym=true;testdo(nxtlev,fsys,6);else error(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;/

45、* 声明部分中每增加一条声明都会给dx增加1,声明部分已经结束,dx就是当前过程数据的size */cx0=cx;gendo(inte,0,dx);/* 生成分配内存代码 */* 语句后跟符号为分号或end */memcpy(nxtlev,fsys,sizeof(bool)*symnum);/* 每个后跟符号集和都包含上层后跟符号集和,以便补救 */nxtlevsemicolon=true;nxtlevendsym=true;statementdo(nxtlev,&tx,lev);gendo(opr,0,0);/* 每个过程出口都要使用的释放数据段指令 */memset(nxtlev,

46、0,sizeof(bool)*symnum);/*分程序没有补救集合 */testdo(fsys,nxtlev,8);/* 检测后跟符号正确性 */listcode(cx0);/* 输出代码 */return 0;/* 初始化 */void init()int i;/* 设置单字符符号 */for(i=0;i<=255;i+)ssymi=nul;ssym'+'=plus;ssym'-'=minus;ssym'*'=times;ssym'/'=slash;ssym'('=lparen;ssym')

47、9;=rparen;ssym'='=eql;ssym','=comma;ssym'.'=period;ssym'#'=neq;ssym''=semicolon;/* 设置保留字名字 */strcpy(&(word00),"begin");strcpy(&(word10),"call");strcpy(&(word20),"const");strcpy(&(word30),"do");strcpy(&

48、;(word40),"end");strcpy(&(word50),"if");strcpy(&(word60),"odd");strcpy(&(word70),"procedure");strcpy(&(word80),"read");strcpy(&(word90),"then");strcpy(&(word100),"var");strcpy(&(word110),"while&quo

49、t;);strcpy(&(word120),"write");/* 设置保留字符号 */wsym0=beginsym;wsym1=callsym;wsym2=constsym;wsym3=dosym;wsym4=endsym;wsym5=ifsym;wsym6=oddsym;wsym7=procsym;wsym8=readsym;wsym9=thensym;wsym10=varsym;wsym11=whilesym;wsym12=writesym;/* 设置指令名称 */strcpy(&(mnemoniclit0),"lit");strc

50、py(&(mnemonicopr0),"opr");strcpy(&(mnemoniclod0),"lod");strcpy(&(mnemonicsto0),"sto");strcpy(&(mnemoniccal0),"cal");strcpy(&(mnemonicinte0),"int");strcpy(&(mnemonicjmp0),"jmp");strcpy(&(mnemonicjpc0),"jpc&qu

51、ot;);/* 供getsym取一个字符,每次读一行,存入line缓冲区,line被getsym取空时 再读一行*/int getch()if(cc=ll)if(feof(fin)printf("program incomplete");return -1;ll=0;cc=0;printf("%d ",cx);fprintf(fa1,"%d ",cx);ch=' 'while(ch!=10)fscanf(fin,"%c",&ch);printf("%c",ch);fprintf(fa1,"%c",ch);linell=ch;ll+;printf("n");fprintf(fa1,"n");ch=linecc;cc+;return 0;/* 生成一项名字表 */void enter(enum object k,/* 名字种类const,var or procedure */ int* ptx,/* 名字表尾指针的指针,为了可以改变名字表尾指针的值,以后所

温馨提示

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

评论

0/150

提交评论