《编译技术》课程设计申优文档.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
《编译技术》课程设计申优文档

《编译技术》课程设计申优文档文法梳理因为我们要用递归子程序法来编写语法分析部分,我们尽量要使其满足不回溯、不会无穷递归,所以我们需要文法满足一定的条件。所以首先要做的就是要对文法进行检查和必要的改写,下面我们就针对这两个问题来分别论述。回溯问题不回溯的实质其实就是匹配成功则不是虚假的、匹配不成功则任何其他候选式肯定也无法成功,这样就能保证每一步的深入工作不会浪费。这个问题其实有两种解决方法:一种是对文法改写,比如有A::=aB|aC那就改写成A::=aA’;A’::=B|C,如果First(B)和First(C)的交集还不为空的话那就继续改写,这样就能满足不回溯。但这样对我们来讲是否是一个比较好的方法呢,我们可以观察文法其实还是比较复杂的,这样做可能会使文法变得混乱而不自然,反而使我们的程序更加不自然;第二种方法是进行预读,这种方法的思想就是既然我现在确定不了该怎么做,那我就向前走走,走着走着总能知道该用什么了吧,这种方法无需对文法进行改写,在写程序的时候也很容易实现,所以我在编译器中使用了这种方法。我们来看一个实际例子:<声明头部> ??::= ?int<标识符> |float <标识符>|char<标识符><变量说明部分> ?::=?<变量定义>;{<变量定义>;}<变量定义>??::= <类型标识符><标识符>{,<标识符>}<常量>???::=? <整数>| <实数>|<字符><类型标识符>????? ::=? int | float | char<有返回值函数定义部分> ?::= ?<声明头部>‘(’<参数>‘)’ ‘{’<复合语句>‘}’我们看上面的文法,比如我们现在读入了int我们还不能判断出到底是“变量定义”还是“有返回值函数定义部分”,这时我们就让程序继续读入,假如我们在下下一个Token处发现是“(”,那我们当然就可以断定语法成分是“有返回值函数定义部分”,如果不是那就认为是“变量定义”。这样回溯问题就解决了。无穷递归问题无穷递归的问题会产生的原因是文法中出现了左递归的产生式,例如A::=Aa,这样如果用递归子程序法就会无穷递归下去,但是我们对文法进行考察之后发现,并没有出现这样的情况,所以就不需要对文法继续改写了。我在我的程序中还加入了对块注释(/**/)和行注释(//)的支持,对于下面的:<有返回值函数定义部分> ?::= ?<声明头部>‘(’<参数>‘)’ ‘{’<复合语句>‘}’<无返回值函数定义部分> ?::=?void<标识符>‘(’<参数>‘)’‘{’<复合语句>‘}’<参数> ???::=?<参数表>这种冗余文法也改写为了:<有返回值函数定义部分> ?::= ?<声明头部>‘(’<参数表>‘)’ ‘{’<复合语句>‘}’<无返回值函数定义部分> ?::=?void<标识符>‘(’<参数表>‘)’‘{’<复合语句>‘}’词法分析这里就是我们编译器真正开始的地方了,词法分析可以说是直接与源程序文件打交道的地方,也是我们编译器的最前端,所以这里的设计直接决定了我们后面工作的进行。其实说它的工作目的是非常简单的,我们只需要把源文件划分成一个个Token,这样我们的语法分析部分得到的就不是一个个字符,而是有一定意义的小短语,这就相当于是把字符串转变为我们程序可以识别的一个个符号了。这部分程序编写比较简单,就是一个自动机,不断地按照规则读入字符,然后进行拼接组成一个字符串小元素。最重要的其实是我们怎么来划分这个Token,这个Token可大可小,我们怎么来衡量这个标准,我个人认为这里我们需要搞清楚词法分析和语法分析的界限,不要把它们混在一起,让词法分析来完成特别复杂的功能,词法分析就是剥离出一个个不同类别的小Token就足够了,不要过度地依赖它来完成更高级别的语法元素分析。在我的程序中我采用了一符一类的方法来标示Token,具体如下:#define TK_PLUS 0 // +#define TK_MINUS 1 // -#define TK_MUL 2 // *#define TK_DIV 3 // /#define TK_LITTLE 4 // #define TK_LITTLEEQL 5 // =#define TK_GREAT 6 // #define TK_GREATEQL 7 // =#define TK_NOTEQL 8 // !=#define TK_EQUAL 9 // ==#define TK_LETTER 10 //字母#define TK_DIGIT 11 //#define TK_NUM 12 //数字#define TK_NUMNO0 13 //非零数字#define TK_CONST 55 //const#define TK_INT 51 //int#define TK_F

文档评论(0)

celkhn5460 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档