ImageVerifierCode 换一换
格式:DOCX , 页数:33 ,大小:454.56KB ,
资源ID:2009044      下载积分:12 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/2009044.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(hust编译原理实验报告2.docx)为本站会员(b****2)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

hust编译原理实验报告2.docx

1、hust编译原理实验报告2编译原理实验报告院 系 计算机科学与技术 专 业 计算机科学与技术 班 级 CS1101 学 号 姓 名 指导教师 周时阳 2014 年 7月 2日实验一一、问题描述 选择计算机高级程序语言之一 C语言,运用恰当的词法分析技术线路,设计和实现其对应的词法分析器。对C语言的词法按照正则文法或正则式NFADFAmin DFA程序设计;能够跳过程序中的注释和空白、换行符等没有意义的部分;遇到无法确认的符合能够报告错误,然后跳过这个错误,继续分解剩下的部分;分析后的结果存放到磁盘文件中。 二、数据结构及算法设计1、C语言简单词法 (1)关键字:main int char lo

2、ng if else for while void 所有的关键字都是小写。在设计测试程序时所涉及的关键字应该在以上范围内才能被识别,否则将作为标识符处理。 (2)运算符和界符:: = + - * / = = ; ( ) + ! != 上面所包含的运算符与界符不是很全面,因此无法识别一些复杂的运算符,例如&、|、%等。 (3)其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义: ID=letter(letter|digit)* NUM=digit digit* 标识符由字母和数字组成,且首字符必须为字母;这里只对整型常数进行识别,浮点数数据在识别过程中会对小数点进行报错。 (4)空

