编译原理词法分析程序实现实验报告.doc

上传人:laozhun 文档编号:2396938 上传时间:2023-02-17 格式:DOC 页数:50 大小:489KB
返回 下载 相关 举报
编译原理词法分析程序实现实验报告.doc_第1页
第1页 / 共50页
编译原理词法分析程序实现实验报告.doc_第2页
第2页 / 共50页
编译原理词法分析程序实现实验报告.doc_第3页
第3页 / 共50页
编译原理词法分析程序实现实验报告.doc_第4页
第4页 / 共50页
编译原理词法分析程序实现实验报告.doc_第5页
第5页 / 共50页
点击查看更多>>
资源描述

《编译原理词法分析程序实现实验报告.doc》由会员分享,可在线阅读,更多相关《编译原理词法分析程序实现实验报告.doc(50页珍藏版)》请在三一办公上搜索。

1、实验一 词法分析程序实现一、实验内容选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。输入:由无符号数和+,*,/, ( , ) 构成的算术表达式,如1.5E+2100。输出:对识别出的每一单词均单行输出其类别码(无符号数的值暂不要求计算)。二、 设计部分因为需要选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来,而其中的关键则为无符号数的识别,它不仅包括了一般情况下的整数和小数,还有以E为底数的指数运算,其中关于词法分析的无符号数的识别过程流程图如下:GOTO 1:GOTO 2:三、 源程序代码部分#include #include#

2、include #define MAX 100#define UNSIGNEDNUMBER 1#define PLUS 2#define SUBTRACT 3#define MULTIPLY 4#define DIVIDE 5#define LEFTBRACKET 6#define RIGHTBRACKET 7#define INEFFICACIOUSLABEL 8#define FINISH 111int count=0;int Class;void StoreType();int Type100;char Store20=0;void ShowStrFile();/已经将要识别的字符串存在

3、文件a中void Output(int a,char *p1,char *p2);/字符的输出过程int Sign(char *p);/+-*/整体识别过程int UnsignedNum(char *p);/是否适合合法的正整数09int LegalCharacter(char *p);/是否是合法的字符:Sign(p)|UnsignedNum(p)|E|.void DistinguishSign(char *p);/+-*/具体识别过程void TypyDistinguish();/字符的识别过程void ShowType();/将类别码存储在Type100中,为语法分析做准备void Sh

