收藏 分享(赏)

东南大学 编译原理 词法分析器实验报告.doc

上传人:精品资料 文档编号:10399024 上传时间:2019-11-07 格式:DOC 页数:11 大小:515.91KB
下载 相关 举报
东南大学 编译原理 词法分析器实验报告.doc_第1页
第1页 / 共11页
东南大学 编译原理 词法分析器实验报告.doc_第2页
第2页 / 共11页
东南大学 编译原理 词法分析器实验报告.doc_第3页
第3页 / 共11页
东南大学 编译原理 词法分析器实验报告.doc_第4页
第4页 / 共11页
东南大学 编译原理 词法分析器实验报告.doc_第5页
第5页 / 共11页
点击查看更多>>
资源描述

1、词法分析设计1. 实验目的 通过本实验的编程实践,了解词法分析的任务,掌握词法分析程序设计的原理和构造方法,对编译的基本概念、原理和方法有完整的和清楚的理解,并能正确地、熟练地运用。2. 实验内容 用 C+语言实现对 C+语言子集的源程序进行词法分析。通过输入源程序从左到右对字符串进行扫描和分解,依次输出各个单词的内部编码及单词符号自身值;若遇到错误则显示“Error” ,然后跳过错误部分继续显示 ;同时进行标识符登记符号表的管理。 3. 实验原理本次实验采用 NFA-DFA-DFA0 的过程:对待分析的简单的词法(关键词/id/num/运算符/空白符等)先分别建立自己的 FA,然后将他们用

2、产生式连接起来并设置一个唯一的开始符,终结符不合并。待分析的简单的词法(1)关键字:“asm“,“auto“,“bool“,“break“,“case“,“catch“,“char“,“class“,“const“,“const_cast“等(2)界符(查表)“;“,“,“,“(“,“)“,“,“,“,“(3)运算符“*“,“/“,“%“,“+“,“-“,“,“ string type; int attr; ; (2)本文的大多数数据结构都用 map来保存,优点是查找方便,大大提高时间复杂度。 map Keywords; /保存关键字 map Sep; /保存界符map Relop; /保存比

3、较运算符map Op; /保存其他运算符mapid; /保存输入字符串中的 idmapnum; /保存数字vectorToken; /保存 token序列,大小未知,所以采用 vector保存6. 核心算法描述(1)void addToken(string s,int type)s 为找到的字符串,type 为可能类型。 将分析出来的 token()序列添加到 Token 序列表中。如果是类型为 1,查看关键词表,若找到,其类型为关键词并将其以类型为关键词存储到 Token 表中;若未找到,则查找 id表,若找到,说明该 id 已经出现过,否则添加新的 id 到 id 表中,将该 i 字符串以

