第6章语法制导翻译和中间代码生成案例.ppt

第6章语法制导翻译和中间代码生成案例.ppt

  1. 1、本文档共55页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 若后继输入符号为∧,则可将⑴式的第四项置为3;若后继输入符号为∨,可将⑵式的第四项置为3。 另外一个未填转移地址的四元式的地址只能作为语义值保存下来。当处理到then,说明布尔表达式翻译完毕,此时可回填布尔表达式的真出口;当处理到else,可回填布尔表达式的假出口。 ③问题的提出 在自下而上的分析过程中,语法分析器是自左至右扫描输入符号串,一个布尔表达式的真假出口,往往不能在产生四元式的同时填入。 接上例,首先将i归约为X,X.addr保留变量a在符号表中的入口地址。然后将X归约为E时,产生二个四元式如下: ⑴ (jnz,a,0,?) ⑵ (jmp,0,0,?) * ④解决办法 1)修改文法 E→EAE|EOE|~E|(E)|XrX|X EA→E∧ //A表示and EO→E∨ //O表示or X→X+X|X*X|(X)|-X|i|x 通过文法修改解决了一半问题。 EA→E∧ 当E∧归约为EA时,可填真出口,真出口为下一个四元式地址,而假出口无法填写。 EO→E∨ 当E∨归约为EO时,可填假出口,假出口为下一个四元式地址,而真出口无法填写。 2)引进语义变量.tc和.fc保存未填转移目标的四元式地址 布尔表达式由若干子表达式构成,转移目标地址只有二个,或为真出口、或为假出口。为了记录和回填方便,利用四元式的第四项(改称为next)构成二条单向链。赋予E、EA和EO另外二个语义值.tc和.fc,分别记录需回填真假出口单向链的链首。 * 假定布尔表达式E的四元式中需回填真出口的有p、q和r三个四元式,这三个四元式可构成一单向链,链首由E.tc指出。 当X或XrX归约为E时,将产生二个四元式。用E.tc指向第一个四元式,用E.fc指向第二个四元式,并将四元式的第四项置为0,表示链尾。如下所示: 在分析过程中,利用语义值传递和合并链的方法,最终完成两根真假出口链的构造。在if-then-else语句中,当翻译完布尔表达式,就可找到真出口,利用E.tc进行回填。当翻译完语句S1,就可知道假出口,利用E.fc进行回填。 * 3)变量和函数 nxq指示器 nxq指向下一个将要形成但尚未形成的四元式地址(编号)。nxq初值为1,每执行一次gen_code函数之后,nxq自动增1。 链合并函数merg(p1,p2) 将以p1和p2为链首的二条单向链合并为一条,并且将合并后的链首作为返回值。若p2为空,则以p1为合并后的链首;若p2非空,则以p2为合并后的链首。 回填函数backpatch(p,t) 将以p为链首的单向链中的每个四元式的第四项置为t。 例a∨bc∨d 解:第一步(a∨) * 第二步(a∨bc∨) 第三步( a∨bc∨ d) * 第四步(当布尔表达式处理完,看到then后可回填真出口,语义动作是在控制语句的翻译中实现) 因(1)式、(3)式和(5)式转移地址相同,故由三个四元式构成一条真出口链,链首由.tc指出。当布尔表达式E处理完,看到then后,可回填真出口。假出口链由(6)式单独构成,链首由.fc指出,作为语义值不断地传递下去。当处理到else时,可回填假出口。 * E→X { E.tc = nxq; gen_code(jnz,X.addr,0,0); E.fc = nxq; gen_code(jmp,0,0,0); } Er→XrX(1) { E.tc = nxq; E.tc =nxq+1; gen_code(jr,X.addr, X(1).addr,0); gen_code(jmp,0,0,0) } E→~E(1) {//真假出口链链首互换 E.tc = E(1).fc; E.fc = E(1).tc; } E→(E(1)){//传递 E.tc= E(1).tc; E.fc = E(1).fc; } EA→E∧{ backpatch(E.tc,nxq);//可填真出口 EA.fc = E.fc; //传递 } E→EAE(2) { E.tc = E(2).tc;//传递真出口链链首 E.fc = merge(EA.fc, E(2).fc);//合并 } E→EOE(2){ E.tc = merge(EO.tc, E(2).tc); //合并 E.fc = E(2).fc; //传递假出口链链

文档评论(0)

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

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

1亿VIP精品文档

相关文档