编译原理词法分析报告_第1页
编译原理词法分析报告_第2页
编译原理词法分析报告_第3页
编译原理词法分析报告_第4页
编译原理词法分析报告_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

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

文档简介

1、精选优质文档-倾情为你奉上 年 月 日专心-专注-专业1、 实验目的1、为初等函数运算语言构造词法分析器。2、掌握生成词法分析器的方法,加深对词法分析原理的理解。3、掌握设计、编制并调试词法分析程序的思想和方法2、实验内容一、根据下面的要求设计初等函数运算语言的词法模式,并用正则式表达出来1、 初等函数运算语言的常量为实数类型,其定义方式为实数的最一般书写方式,如:123.321。具体要求:不支持整数部分大于0时首数字为0;不支持小数点后结尾为0;不支持科学记数法;不支持仅为整数时有小数点;支持负数符号,不支持正数符号。2、 初等函数运算语言的变量采用与C语言的标识符定义一样的方式:首字符为字

2、母或下划线;其他的为字母、数字及下划线的混合串;区分大小写;变量长度不超过32个字符。3、 初等函数运算语言需要处理的函数仅为表一中所列举的内容。函数的格式及参数内容也如表一所示。4、 初等函数运算语言支持四则运算,其计算的符号与C语言相同,为:+-*/。5、 初等函数运算语言的合法的分隔符包括:空格、制表符、分行符圆括号(左、右)、分号。其中空格、制表符、分行符可以出现在任何两个不同的单词中间;圆括号(左、右)用于表达式中,用于改变运算的优先级,以及标识函数的参数;分号用于标识一个语句的结束。6、 初等函数运算语言支持的常量还包括:PI,E。其中,PI为圆周率,E为自然常数。二、将正则式转化

3、为最小DFA,给出该DFA的形式化表示和图形表示。三、根据DFA给出状态转换表。四、给出初等函数运算语言的记号表,即词法分析中,语言中的记号将分为多少类,每一类型的编码、类型、属性等内容是什么。五、编写词法分析器,将输入的字符串转化成为记号流,便于后续的语法分析工作。要求词法分析器中能够识别词法错误。2.1词法模式设计/正则式分隔符:compart=t|n|(|)|;|空格运算符:operation=+|-|*|/|=|变量:variable=azAZ( azAZ_09)*常量:constant=(|-)(0|(19)(09)*)(.(09)*(19)|)|PI|E2.2DFA注:id表示字母

4、,num表示数字2.3状态转换表id01-9下划线减号小数点01341281111198283488838888964844896686788878678988888888注:0是初态,2,6是中间状态,1,3,4,7是终态,其中1表示标示符,3,4,7是实数,8表示不合法的状态,9表示'-'为减号2.4记号表符号SinCostgctgloglgln();?+记号01234567891011符号-*/=常量变量无法识别的标示符,记号12131415161718192021223、 实验程序清单#include <iostream>#include<string

5、>using namespace std;#define max 10 char ch =' 'string key7="sin","cos","tg","ctg","log","lg","ln"/关键字char compart6='t','n','(',')','',' '/分隔符char operation5='+',&

6、#39;-','*','/','='/运算符/int s8=0,1,2,3,4,6,7,8;/状态集合,0是初态,2,6是中间状态,1,3,4,7是终态, 其中1表示标示符,3,4,7是实数,8表示不合法的状态 int token23=0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22;/0表示sin,1表示cos,2表示tg,3表示ctg,4表示log,5表示lg,6表示ln,7表示(,8表示),9表示;,10表示?,11表示+,12表示-,13表示*,14表示/,15表