4、类型为id 添加到 Token 表中。如果类型为 2,在界符表中查找,如果找到以类型为界符存储到Token 表中,同理其他几种类型。可能类型为 1-5,如果出现其他类型表示是词法分析器中发现额错误,将错误信息记录下来。void addToken(string s,int type) switch(type)case 1: l_it=Keywords.find(s); if (l_it!=Keywords.end() token t=s,“keywords“,l_it-second; Token.push_back(t); elsel_it=id.find(s); if (l_it=id.end

5、() ids=idNum; token t=s,“id“,idNum+; Token.push_back(t); else token t=s,“id“,l_it-second; Token.push_back(t); break;case 2:l_it=Sep.find(s); if (l_it!=Sep.end() token t=s,“separatrix“,l_it-second; Token.push_back(t); break;case 3:l_it=Op.find(s); if (l_it!=Op.end() token t=s,“op“,l_it-second; Token.

6、push_back(t); break;case 4:l_it=Relop.find(s); if (l_it!=Relop.end() token t=s,“relop“,l_it-second; Token.push_back(t); break;case 5: l_it=num.find(s); if (l_it=num.end() nums=nNum; token t=s,“num“,nNum+; Token.push_back(t); else token t=s,“num“,l_it-second; Token.push_back(t); break; default: /erro

7、r token t=s,“id“,-1; Token.push_back(t); break; (2)void lexical() 词法分析器,按字符读入文法并对其进行处理。从状态 0开始处理,如果是空白符则一直在状态 0,如果第一个字符为字母,继续往后寻找,直至不是字母或是数字结束;若第一个字符为数字,将其拼凑成一个数字,数字可以有小数点等,详细见状态转换图,注意以数字开头容易出现一种例如 3a类型的错误,所以以数字开头的一定要往下多找一个,看最后一个数字后面是否为空白符或界符或者其他允许出现的符号,如果后面紧跟着字母则报错。如上同理分析运算符等。注意每次处理完遇到一个字符串都要将其送到 a

8、ddToken()添加到Token表中并回到状态 0,继续往下处理。void lexical()fstream ln(“E:ln.txt“); char ch,tempch; int state=0; string s=“,key=“; while(!ln.eof() switch(state) case 0: ch=ln.get(); s=ch; if (ch=13|ch=10|ch=32|ch=9) state=0; s=“; else if (ch=) state=9;else if (isLetter(ch) state=13;else if (isDigit(ch) state=15

9、; else if (ch=+|ch=-|ch=*|ch=/|ch= tempch=ch; else if (ch=) state=44; else if (isSep(ch)!=-1) state=47;else if (isOp(s)!=-1) state=48; else if (isRelop(s)!=-1) state=49; else state=50; /error break; case 1: ch=ln.get(); if(ch=|ch=) state=2; else if(ch=) state=11; else state=12; break;case 10: s+=ch;

10、 addToken(s,4); state=0;break;case 11:s+=ch;addToken(s,3); state=0; break; case 12: /* state=0;addToken(s,4); ln.seekg(-1,ios:cur); break;case 13: ch=ln.get(); if(isDigit(ch)|isLetter(ch) s+=ch; else state=14; break; case 14: /* state=0;addToken(s,1); ln.seekg(-1,ios:cur);break;case 15: ch=ln.get();

11、 if (isDigit(ch) s+=ch; else if (ch=.)s+=ch; state=16; else state=18; break; case 16: ch=ln.get(); s+=ch;if (isDigit(ch) state=17; else state=50; /error break;case 17: ch=ln.get(); if (isDigit(ch) s+=ch; state=17; else state=18; break; case 18: /* if (isLetter(ch) s+=ch; state=50; elseaddToken(s,5);

12、 ln.seekg(-1,ios:cur); state=0; break;case 20: ch=ln.get(); if(ch=tempch|ch=) state=21; else state=23; break;case 21: s+=ch; addToken(s,3); state=0; break; case 23:addToken(s,3); ln.seekg(-1,ios:cur); state=0; break; case 44: ch=ln.get(); if (ch=) state=45; else state=46; break;case 45: s+=ch; addTo

13、ken(s,3); break; case 46:addToken(s,3); ln.seekg(-1,ios:cur); break;case 47:addToken(s,2); state=0; break; case 48:addToken(s,3); state=0;break; case 49: addToken(s,4); state=0; break; case 50: /error while(ch=ln.get()!=EOF) if(isSep(ch)!=-1|ch=13|ch=10|ch=32|ch=9) break; else s+=ch; addToken(s,6);

14、/error ln.seekg(-1,ios:cur); state=0; break;default: break; 7. 测试用例待测字符串:void fun() int a=2,b=3,3a; a+;b-; a+=b; b*=a; int c=a+4; int d=b*5; 产生结果在 out.txt 中(注意,无论输入输出文件都要保存在 E 盘根目录下) 8. 出现的问题与解决方案本实验的难点就是进行有效地进行状态如转换,先对每一个简单部分,如空白符、id、digit 等画出自动机状态,然后由 NFA-DFA,添加一个唯一的初始状态, 产生式连接。再将 DFA 中等价的状态合并最后变成 DFA0。这样便大大简化了代码量,也使得逻辑思维更加清晰。 9. 自我体会将理论运用到实际,不仅可以帮我们更好地复习理论知识,还可以让我们发发掘到一些更深刻层面上的东西。通过本次实验,我深入了解了词法分析的过程,对 NFA,DFA,DFA0之间的转换也更能更加熟练地运用。这次实验还有许多需要加强的地方,比如还可以对 id的类型进行明确分类,是函数还是变量,是什么类型的,返回类型是什么等等。之后有机会的话,我一定会更加深入的研究,将这个实验更加完善。

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

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报