2007计软编译原理实验(共37页)

上传人:痛*** 文档编号:129931780 上传时间:2022-08-03 格式:DOC 页数:37 大小:182.50KB
收藏 版权申诉 举报 下载
2007计软编译原理实验(共37页)_第1页
第1页 / 共37页
2007计软编译原理实验(共37页)_第2页
第2页 / 共37页
2007计软编译原理实验(共37页)_第3页
第3页 / 共37页
资源描述:

《2007计软编译原理实验(共37页)》由会员分享,可在线阅读,更多相关《2007计软编译原理实验(共37页)(37页珍藏版)》请在装配图网上搜索。

1、编译原理实验书 2010年11月 实验目录: 适用专业及实验总学时:2007级计算机科学与技术专业(软件方向),18学时。 任课教师: 黄玲 E-mail: huangl 恭喜你!你将进入非常重要的专业课程的实践。编译原理的知识影响到专业人员的素质,除编译程序外有大量专业工作与编译技术相关 。你现在需要通过脚踏实地的实践学习(很辛苦的!),把自己的专业水平提高一个层次。你需要在实验课前自己阅读程序代码,在实验课中调试程序,实验课后完成实验报告(每一个实验上交一份实验报告),实验报告必须阐述清楚你的所做的工作,内容包含修改思路、关键修改代码、运行结果、对运行结果的评价、进一步改进的建议。最重要的

2、是,通过实践你可以获得专业的能力和自信。加油!实验1:词法分析程序(3学时,第12周)一、实验目的和内容:1实验目的:通过词法分析程序,了解词法分析的过程。2实验内容:用C实现对Pascal的子集程序设计语言的词法识别。3实验要求:要求修改文法和程序,增加浮点数处理功能。4. 实验环境是Windows操作系统、Visual C+开发环境。二、未增加浮点数处理的原设计:1 程序设计语言的描述:.PROGRAM ;CONST ,;标识符=无符号整数VAR ,;标识符,标识符:INTEGER|LONG;PROCEDURE 标识符;|PROCEDURE 标识符(标识符:);|标识符:=IF THEN

3、WHILE DO 标识符|标识符()READ (标识符,标识符)WRITE (,)BEGIN ;END|ODD +|-标识符|无符号整数|()+|-*|/=|=其中: 用左右尖括号括起来的符号串表示非终结符 定义为 表示该语法成分可以重复0n次 表示方括号内为可选项,即0或1次2 程序设计语言单词的内部编码:(35个终结符) 内码单词内码单词内码单词内码单词1PROGRAM2CONST3VAR4INTEGER5LONG6PROCEDURE7IF8THEN9WHILE10DO11READ12WRITE13BEGIN14END15ODD16+17-18*19/20=21222325=26.27,2

4、8;29:30:=31(32)33无符号整数34标识符35# 3下面是一个词法分析程序,该程序能够将源程序,也就是相应字符流转换成内码,并输出到文件。程序的执行需要提供两个参数,第一个参数是源程序文件名,第二个参数是存放分析结果的文件名,第二个参数可以省略,可由程序自动生成。Vc+6程序参数的设置方法:菜单project下子菜单settings中的debug选项卡下program arguments对话框中,输入参数。如采用Visual Studio 2008开发环境,构建控制台应用程序,参数设置:项目属性-(活动debug模式)配置属性-调试-命令参数,同时工作目录为当前工程下debug 。

5、 #include #include #include #include #define lenth1 15 /保留字表的长度#define lenth2 17 /运算符界符表长度struct char name21;int type;int addr;indent1000; /符号表struct stchar name21;int code;sym; /当前单词FILE *f1,*f2;int line=1,row=1,val; /行号、列号、数字串的值char ch= ; /当前字符int lenth3=0; /符号表中实际的标识符个数void getsym();char getchr()

6、;void error(int);main(int argc,char *argv) char ft12,*fc; if (f1=fopen(argv1,r)=NULL) /打开源程序文件 printf(can not open file.n);exit(0); if (argc=2) /如果没有提供第二个参数 strcpy(ft,argv1);if (fc=strchr(ft,.)!=NULL) /如果第一个参数即源文件名,有后缀 .xxxstrcpy(fc,.mid); /结果文件名:源文件名非后缀部分.midelsestrcat(ft,.mid); /结果文件名:源文件名.mid els