7、示=,/16表示常量,17表示变量,18表示不可识别标示符,19表示,20表示逗号,21表示,22表示char arr32; int state=0;int s=0;bool tag=0;/tag=0表示'-'为负数的负号,tag=1表示'-'为减号FILE *fp;int IsKey(string c) /判断是否为关键字 for(int i=0;i<7;i+) if(pare(c)=0) return i;/返回下标,下标和其token记号一致 return -1;bool IsLetter(char c) /判断是否为字母 if(c&

8、lt;='z')&&(c>='a')|(c<='Z')&&(c>='A') return 1; else return 0;bool IsNum(char c) /判断是否为1-9的数字 if(c>='1'&&c<='9') return 1; else return 0;bool IsUnderline(char c) /判断是否为下划线if(c='_')return 1;elsereturn 0;voi

9、d move(char ch,int s)/在状态s接收字符ch后,移动的新状态/arr=arr+ch;switch(s)case 0:if(ch='_'|IsLetter(ch) state= 1;else if(ch='0')state=3;elseif(IsNum(ch)state=4;elseif(ch='-')state=2;elsestate=8;break;case 1:if(IsNum(ch)|ch='_'|IsLetter(ch)|ch='0')state=1;elseif(ch='-&#

10、39;) state=9;elsestate=8;break;case 2:if(ch='0')state=3;elseif(IsNum(ch)state=4;elsestate=8;break;case 3:if(ch='.')state=6;elseif(ch='-') state=9;elsestate=8;break;case 4: if(IsNum(ch)|ch='0')state=4;elseif(ch='-') state=9;elseif(ch='.') state=6;else s

11、tate=8;break;case 6: if(ch='0') state=6; else if(IsNum(ch) state=7; else state=8; break; case 7: if(ch='0') state=6; else if(IsNum(ch) state=7; else if(ch='-') state=9;elsestate=8; break; case 8: if(ch='-') state=9; else state=8; break;/switchvoid judge(char arr)if(s=

12、3|s=4|s=7)cout<<"("<<arr<<" "<<token16<<")"<<endl; /常量else if(s=1) if(!strcmp(arr,"PI")|!strcmp(arr,"E")cout<<"("<<arr<<" "<<token16<<")"<<endl; /常量

13、 else if(IsKey(arr)=-1) cout<<"("<<arr<<" "<<token17<<")"<<endl; /普通标示符 else cout<<"("<<arr<<" "<<IsKey(arr)<<")"<<endl; /关键字 elseif(s=9)cout<<"("<&l

14、t;arr<<" "<<token12<<")"<<endl;/减号if(s=8) cout<<"("<<arr<<" "<<token18<<")"<<endl; /不可识别标示符标示符 switch(ch) case'+': cout<<"("<<ch<<" "<<tok

15、en11<<")"<<endl;break;/运算符 case'*' : cout<<"("<<ch<<" "<<token13<<")"<<endl;break;/运算符 case'=' : cout<<"("<<ch<<" "<<token15<<")"<<

16、;endl;break;/运算符 case'/' : cout<<"("<<ch<<" "<<token14<<")"<<endl;break;/运算符case'': cout<<"("<<ch<<" "<<token19<<")"<<endl;break;/运算符 case'(' :c

17、out<<"("<<ch<<" "<<token7<<")"<<endl;break;/分隔符 case')' : cout<<"("<<ch<<" "<<token8<<")"<<endl;break;/分隔符 case'' :cout<<"("<<ch&l

18、t;<" "<<token9<<")"<<endl;break;/分隔符 case',' :cout<<"("<<ch<<" "<<token20<<")"<<endl;break;/分隔符 case'' :cout<<"("<<ch<<" "<<token21&l

19、t;<")"<<endl;break;/分隔符 case'' :cout<<"("<<ch<<" "<<token22<<")"<<endl;break;/分隔符case'?':cout<<"("<<ch<<" "<<token10<<")"<<endl;break

20、;/运算开始符case' ':case'/t':case'/n': void analyse(FILE*fp)int i=0;while(ch!='EOF') char arr32='0' while(ch!='('&&ch!=')'&&ch!=' '&&ch!='t'&&ch!='n'&&ch!=''&&ch!='&

21、#39;&&ch!=','&&ch!='?'&&ch!='-'&&ch!=''&&ch!=''&&ch!='+'&&ch!='*'&&ch!='/'&&ch!='='&&ch!='EOF') if (i<32) arri=ch; move(ch,s); s=state; i

22、+; ch=fgetc(fp); /while judge(arr); if(ch='-') char arr32='0' i=0; while(ch!='('&&ch!=')'&&ch!=' '&&ch!='t'&&ch!='n'&&ch!=''&&ch!=''&&ch!=','&&ch!='?

23、9; &&ch!=''&&ch!=''&&ch!='+'&&ch!='*'&&ch!='/'&&ch!='='&&ch!='EOF') move(ch,s); s=state; arri=ch; if(state!=9) i+; ch=fgetc(fp); else /s=9为减号时 char arr32='0' break; /while judge(ar

24、r); s=0; i=0; ch=fgetc(fp); else char arr32='0' ch=fgetc(fp); i=0; s=0; /whilevoid main() char in_fn30; FILE * fp; cout<<"请输入源文件名(包括路径和后缀名):" for(;) cin>>in_fn; if(fp=fopen(in_fn,"r")!=NULL)/意思是文件指针fpin在调用fopen打开文件如果失败,则会成为一个空指针! break; /文件顺利打开后,指向该流的文件指针就会被返回

25、。 else cout<<"文件路径错误!请输入源文件名(包括路径和后缀名):" cout<<"n*分析如下*"<<endl; ch=fgetc(fp); char arr32='0' arr0=ch; / fseek(fp,-1,1); analyse(fp); fclose(fp); cout<<endl; int a; cin>>a;4、 调试过程和运行结果5、 程序的主要部分及其功能说明由DFN得到的状态转换程序:void move(char ch,int s)/在状态s

26、接收字符ch后,移动的新状态switch(s)/状态0时,当接收到字符ch为字母或下划线时状态S转移到状态1,ch为0时转移到状态3,ch为1-9时转移到状态4,ch为-时,转移到状态2,否则转移到状态8case 0:if(ch='_'|IsLetter(ch) state= 1;else if(ch='0')state=3;elseif(IsNum(ch)state=4;elseif(ch='-')state=2;elsestate=8;break;case 1:if(IsNum(ch)|ch='_'|IsLetter(ch)|

27、ch='0')state=1;elseif(ch='-')state=9;elsestate=8;break;case 2:if(ch='0')state=3;elseif(IsNum(ch)state=4;elsestate=8;break;case 3:if(ch='.')state=6;elseif(ch='-')state=9;elsestate=8;break;case 4: if(IsNum(ch)|ch='0')state=4;elseif(ch='-')state=9

28、;elseif(ch='.') state=6;else state=8;break;case 6: if(ch='0') state=6; else if(IsNum(ch) state=7; else state=8; break; case 7: if(ch='0') state=6; else if(IsNum(ch) state=7; else if(ch='-')state=9;elsestate=8; break; case 8:state=8;/switch从文件读字符,并进行词法分析,当读入的字符不为运算符和界符

29、时就往下读,并将读到的字符存入数组arr,当遇到运算符和界符时调用judge(arr)进行分析,输出arr所存字符串及其属性,当遇到-时,需要判断它是表示减号还是表示负数的负号,主要是根据其状态来判断,如果输入-后,若其状态没有调到状态9,则其为负数的负号,否则为减号。主要程序如下: void analyse(FILE*fp)int i=0;while(ch!='EOF') char arr32='0' while(ch!='('&&ch!=')'&&ch!=' '&&ch!='t'&&ch!='n'&&ch!=''&&ch!=''&&ch!=','&&ch!='?'&&ch!='-'&&ch!=''&&ch!=''&&ch!='+'&&ch!='*'&

温馨提示

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

评论

0/150

提交评论