您的当前位置:首页正文

实验3__识别无符号数的词法分析器设计实现c++

2023-01-23 来源:钮旅网
 班级:

学号: 姓名:

实验三 识别无符号数的词法分析器程序设计

一、实验目的与要求

通过编写并上机调试一个词法分析程序,掌握在对程序设计语言的源程序进行扫描的过程中,将源程序分解成各类单词的词法分析方法。 二、实验重难点

DFA无符号数的词法分析器编码实现 三、实验内容与要求

1. 阅读实验案例,明确实验要求和程序实现方案; 2. 参考实验案例,完善该无符号数的词法分析器设计程序。 四、实验学时

2课时

五、实验设备与环境 C语言编译环境

六、实验案例

1. 无符号数的词法分析器原理

(1)正规式表示:Unsigned digital: d…d…d…dESd…d, it includes four regular 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-67 while

VT={0, ···,9, ·,+,-,E} d =0|1| ···|9 S = +|-|ε

(2)NFA表示:

(3)经过NFA转DFA和DFA的化简后得到无符号数的DFA表示:

班级:

学号: 姓名:

2.设计要求

选取无符号数的算术四则运算中的各类单词为识别对象,要求将其中的各个单词识别出来。

输入:由无符号数和+,-,*,/, ( , ) 构成的算术表达式,如1.5E+2-100。 输出:对识别出的每一单词均单行输出其类别码。 单词符号 无符号数 + - * / ( ) 如1 (对应1.5E+2)

3 (对应-) 1 (对应100) 3、程序源代码:

类别码(CLASS) 1 2 3 4 5 6 7 单词值(VALUE) 数字值 + - * / ( ) 1.cpp

4、运行结果:

测试用例1:0.23E-12-E12

结论:(1)案例中的程序只给出了A到B\\C及其后续通路的程序,没有给出A到D及其后续通路的程序。因此不能识别E12是一个无符号数。 测试用例2:0.23E*12/a(0.23E-12)

班级:

学号: 姓名:

结论:(2)案例中的程序只给出了若输入的字符串符合无符号数的DFA语法规则,将该无符号数识别出来,并没有给出当输入的字符串不符合无符号数的DFA语法规则时,如何处理。请将案例程序按下表规则补充完整。

错误提示有两层含义,一个是输入字符不属于输入字母表,一个是输入字符正确但不合语法规则,这两种错误都应该予以检测并给出相应的处理。但案例程序只检测了第一种错误。 七、无符号数的词法分析器设计的完善

1. 设计要求,对案例程序的BUG进行完善:

(1)案例中的程序只给出了A到B\\C及其后续通路的程序,没有给出A到D及其后续通路的程序,请将A到D及其后续通路的程序给出。

(2)案例中只给出了若输入的字符串符合无符号数的DFA语法规则,将该无符号数识别出来,并没有给出当输入的字符串不符合无符号数的DFA语法规则时如何处理。请将案例程序按下表规则补充完整。注意:3个非终态都应该给出相应的判断。 单词符号 无符号数 + - * / ( ) 非法的字符串 类别码(CLASS) 1 2 3 4 5 6 7 8 单词值(VALUE) 数字值 无值 无值 无值 无值 无值 无值 该非法的字符串 2. 词法分析程序(c++语言版,保持良好的缩进关系,主函数不能改,只能改AssortIdentify()、Output()函数等相应的函数): #include using namespace std;

#define M 101 //最多可输入的字符数 #define UNSIGNEDNUMBER 1 //无符号数 #define PLUS 2 //加号 #define SUBTRACT 3 //减号 #define MULTIPLY 4 //乘号 #define DIVIDE 5 //除号 #define LEFTBRACKET 6 //左括号 #define RIGHTBRACKET 7 //右括号

#define ILLEGAL 8 //非法的字符串

班级:

学号: 姓名:

class AccidenceAnalysis //定义词法分析器类 {

private:

char testStr[M],*p; //私有数据 public:

AccidenceAnalysis(); //构造函数,功能一般是对类做初始化 void InputStr(); //输入函数

void Output(int a,char *p1,char *p2); //输出函数

int IsAcceptantCharacter(char *p); //判断输入字符是否属于字符集 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;itestStr[i]='\\0';// \\0是C++中字符串的结尾标志,存储在字符串的结尾。 p=&testStr[0]; //指针P指向字符数组首元素 }

void AccidenceAnalysis::InputStr() {

cout<<\"\请按要求输入您要分析的语句,所输字符应在要求范围(不超过\"<while((ch=cin.get())!='\\n') // cin.get()是保留回车在输入流队列中的.而cin是丢弃回车的. {

testStr[i]=ch; i++; }

AbnormityExamine(testStr); }

void AccidenceAnalysis::AbnormityExamine(char a[]) {

int j=0;

char *ptr1,*ptr2;

ptr1=a;//指向字符串数组a ptr2=a;

while(*ptr2!='\\0') {

班级:

学号: 姓名:

j++;

if(!IsAcceptantCharacter(ptr2)) {

cout<<\"\您输入的第\"<continue; //结束本次循环,继续下次循环,并且进行条件判断; } else {

*ptr1=*ptr2; ptr1++; ptr2++; } }

while(ptr1<=ptr2) {

*ptr1='\\0'; ptr1++; } }

void AccidenceAnalysis::Output(int a,char *p1,char *p2) { if(a!=ILLEGAL){

cout<<\"\类别码:\"<cout<<*p1; p1++; } } else{

cout<<\"\类别码:\"<cout<<*p1; p1++; }

cout<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 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(SUBTRACT,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出发,判断输入是否为符号,如果是,则不是无符号数,而是运算符,调用运算符识别函数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(*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++;

continue; }

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,可以判断为无符号数 {

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=='-') {

班级:

学号: 姓名:

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++;

continue; }

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之后如果输入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; } }

//////////////////////////////////////

班级:

学号: 姓名:

}

cout<cout<<\"\单词分析完毕.\"<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:

时间:

因篇幅问题不能全部显示,请点此查看更多更全内容