7、e strcpy(ft,argv2); if (f2=fopen(ft,w)=NULL) /打开结果文件 printf(cannot open file 2n); exit(0); while (!feof(f1) /只要没有遇到源文件的结尾,继续循环。 getsym(); /获取一个单词放到sym printf(%s %dn,sym.name,sym.code); /显示当前单词的名字及其内码 fprintf(f2,%s %dn,sym.name,sym.code);/向输出文件写入:单词名字 单词内码 fclose(f1); fclose(f2);void getsym()static c

8、har alenth110=PROGRAM,CONST,VAR,INTEGER,LONG,PROCEDURE,IF,THEN,WHILE,DO,READ,WRITE,BEGIN,END,ODD;/保留字表static char dlenth23=+,-,*,/,=,=,.,;,:,:=,(,); /运算符界符表char str21;int i,n;while (isspace(ch) ch=getchr();if (isalpha(ch) /如果当前字符是字母,则后面几行代码就是识别标识符的自动机的实现n=0; while (isalpha(ch) | isalnum(ch) /当前字符是字母

9、或者数字,继续循环 if (isalpha(ch) ch=tolower(ch); if (n20) strn+=ch; /构造字符串 ch=getchr(); /从文件中读取下一个字符 strn=0; for (i=0;ilenth1;i+) /检查当前符号串是否保留字 if (!strcmp(str,ai) break; /如果字符串已经登记在保留字表,中断循环 if (ilenth1) /如果该字符串是保留字,将当前单词写入sym strcpy(sym.name,ai);sym.code=i+1; else /该单词不是保留字,而是标识符 for(i=0;ilenth3;i+) /在符号

10、表里检查是否已经登记过该标识符 if (!strcmp(str,indenti.name) break; /如果登记过,中断循环 if (i=lenth3) strcpy(indenti.name,str);/如果没有登记过该标识符,登记它到符号表。lenth3+; strcpy(sym.name,indenti.name); /当前标识符写入sym sym.code=34; else if (isalnum(ch) /如果当前字符是数字,则后面就是识别数字串的自动机的实现 val=0;n=0; while (isalnum(ch) val=val*10+ch-0; sym.namen+=ch

11、; ch=getchr();sym.namen=0;sym.code=33; else /当前字符是运算符或者界符 if (ch=+ | ch=- | ch=* | ch=/ | ch= | ch=. | ch=, | ch=; | ch=( | ch=) str0=ch;str1=0;ch=getchr(); /从文件中读入一个字符 for (i=0;ilenth2;i+) /在运算符界符表查询,是否有此ch字符if (!strcmp(str,di) strcpy(sym.name,str); /有, sym.code=i+16; else /处理符号 = : := n=0;if (ch=

12、| ch=:) strn+=ch; if (ch=getchr()=) / =或:= strn+=ch; ch=getchr(); else if (ch=) / =或 strn+=ch; ch=getchr(); else if (ch=-1) strcpy(sym.name,); sym.code=35; /#/else error(1); strn=0; /str为一个完整的单词 for (i=0;ilenth2;i+) /查运算符界符表,看是否有此符号串str if (!strcmp(str,di) strcpy(sym.name,str); sym.code=i+16; char g

13、etchr() char ch=fgetc(f1); if (ch=n) row=1; line+; else if (ch!= & ch!=t) row+; return (ch);void error(int n) printf(%d error happens.n,n); exit(0);4. 词法分析程序 getsym()流程图读入下一个字符到chch的符号是空格? Y Nch的符号是字母? 标识符或者保留字 Y ch的符号是字母或数字? N N Ych的符号是字母? N Y将ch的字母变为小写字母将ch的符号加入到字符数组str尾读入下一个符号到ch在str尾增加0,构建一个字符串在

14、保留字表a中查找str的位置ii或者:吗?构造str并读入符号到ch Y ch是=吗? N N 或: Y =或:=构造str并读入符号到ch ch是吗? N Y =或构造str并读入符号到ch登记#到sym,内码35 在str末尾加0,构建字符串在运算符界符表d查str位置i。查到?单词str?登记str到sym,内码i+16 Y N结束三、增加浮点数功能时,可以使用下面的源程序作为词法分析程序的输入(当然,你也可以自己编写各种源程序,以便测试程序。)词法分析程序输出词法分析结果。PROGRAM mypascal;CONST UNIT=100;VAR x:INTEGER,y:FLOAT;PRO

15、CEDURE subproc(i:INTEGER); BEGIN x:=i; END; BEGIN subproc(20); x:=x+UNIT; y=y*x+23.45;END.实验2:语法分析-递归子程序法(3学时,第13周)一、实验的目的和内容:1目的:通过完成语法分析程序,了解语法分析的过程和作用。2实验内容:用递归子程序法实现对Pascal的子集程序设计语言的分析程序。分析程序对源程序的内码流进行分析,如果为文法定义的句子,则输出“是”,否则输出“否”。3 实验要求:要求修改文法和程序,增加浮点数处理功能。二、未增加浮点数处理功能的原设计:1改写实验一的未增加浮点数处理的文法,使其是

16、LL(1)文法。改变后文法如下:.PROGRAM ;CONST ;|标识符=无符号整数, |VAR |标识符:;, 标识符 | |INTEGER|LONG; |PROCEDURE 标识符;(标识符:) |; |标识符:=|()|IF THEN WHILE DO READ (标识符)WRITE (), |BEGIN END; |ODD +|-|标识符|无符号整数|()+|-*|/=|=2非终结符和函数名对照表:(34个非终结符) 非终结符函数名非终结符函数名programprogheadblockconsexplconsdefivarexplconssuffvardefivarsuffprocd

17、efitypilprocedhprocsuffassiprosentencesuffixifsentreadwhilsentidsuffwritecompsentexprsuffsentsuffconditiotermsuffexpresstermfactsuffargumentfactoraAddopermuloperrespoper3下面是一个递归子程序语法分析程序,程序的执行需要提供一个参数:源程序文件名。该程序判断给定的源程序语法是否正确。#include #include #include #include #define PROGRAM 1 /从这里开始宏定义终结符内码,为的是增加

18、程序的易读性#define CONST 2#define VAR 3 #define INTEGER 4#define LONG 5#define PROCEDURE 6#define IF 7#define THEN 8#define WHILE 9#define DO 10#define READ 11#define WRITE 12#define BEGIN 13#define END 14#define ODD 15#define ADD 16#define SUB 17#define MUL 18#define DIV 19#define EQU 20#define NEQ 21#d

19、efine LES 22#define LEQ 23#define LAG 24#define GEQ 25#define DOT 26#define COM 27#define SEM 28#define COL 29#define ASS 30#define LBR 31#define RBR 32#define INT 33#define ID 34 /标识符内码#define EIN 35#define lenth1 15 /保留字表长度#define lenth2 17 /运算符界符长度struct char name21;int type;int addr;indent 1000;

20、 /符号表struct stchar name21;int code;sym; /当前单词int lenth=0;FILE* f1;int line=0,row=0,val;void getsym();char getchr();void error(int);void program();void proghead();void block();void consexpl();void consdefi();void varexpl();void conssuff();void vardefi();void varsuff();void procdefi();void typeil();vo

21、id procedh();void procsuff();void assipro();void sentence();void suffix();void ifsent();void read();void whilsent();void idsuff();void write();void compsent();void exprsuff();void sentsuff();void condition();void termsuff();void express();void term();void factsuff();void factor();void addoper();void

22、 muloper();void respoper();void argument();char ch= ; /当前字符int lenth3=0; /符号表中实际标识符个数void main(int argc,char* argv) if (f1=fopen(argv1,r)=NULL) /打开源程序文件 printf(cannot open filen); exit(0); getsym(); /获取第一个单词 program(); /程序的语法分析 printf(the program is rightn);/源程序正确 fclose(f1);void program() /非终结符的分析程

23、序:-. proghead(); /非终结符的分析程序 block(); /非终结符的分析程序 if (sym.code=DOT) /DOT为.的内码表示,见文件首的宏定义。如果当前单词是. getsym(); /读取下一个单词到sym else error(2);void proghead() /非终结符的分析程序:-PROGRAM 标识符;if(sym.code=PROGRAM) getsym(); if (sym.code=ID) getsym(); if (sym.code=SEM) getsym(); else error(5); else error(4); elseerror(3

24、);void block() /非终结符的分析程序 consexpl(); varexpl(); procdefi(); compsent();void consexpl() /非终结符CONST ;|if (sym.code=CONST) /如果当前单词不是CONST,则是分支,什么事情都不做。 / CONST ; getsym(); consdefi(); conssuff(); if (sym.code=SEM) getsym(); else error(6);void consdefi() /非终结符if (sym.code=ID) getsym(); if (sym.code=EQU

25、) getsym();if (sym.code=INT)getsym();elseerror(9); else error(8); elseerror(7);void conssuff() /非终结符,| if (sym.code=COM) getsym(); consdefi(); conssuff();/* if (sym.code=SEM) getsym(); else error(10); */void varexpl() /变量说明部分 if (sym.code=VAR) getsym();vardefi();varsuff(); void vardefi() /非终结符if (sy

26、m.code=ID) getsym(); idsuff(); if (sym.code=COL) getsym(); typeil(); if (sym.code=SEM) getsym(); else error(12); else error(11);void varsuff() /非终结符if (sym.code=ID) vardefi(); varsuff();void typeil() /非终结符if (sym.code=INTEGER|sym.code=LONG) getsym();else error(13);void procdefi() /非终结符if (sym.code=P

27、ROCEDURE) procedh(); block(); if (sym.code=SEM) getsym(); procsuff(); else error(14);void procedh() /非终结符if (sym.code=PROCEDURE) getsym(); if (sym.code=ID) getsym(); argument(); if (sym.code=SEM) getsym(); else error(16); else error(15);void argument() /非终结符if (sym.code=LBR) getsym(); if (sym.code=I

28、D) getsym(); if (sym.code=COL) getsym(); typeil(); if(sym.code=RBR) getsym(); else error(19); else error(18); else error(17);void procsuff() /非终结符if (sym.code=PROCEDURE) procedh(); block(); if (sym.code=SEM) getsym(); procsuff(); else error(20);void assipro() /赋值或调用语句 if (sym.code=ID) getsym();suffi

29、x(); else error(21);void sentence() /语句 if (sym.code=ID)assipro(); else if (sym.code=IF)ifsent(); else if (sym.code=WHILE)whilsent();else if (sym.code=READ)read();else if (sym.code=WRITE)write();else if (sym.code=BEGIN)compsent();void suffix() /非终结符if (sym.code=ASS) getsym(); express();elseif (sym.c

30、ode=LBR) getsym(); express(); if (sym.code=RBR) getsym(); else error(22);void ifsent() /非终结符if (sym.code=IF) getsym(); condition(); if (sym.code=THEN) getsym(); sentence(); else error(24);elseerror(23);void whilsent() /while语句 if (sym.code=WHILE) getsym();conditio();if (sym.code=DO) getsym(); senten

31、ce();else error(26); else error(25);void read() /非终结符if (sym.code=READ) getsym(); if (sym.code=LBR) getsym(); if (sym.code=ID) getsym(); idsuff(); if (sym.code=RBR) getsym(); else error(27); else error(30); else error(29); elseerror(28);void idsuff() /非终结符if (sym.code=COM) getsym(); if (sym.code=ID)

32、 getsym(); idsuff(); else error(31);void write() /写语句 if (sym.code=WRITE) getsym();if (sym.code()=LBR) getsym(); express(); exprsuff(); if (sym.code=RBR) getsym() else error(34);else error(33); else error(32); void compsent() /非终结符if (sym.code=BEGIN) getsym(); sentence(); sentsuff(); if (sym.code=EN

33、D) getsym(); else error(36); elseerror(35);void exprsuff() /非终结符 if (sym.code=COM) getsym(); express(); exprsuff();void sentsuff() /非终结符if (sym.code=SEM) getsym(); sentence(); sentsuff();void condition() /非终结符if (sym.code=ODD) getsym(); express(); else express(); respoper(); express();void express()

34、 /非终结符+|-|if (sym.code=ADD|sym.code=SUB) getsym();term();termsuff();void term() /非终结符 factor(); factsuff();void termsuff() /非终结符if (sym.code=ADD|sym.code=SUB) getsym(); factor(); factsuff();void factsuff() /非终结符if (sym.code=MUL|sym.code=DIV) getsym(); factor(); factsuff();void factor() /非终结符if (sym.

35、code=ID) getsym(); /factsuff();else if (sym.code=INT) getsym();else if (sym.code=LBR) getsym(); express(); if (sym.code=RBR) getsym(); else error(38);elseerror(37);void addoper() /非终结符 if (sym.code=ADD|sym.code=SUB) getsym(); else error(39);void muloper() /非终结符 if (sym.code=MUL|sym.code=DIV) getsym(

36、); else error(40);void respoper() /非终结符 if (sym.code=EQU & sym.code=GEQ) getsym(); else error(41);void getsym()static char alenth110=program,const,var,integer,long,procedure,if,then,while,do,read,write,begin,end,odd;static char dlenth23=+,-,*,/,=,=,.,;,:,:=,(,);char str21;int i,n;while (isspace(ch)

37、ch=getchr();if (isalpha(ch) n=0; while (isalpha(ch) | isalnum(ch) if (isalpha(ch) ch=tolower(ch); if (n20) strn+=ch; ch=getchr(); strn=0; for (i=0;ilenth1;i+) if (!strcmp(str,ai) break; if (ilenth1) strcpy(sym.name,ai);sym.code=i+1; else for(i=0;ilenth3;i+) if (!strcmp(str,indenti.name) break; if (i=lenth3) strcpy(indenti.name,str); strcpy(sym.name,indenti.name); sym.code=34; lenth3+;/在符号表登记标识符 else if (isalnum(ch) val=0;n=0; while (isalnum(ch) val=val*10+ch-0; sym.namen+=ch; ch=getchr(); sym.namen=0;

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


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