4、owStrFile()/已经将要识别的字符串存在文件a中FILE *fp_s;char ch;if(fp_s=fopen(a.txt,r)=NULL)printf(The FILE cannot open!); exit(0);elsech=fgetc(fp_s);while(ch!=EOF)putchar(ch);ch=fgetc(fp_s);printf(n);void StoreStr()/将文件中的字符串存储到数组Storei FILE *fp=fopen(a.txt,r);char str;int i=0;while(!feof(fp)fscanf(fp,%c,&str);if(st

5、r=?)Storei=0;break;Storei=str;i+;Storei=0;void ShowStore()int i;for (i=0;Storei!=0;i+) printf(%c,Storei);printf(n);void Output(int a,char *p1,char *p2) printf(%3st%dt%st,CLASS,a,VALUE);while(p1=p2)printf(%c,*p1);p1+;printf(n);int Sign(char *p)char ch=*p;if(ch=+|ch=-|ch=*|ch=/|ch=(|ch=)return 1;elser

6、eturn 0;int UnsignedNum(char *p)char ch=*p;if(0=ch&ch=9)return 1;elsereturn 0;int LegalCharacter(char *p)char ch=*p;if(Sign(p)|UnsignedNum(p)|ch=E|ch=.)return 1;else return 0;void DistinguishSign(char *p) int Class;char ch=*p;switch(ch) case +: Output(PLUS,p,p);Typecount+=PLUS;break; case -: Output(

7、SUBTRACT,p,p);Typecount+=SUBTRACT;break; case *: Output(MULTIPLY,p,p);Typecount+=MULTIPLY;break; case /: Output(DIVIDE,p,p);Typecount+=DIVIDE;break; case (: Output(LEFTBRACKET,p,p);Typecount+=LEFTBRACKET;break; case ): Output(RIGHTBRACKET,p,p);Typecount+=RIGHTBRACKET;break; default: break; void Typy

8、Distinguish() printf(词法开始,分析结果如下:n); char *p; p=&Store0; while(*p!=0) if(Sign(p) DistinguishSign(p+); continue; else if(UnsignedNum(p)|*p=.) char *p1=p;if(UnsignedNum(p)while(UnsignedNum(p)p+;if(*p=0) Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=E)p+;if(UnsignedNum(p

9、)while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=+|*p=-)p+;while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(INEFFICACIOUSLABEL,p1,-p);printf(输入的这个符号是不合法的!);break;Typecount+=INEFFICACIOUSLABEL;p+

10、;continue;else if(*p=.)p+;while(UnsignedNum(p)p+;if(*p=0) Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=E)p+;if(UnsignedNum(p)while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=+|*p=-)p+;if(UnsignedNum(p)while(Unsigned

11、Num(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(INEFFICACIOUSLABEL,p1,-p);printf(输入的这个符号是不合法的! /n);break;Typecount+=INEFFICACIOUSLABEL;p+;continue;elseOutput(INEFFICACIOUSLABEL,p1,-p);printf(输入的这个符号是不合法的!因为他的后面既不是09也不是“+”或者“-);break;/1.5E*2这样的字符串不是无符号数 Typecou

12、nt+=INEFFICACIOUSLABEL;p+;continue;else Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;if(*p=.)p+;if(UnsignedNum(p)p+;while(UnsignedNum(p)p+;if(*p=0) Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;

13、continue;else if(*p=E)p+;if(UnsignedNum(p)while(UnsignedNum(p)p+; Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else if(*p=+|*p=-)p+;while(UnsignedNum(p)p+;Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUMBER;p+;continue;else Output(UNSIGNEDNUMBER,p1,-p);Typecount+=UNSIGNEDNUM

14、BER;p+;continue;else Output(INEFFICACIOUSLABEL,p1,-p); printf(输入的这个符号是不合法的!);break;Typecount+=INEFFICACIOUSLABEL;p+;continue; else if(*p=E) Output(INEFFICACIOUSLABEL,p,p);break; Typecount+=INEFFICACIOUSLABEL; printf(输入的这个符号是不合法的!); p+; continue; printf(nn词法分析完毕!);void ShowType()/将类别码存储在Type100中,为语法分

15、析做准备 printf(n用类别码表示输入的字符如下:n);int i;printf(n);for(i=0;Typei!=FINISH;i+)printf(%d,Typei);printf(nn); void main() /词法分析部分 StoreStr(); ShowStore(); TypyDistinguish(); Typecount=FINISH; ShowType(); 四、 实验结果正确的结果:错误的结果:输入的字符串中有1.5E*2因为实验是以文件的形式进行读取的所以,在读取不合法的过程中只是将存在project 中的a.txt 中的内容改变改为1.5E*2+100*555实

16、验结果如下:结果分析:对于正确的结果,我以二元式的形式输出,包括他的值和他的类别码,其中将类别码存放在另外的一个数组中,为了在实验二中的语法识别打下基础。对于错误的结果,我选择的是跳出这个程序,并且能过分析出错的原因。改进设计:(1)字符串是以文件的形式输出的,连续重复输入存在局限性(2)能够跳过错误的字符继续识别剩下的字符实验一扩展李晓萌 088330一、实验内容:试对基础实验识别的单词种类进行扩充,构造识别以下单词的词法分析程序。语言中具有的单词包括五个有代表性的关键字begin、end、if、then、else;标识符;整型常数;六种关系运算符;一个赋值符和四个算术运算符。二、 设计部分

17、基础实验和扩展实验的差别在基础实验的关键在于无符号数的判断,但是,扩展实验的关键在于关键字和标识符的识别。关于关键字的识别,通过和题目中给出的几个关键字的对比,若相同则可以确定是关键字,否则,就可自动确定为标识符具体实现的流程图如下:三、 源程序代码部分#include #include #define BEGIN 1#define END 2#define IF 3#define THEN 4#define ELSE 5# define ID 6# define INT 7# define LT 8# define LE 9# define EQ 10# define NE 11# defi

18、ne GT 12# define GE 13#define IS 14#define PL 15#define MI 16#define MU 17#define DI 18char *KeyWord5=begin,end,if,then,else; int i=0,j=0,k=0,t=0;/搜索指示器 char ch;/存放最新读入的原程序字符 char strToken20;/存放构成单词符号的字符串 char * chr_form100;/字符表 char * int_form100;/常数表 char form1000; int q=0; int temp; void GetChar(

19、)/将下一个字符读入ch中,搜索指示器前移一字符位 ch=formk; k+; void GetBC()/检查ch中的字符是否为空白,若是则调用Getchar直至ch中进入 /一个非空白字符 while(ch= ) /k-; GetChar(); void Concat()/将ch中的字符连接到strToken之后, strTokeni=ch; i+; bool IsLetter()/判断ch中的字符是否为字符 if(ch=a)|(ch=A) return (1); else return(0); bool IsDigit()/判断ch中的字符是否为数字 /k-; if(ch)=0) retu

20、rn (1); else return (0); int Reserve()/对strToken中的字符串查找保留字表,若它是一个保留字 /则返回它的编码,否则返回-1值 for(int q=0;q5;q+) if(strcmp(KeyWordq,strToken)=0) return q; if(q=4) return -1; void Retract()/将搜索指示器回调一个字符位置,将ch置为空白字符 k-; ch=NULL; char*InsertId()/将strToken中的标识符插入符号表,返回符号表的指针 chr_formj=strToken; j+; return chr_f

21、orm0; char * InsertConst()/将strToken中的常数插入常数表,返回常数表指针 int_formt=strToken; t+; return int_form0; int code; / void Output(int a,char *p1,char *p2)coutt类别码(CLASS):at 单词值(VALUE):;while(p1=p2)cout*p1;p1+;coutendl; void analyze() GetChar(); GetBC(); /cout此处没有错endl; if(IsLetter() while(IsLetter()|IsDigit()

22、 Concat(); GetChar(); /cout此处没有错endl; Retract(); code=Reserve(); switch(code) case 0:cout需检测的的单词:strToken 类别码为: BEGIN endl;break; case 1:cout需检测的的单词:strToken 类别码为: ENDendl;break; case 2:cout需检测的的单词:strToken 类别码为: IFendl;break; case 3:cout需检测的的单词:strToken 类别码为: THENendl;break; case 4:cout需检测的的单词:strT

23、oken 类别码为: ELSEendl;break; default: cout需检测的的单词:strToken 类别码为: IDendl;break; else if(IsDigit() while(IsDigit()|ch=.) Concat(); GetChar(); Retract(); cout需检测的的单词:strToken 类别码为: INTendl; else switch (ch) case +: cout需检测的的单词:+ 类别码为: PLendl;break; case-: cout需检测的的单词:- 类别码为: MIendl;break; case*: cout需检测的

24、的单词:* 类别码为: MUendl;break; case/: cout需检测的的单词:/ 类别码为: DIendl;break; case:GetChar(); if(ch=) cout需检测的的单词:= 类别码为: ISendl;break; else Retract(); cout需检测的的单词为非法输入!endl;break; case=:cout需检测的的单词:= 类别码为: EQ:GetChar();switch(ch) case=: cout= 类别码为: GEendl;break; default:Retract(); cout 类别码为: GTendl;break; cas

25、e:GetChar(); switch(ch) case=:cout需检测的的单词:= 类别码为: LE:cout需检测的的单词: 类别码为: NEendl;break; default:Retract(); cout需检测的的单词: 类别码为: LTendl;break; while(kq) for(int p=0;p50;p+) strTokenp=0; i=0; analyze(); void main() cout请输入一段程序,以#号结束:endl; form0=cin.get(); for( q=1;formq-1!=#;q+) formq=cin.get(); if(formq=

26、#) cout你输入的程序段为n; cout.write(form,q); break; coutE(自己添加的)E-E+T| E-T|TT-T*F| T/F|FF-(E)|i该表1是根据下一页的图画出来的:+-*/()i#E T F0S4S51231S6S7acc2R3S8S9R3R33R6R6R6R6R6R64S4S510235R8R8R8R8R8R86S4S51137S4S51238S4S5139S4S51410S6S7S1511R1R1S8S9R1R112R2R2S8S9R2R213R4R4R4R4R4R414R5R5R5R5R5R515R7R7R7R7R7R7表1(2)对实验一得字符

27、串1.5E+2+100*555进行验证:经过自己的推理所得的表2步骤状态栈符号栈输入串ACTIONGOTO10#i+i*iS5205#i+i*i#R8GOTO0,F=3303#F+i*i#R6GOTO0,T=2402#T+i*i#R3GOTO0,E=1501#E+i*i#S66016#E+i*i#S570165#E+i*i#R8GOTO0,F=380163#E+F*i#R6GOTO0,T=290162#E+T*i#S81001628#E+T*i#S511016285#E+T*i#R8GOTO0,F=312016283#E+T*F#R6GOTO0,T=21301611#E+T#R1GOTO0,E

28、=11401#E#acc成功!表2程序设计:(1)设置输入缓冲区用结构buf实现输入字符的存储,包括值和类型的存储(为实验三做准备),为后续的语法分析和词法分析做准备(2)状态栈state 作为状态栈,存储归约和移进过程状态的变化(3)符号栈Symbol作为符号栈,栈顶的符号不断地进行着归约和移进的动作(4)运用c语言编写了相应的程序进行移近和归约以及接受的动作,需要注意的是,在规约的过程中不仅需要弹出数目确定的字符,还要有相应的字符入栈注意:在实验设计过程中,从读取存有算数字符的文件开始,就获得了每一个算术表达式的字符个数(除去”-”的剩余部分)并存储在数组VNum中三、 源程序代码实验代码

29、部分将会在实验三给出四、 实验结果见实验三实验三 语义分析程序实现李晓萌 088330一、实验内容:通过设计、编制、调试一个简单的语义处理分析程序,实现对实验一和实验二所得单词和语句的语义信息简单处里,进一步掌握语义处理的内容和简单方法。二、设计部分(1)需要将实验一的1.5E+2+100*555中的每一个无符号数相应的算出最终的结果:如:1500.000000+2.000000+100.000000*555.000000(2)在进行归约的过程中,不仅仅是弹出需要进行归约的字符,还要进行值的传递和计算计算(3)设计思路:1 Calculate_UnsignedFigure(char *p1,c

30、har *p2) 函数能过准确的计算出无符号的值2 Quarternary_Out(int a1,double a2,double a3,double a4)语义分析四元式输出3 Store_ResuctionMAX在语法分析的过程中,把归约过程都标记在这个数组中& UnsignedFigure在计算的过程中也已经把相应的算数字符的值存储在这个数组4调用相应的归约过程,利用UnsignedFigure存储的值进行计算,最后获得运算结果结果可以对实验二得标进一步完善步骤状态栈符号栈输入串ACTIONGOTO语义处理生成中间代码10#i+i*iS5205#i+i*i#R8GOTO0,F=3i1.value=1500.000000303#F+i*i#R6GOTO0,T=2F1.value=1500.000000402#T+i*i#R3GOTO0,E=1T1.value=1500.000000501#E+i*i#S6E1.value=1500.0000006016#E+i*i#S570165#E+i*i#R8GOTO0,F=3i2.value=100.00000080163#E+F*i#R6GOTO0,T=2F2.value=100.00000090162#E+T*i#S8T2.value=100.0000001001628#

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号