编译原理演示文稿6.ppt

  1. 1、本文档共136页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
第六章 语法制导译 在前面已经介绍了编译程序构造的二个重要阶段,即词法分析和语法分析。现在再来介绍编译程序的另一个重要阶段——中间代码生成。虽然在实际应用中,是否采用中间代码形式是根据实际情况而定的。但事实上,为了使编译程序的结构清晰、简单、明确,多数编译程序采用了中间代码的形式。尤其是使用了中间代码的形式,使目标代码优化比较容易实现。通常以中间代码生成这一阶段来划分编译程序的前端和后端。对于不同的高级语言只要翻译成相同的中间代码,再接上一个相同的把中间代码翻译成目标代码的后端,就可以形成不同的编译程序。同一种高级语言只要翻译成相同的中间代码就可以共用一个前端,接上后端可以在不同机型上实现同一语言的编译程序。虽然中间代码的形式很多,但常见的中间代码有逆波兰式、三元式、四元式、树形表示等。本章讨论如何将高级语言翻译成中间代码。 6.1 中间代码的形式 中间代码的形式虽然很多,但组成中间代码的原则是: (1) 形式比较简单,容易翻译成相应的目标机器代码 (2) 能充分反映源程序的特点 比较常用有逆波兰式、三元式、四元式和树型表示。 6.1.1 逆波兰式 逆波兰式是由波兰数学家卢卡西维奇发明的一种表示算术表达式或逻辑表达式的方法,它是一种能表示运算符的计算顺序,但没有括号的表达式。在这种表示法中,把运算符直接跟在运算对象后面,因此逆波兰表示法又称后缀表示法。 逆波兰表示法的格式为: 运算对象1 运算对象2运算符 例如:表达式(a+b*c/d)*e-f的逆波兰式为: abc*d/+e*f- 从上可以看出,逆波兰式具有下列性质: (1) 在中缀式和逆波兰式中,运算对象是按相同的顺序出现的 (2) 在逆波兰式中,运算符是按计算顺序(从左到右)出现的 (3) 运算符紧跟在其运算对象后面出现的 当逆波兰式允许单目运算符(仅允许一个运算对象的运算符)出现时,会产生一些问题。如写出表达式a+(-b*c/d)*e的逆波兰式为ab-cd/*e*,此时很难区分运算符-是单目的还是双目的。即先计算a-b还是-b。解决上述问题的方法有二种: (1) 把单目运算符改成双目,如改写成:a0b-cd/*e* (2) 引进新的运算符为@,如:ab@cd/*e* 其它单元目的运算符可参照上述方法处理。对于第一种方法,把单目运算符处理成双目运算符增加了运算的时间,降低了工作效率。对于第二种方法,要解决的问题是如何把符号‘-’处理成不同的符号。处理的时机可以放在词法分析中解决,如在表达式的起始位(如赋值号后、逗号后、左括号后等)设置标记flag为1,即单元目运算符,在遇到运算对象后设置标记flag为0,即双目运算符。 计算逆波兰式表示的算术或逻辑表达式比计算中缀式要简单。这是因为计算逆波兰式不要比较运算符的优先级,只要一遇到运算符就立即可以计算。具体实现中只要用一个栈来存放运算对象,故该栈又称运算对象栈或运算分量栈。在栈中存放未被计算的运算对象,当一旦扫描到运算符时,就从栈中取出运算符所需的运算对象个数进行计算。然后再将计算结果放入栈中,当全部扫描完逆波兰式后栈顶元素即为最后的计算结果。 一般算法语言除了算术表达式和逻辑表达式外,还有其它如赋值语句、条件语句、循环语句等,但只要遵守运算对象后直接紧跟计算它们的运算符这一规则,就可以很方便地将逆波兰式扩充到整个算法语言。 例如,赋值语句 变量:=表达式可改写为变量表达式:= ;GOTO L 改写成L jmp (其中jmp 表示转移的运算符,L表示逆波兰式的编号或地址)。 对于条件语句:if E then S1 else S2 可以考虑三目运算符if,如ES1S2if。但这种表示方法当执行到运算符if时,E、S1、S2三个运算对象已经全部计算过可或执行了,由于构造的逆波兰式都是从左到右执行的,此时很难再回到前面去重新执行或跳过相应的逆波兰式。为此可以用二目条件转移来表示:Eop1jz S1op2jmpS2,其中,op1、op2分别为S2的开始位置和跟在S2之后那个符号的位置。jz和jmp分别为条件和无条件转运算符。类似可以引进条件转移的逆波兰式为: 运算对象1 运算对象2运算符 其中运算对象1是算术值或逻辑值,运算对象2是逆波兰的某个编号或位置;运算符可以是jl、jg、jle、jge、jz、jnz等,分别表示小于、大于、小于等于、大于、等于、不等于等转移的运算符。 当然用同样的方式,还可以将逆波兰式扩充至数组、记录或其它数据类型,也可将for语句、while语句、case语句扩充至逆波兰式。另外需要指出的是:赋值运算符和其它逆波兰式不一样,它要把表达式的值放

文档评论(0)

wendan118 + 关注
实名认证
内容提供者

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

1亿VIP精品文档

相关文档