3、格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM、运算符、界符和关键字,制表符和换行符等都只是对程序起到一个可读性的作用,在词法分析中没有实际意义,因此词法分析阶段通常被忽略。 (5)注释由/*/及其内部内容组成,在词法分析阶段也对程序的分析没有实际意义,因此也要被忽略。 关键字的判定规则是先进行标识符的识别,识别到最终状态后,在关键字数组中查找,看此标识符是否为关键字,如果是则将其划为关键字一类,否则作为标识符。 因此,此正规式的主要分析在标识符ID中会详细分析,在分析完后只要通过一个strcmp函数就可以分辨出是否关键字。2、标识符与运算符 各种单词符号对应的种别码单词种别是语法

4、分析需要的信息,而单词自身的值则是编译其他阶段需要的信息。因此词法分析器的输出结果表示为:(单词种别,单词自身的值)单词的种别采用整数编码表示,下面给出了词法分析器的各个单词符号的种别码。 Start:1If:2Then:3Int:4While:5Do:6For:7End:8字母:10数字:11*:13/:14+:15-:16:17:20:23=:25;:26(:27):28!:02.1标识符ID:标识符ID的正则式表示如下: ID= letter (letter| digit)* letter= az digit= 09 根据以上正则式画出NFA如下图。 图 1 ID的NFA表示下面将这个N

5、FA转换为DFA。利用子集构造法,构造上述NFA的DFA步骤如下: (1)首先计算closure(1),令0= closure(1)=1,0未被标记,它现在是子集族C的唯一成员。 (2)标记0;令1= closure(move(0,letter)=2,3,4,6,9,将1加入到C中,1未被标记。令2= closure(move(0,digit)=,不再计算。 (3)标记1;计算3= closure(move(1,letter)=3,4,5,6,8,9,将3加入到C中,它未被标记。计算4= closure(move(1,digit)=3,4,6,7,8,9,将4加入到C中,它未被标记。 (4)标

6、记3;计算closure(move(3,letter)=3,4,5,6,8,9,即3,它已经在C中了。计算 closure(move(3,digit)=3,4,6,7,8,9,即4,它已经在C中了。 (5)标记4;计算closure(move(4,letter)=3,4,5,6,8,9,即3,它已经在C中了。计算 closure(move(4,digit)=3,4,6,7,8,9,即4,它已经在C中了。 至此,算法终止共构造了4个子集: 0=1 1=2,3,4,6,9 3=3,4,5,6,8,9 4=3,4,6,7,8,9 那么上述NFA构造的DFA为: (1)S=0,1,3,4 (2)=le

7、tter, digit (3)D(0,letter)=1 D(1,letter)=3 D(1,digit)=4 D(3,letter)=3 D(3,digit)=4 D(4,letter)=3 D(4,digit)=4 (4)0=0 (5)=4 为了方便书写,将0,1,3,4分别重命名为A,B,C,D。则重新得到的DFA如下图所示。 图 2 ID的DFA表示上面的DFA并不是最小DFA,如果要转换为最小DFA,则只需将B与D状态合并即可。参考如下。 图 3 ID的mDFA根据DFA进行辨别标识符的程序设计,算法分析如下: (1)得到第一个首单词,确定为字母,记下当前位置为初始位置; (2)向后

8、取一个单词; (3)如果该单词为字母或者数字,跳到(2)继续执行; (4)如果该单词为空格符或者换行符等界符,则停止执行; (5)在停止处,去初始位置到当前位置的单词单元到缓冲区,作为整个标识符输出; (6)程序结束。 该部分程序没有考虑关键字判别,因此,在上述算法中,在第5步之后要进行操作:根据得到的缓冲区的数据,依次与关键字数组中的关键字进行比较,如果相同,那么这个标识符就是关键字,将它划为关键字一类输出。含有关键字比较的程序流程图如图4。 图 4 ID与关键字程序流程2.2运算符和界符:运算符和界符的正则式表示为: mark= +|-|*|/|=|=|(|)|!|!=|+|=|,|;|:

9、 运算符的检索也比较简单,因为大多只有一个符号,对于双目运算符则按如下方式识别: +(后一位为+)|+(后一位不为+) -负号(在=或者(之后)|减号(不在=或者(之后) =(后一位为=)|=(后一位为=)|(后一位不为=) !=(后一位为=)|!(后一位不为=) /注释(后一位为/或者*)|除号(后一位不为/或者*) 按照以上思想,如果碰到上述运算符,则相应的查看后一位的值,按条件识别不同的单目运算符和双目运算符。 2.3整型常数:整型常数NUM的正则式表示如下: NUM=digit digit* digit= 09 根据正则式画出相应的NFA如图4。 同样,根据子集构造法,如同ID的转换方

10、法类似可以得到相应的DFA。NUM的DFA表示如图5。 图 5 NUM的NFA表示DFA表示如下: 0=1,1=2,3,5,2=3,5 (1)S=0,1,2 (2)=digit (3)D(0,digit)= 1 D(1,digit)= 2 D(2,digit)= 2 (4)0=0 (5)=2 将0,1,2分别用A,B,C代替,则可以得到NUM的DFA表示。 图 6 NUM的DFA表示同理,根据DFA可以将B状态合并,这样得到的mDFA如图7。 图 7 NUM的mDFA因此,整型数据的递归方法与标识符类似,这里不列举其算法思想与流程图了。在递归过程中的计数方法为依次往后取数的过程中,原值乘十后与

11、最低位相加,算式为:uWord.value.T2=uWord.value.T2*10+strSourcegnLocate-0。其中,等式左边uWord.value.T2为存放整型数据的缓冲区,strSourcegnLocate为当前位置的数值的ascii码字符值,因此需减去字符0的ascii码值。 另外,还有负数的问题。负数问题的解决方式是一样的。在运算符判断过程中如果已经发现“-”为负号,那么其后的整型常数仍旧按照上述方法取指,但是计算数值的公式为:uWord.value.T2=uWord.value.T2*10-strSourcegnLocate-0。这样得到的整个数据即为正确的负数值。

12、三 程序实现源代码#include#include#includechar prog80,token8;char ch;int syn,p,m=0,n,row,sum=0;char *rwtab8= start,if,then,int,while,do,for,end;using namespace std;void scaner() for(n=0; n=a&ch=A&ch=0&ch=a&ch=A&ch=Z) tokenm+=ch; ch=progp+; tokenm+=0; p-; syn=10; for(n=0; n=0&ch=0&ch32767) syn=-1; else switch(ch) /其他字符 case) syn=21; tokenm+=ch; else if(ch=) syn=22; tokenm+=ch; else syn=23; p-; break; case: m=0; tokenm+=ch; ch=progp+; if(ch=) syn=24; tokenm+=ch; else syn=20; p-; break;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1