1、实验3识别无符号数的词法分析器设计实现c 汇总实验三 识别无符号数的词法分析器程序设计一、实验目的与要求通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将源程序分解成各类单词的词法分析方法。二、实验重难点DFA无符号数的词法分析器编码实现三、实验内容与要求1. 阅读实验案例,明确实验要求和程序实现方案;2. 参考实验案例,完善该无符号数的词法分析器设计程序。四、实验学时2课时五、实验设备与环境C语言编译环境六、实验案例1. 无符号数的词法分析器原理(1)正规式表示:Unsigned digital: ddddESdd, it includes four reg
2、ular expressions: dd* 如:5 56 567 d*.dd* 如:.5 5.6 5.67 d*ESdd* 如:E5 E+56 5E-67 d*.dd*ESdd* 如:.5E5 5.65E+56 5.4E-67while VT=0, ,9, ,+,-,E d =0|1| |9 S = +|-|(2)NFA表示:(3)经过NFA转DFA和DFA的化简后得到无符号数的DFA表示:2.设计要求选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。输入:由无符号数和+,*,/, ( , ) 构成的算术表达式,如1.5E+2100。输出:对识别出的每一单词均单行
3、输出其类别码。单词符号类别码(CLASS)单词值(VALUE)无符号数1数字值+2+-3-*4*/5/(6()7) 如1 (对应1.5E+2)3 (对应-)1 (对应100)3、程序源代码:4、运行结果:测试用例1:0.23E-12-E12结论:(1)案例中的程序只给出了A到BC及其后续通路的程序,没有给出A到D及其后续通路的程序。因此不能识别E12是一个无符号数。测试用例2:0.23E*12/a(0.23E-12) 结论:(2)案例中的程序只给出了若输入的字符串符合无符号数的DFA语法规则,将该无符号数识别出来,并没有给出当输入的字符串不符合无符号数的DFA语法规则时,如何处理。请将案例程序
4、按下表规则补充完整。错误提示有两层含义,一个是输入字符不属于输入字母表,一个是输入字符正确但不合语法规则,这两种错误都应该予以检测并给出相应的处理。但案例程序只检测了第一种错误。七、无符号数的词法分析器设计的完善1. 设计要求,对案例程序的BUG进行完善:(1)案例中的程序只给出了A到BC及其后续通路的程序,没有给出A到D及其后续通路的程序,请将A到D及其后续通路的程序给出。(2)案例中只给出了若输入的字符串符合无符号数的DFA语法规则,将该无符号数识别出来,并没有给出当输入的字符串不符合无符号数的DFA语法规则时如何处理。请将案例程序按下表规则补充完整。注意:3个非终态都应该给出相应的判断。
5、单词符号类别码(CLASS)单词值(VALUE)无符号数1数字值+2无值-3无值*4无值/5无值(6无值)7无值非法的字符串8该非法的字符串2. 词法分析程序(c+语言版,保持良好的缩进关系,主函数不能改,只能改AssortIdentify()、Output()函数等相应的函数):#includeusing namespace std;#define M 101 /最多可输入的字符数#define UNSIGNEDNUMBER 1 /无符号数#define PLUS 2 /加号#define SUBTRACT 3 /减号#define MULTIPLY 4 /乘号#define DIVIDE
6、5 /除号#define LEFTBRACKET 6 /左括号#define RIGHTBRACKET 7 /右括号#define ILLEGAL 8 /非法的字符串 class AccidenceAnalysis /定义词法分析器类 private: char testStrM,*p; /私有数据 public: AccidenceAnalysis(); /构造函数,功能一般是对类做初始化 void InputStr(); /输入函数 void Output(int a,char *p1,char *p2); /输出函数 int IsAcceptantCharacter(char *p);
7、/判断输入字符是否属于字符集 int IsOperator(char *p); /判断字符是否是字符集+,-,*,/,(,)中的字符 int IsUnsignedNum(char *p); /判断字符是否是0-9的整数 void AbnormityExamine(char a); /异常检测函数 void IdentifyOperator(char *p);/识别字符集+,-,*,/,(,)中的字符 void AssortIdentify(); /对输入字符分类识别;AccidenceAnalysis:AccidenceAnalysis() int i; for(i=0;iM;i+) test
8、Stri=0;/ 0是C+中字符串的结尾标志,存储在字符串的结尾。 p=&testStr0; /指针P指向字符数组首元素void AccidenceAnalysis:InputStr() coutt请按要求输入您要分析的语句,所输字符应在要求范围(不超过M)之内,并按回车键运行:; char ch; int i=0; while(ch=cin.get()!=n) / cin.get()是保留回车在输入流队列中的.而cin是丢弃回车的. testStri=ch; i+; AbnormityExamine(testStr);void AccidenceAnalysis:AbnormityExami
9、ne(char a) int j=0; char *ptr1,*ptr2; ptr1=a;/指向字符串数组a ptr2=a; while(*ptr2!=0) j+; if(!IsAcceptantCharacter(ptr2) coutt您输入的第j个字符 *ptr2 不可以被此程序识别! 将被跳过.endl; ptr2+; continue; /结束本次循环,继续下次循环,并且进行条件判断; else *ptr1=*ptr2; ptr1+; ptr2+; while(ptr1=ptr2) *ptr1=0; ptr1+; void AccidenceAnalysis:Output(int a,
10、char *p1,char *p2) if(a!=ILLEGAL) coutt类别码:a 单词值:; while(p1=p2) cout*p1; p1+; else coutt类别码:a非法的字符串:; while(p1=p2) cout*p1; p1+; coutendl; int AccidenceAnalysis:IsOperator(char *p) char ch=*p; if(ch=+|ch=-|ch=*|ch=/|ch=(|ch=) return 1; else return 0;int AccidenceAnalysis:IsUnsignedNum(char *p) char
11、ch=*p; if(0=ch&ch=9) return 1; else return 0;int AccidenceAnalysis:IsAcceptantCharacter(char *p) char ch=*p; if(IsOperator(p)|IsUnsignedNum(p)|ch=E|ch=.) return 1; else return 0;void AccidenceAnalysis:IdentifyOperator(char *p) char ch=*p; switch(ch) case +: Output(PLUS,p,p);break; case -: Output(SUB
12、TRACT,p,p);break; case *: Output(MULTIPLY,p,p);break; case /: Output(DIVIDE,p,p);break; case (: Output(LEFTBRACKET,p,p);break; case ): Output(RIGHTBRACKET,p,p);break; default: break; void AccidenceAnalysis:AssortIdentify() while(*p!=0) /从DFA的初始状态出发进行分类识别 if(IsOperator(p)/情况1:从状态A出发,判断输入是否为符号,如果是,则不是
13、无符号数,而是运算符,调用运算符识别函数IdentifyOperator(char *p)识别运算符。 IdentifyOperator(p+); continue; else if(IsUnsignedNum(p)|*p=.)/情况2:从状态A出发,判断输入是否为为数字或者. char *p1=p; /拼数,从指针p1到指针p之间的所有的字符串 if(IsUnsignedNum(p) /情况2.1:从状态A出发,如果输入为数字,到达状态B while(IsUnsignedNum(p) /情况2.1.1:B之后如果输入为数字,且后面都是数字,则到达终态B,可以判定为无符号数。 p+; if(*
14、p=0) Output(UNSIGNEDNUMBER,p1,-p); /拼数,从指针p1到指针p之间的所有的字符串 p+; continue; else if(*p=E) /情况2.1.2:B之后如果输入E,到达状态D,需要进一步判断。 / char*p1=p; p+; if(*p1=+|*p=-) if(IsUnsignedNum(p)/情况2.1.2.1:D之后如果输入d、+、-,且后面一直都是输入d,则到达终态F,可以判断是无符号数。(因为s为+、-、 ) while(IsUnsignedNum(p) p+; Output(UNSIGNEDNUMBER,p1,-p); p+; conti
15、nue; else if(*p=+|*p=-) p+; while(IsUnsignedNum(p) p+; Output(UNSIGNEDNUMBER,p1,-p); p+; continue; else p+; Output(ILLEGAL,p1,-p); p+; continue; / else if(*p=.) /情况2.2.3:从状态B出发,如果输入为.,到达状态C。 p+; while(IsUnsignedNum(p) /情况2.2.3.1:从状态C出发,如果输入为d,到达状态E p+; if(*p=0) /情况2.2.3.1.1:如果遇到字符串结束标志,到达终态E,可以判断为无符
16、号数 Output(UNSIGNEDNUMBER,p1,-p); p+; continue; else if(*p=E) /情况2.2.3.1.2:从状态E出发,如果输入E,到达状态D,重复刚才状态D之后的判断。 (D之后如果输入d、+、-,且后面一直都是输入d,则到达终态F,可以判断是无符号数。(因为s为+、-、 ) / char*p1=p; p+; if(*p1=+|*p=-) if(IsUnsignedNum(p) while(IsUnsignedNum(p) p+; Output(UNSIGNEDNUMBER,p1,-p); p+; continue; else if(*p=+|*p=
17、-) p+; while(IsUnsignedNum(p) p+; Output(UNSIGNEDNUMBER,p1,-p); p+; continue; else p+; Output(ILLEGAL,p1,-p); p+; continue; / if(*p=.) /情况2.2:从状态A出发,如果输入为.。,到达状态C p+; if(IsUnsignedNum(p) /情况2.2.1: C到E p+; while(IsUnsignedNum(p) p+; if(*p=0) /情况2.2.1.1: C到E后到终态 Output(UNSIGNEDNUMBER,p1,-p); p+; conti
18、nue; else if(*p=E) /情况2.2.1.2: E到D p+; if(IsUnsignedNum(p) /情况2.2.1.2: D到H while(IsUnsignedNum(p) p+; Output(UNSIGNEDNUMBER,p1,-p); p+; continue; else if(*p=+|*p=-) /情况2.2.1.2: D到F p+; while(IsUnsignedNum(p) /情况2.2.1.2: F到H p+; Output(UNSIGNEDNUMBER,p1,-p); p+; continue; / else if(*p=E)/情况2.1.2:B之后如
19、果输入E,到达状态D,需要进一步判断。 char*p1=p; p+; if(*p1=+|*p=-) if(IsUnsignedNum(p) while(IsUnsignedNum(p) p+; Output(UNSIGNEDNUMBER,p1,-p); p+; continue; else if(*p=+|*p=-) p+; while(IsUnsignedNum(p) p+; Output(UNSIGNEDNUMBER,p1,-p); p+; continue; else p+; Output(ILLEGAL,p1,-p); p+; continue; / coutendl; coutt单词
20、分析完毕.endl;int main() AccidenceAnalysis accidenceanalysis; accidenceanalysis.InputStr(); accidenceanalysis.AssortIdentify(); return 0; 3. 测试数据及运行结果(可截图):截图上要有自己的姓名学号信息测试用例1运行截图:0.23E-12-E12测试用例2运行截图:0.23E*12/a(0.23E-12) E*5 0.23E +*5 .*5 4.实验结果分析与心得体会教师评语:是否完成实验程序的预备设计? 是: 不是:程序能否正常运行? 是: 不是:有无测试数据及结果分析 是: 不是:是否在本次规定时间完成所有项目? 是: 不是:实验成绩等级:教师签名:N0: 时间: