第1关:赋值语句的三地址代码产生

第1关:赋值语句的三地址代码产生
第1关:赋值语句的三地址代码产生

引言

在编译原理中,三地址代码(Three-Address Code, TAC)是一种常见的中间代码形式,用于桥接源语言与目标机器代码之间的转换。本文以“赋值语句三地址代码产生”为例,介绍如何在递归下降解析的框架下,基于属性文法插入语义动作,生成正确的三地址代码,并给出完整的修正后代码,方便大家参考。


问题描述

给定一个简单的赋值语句文法:

<赋值语句> ::= <标识符> := <表达式>
<表达式> ::= [+|-]<项>{<加法运算符><项>}
<项>     ::= <因子>{<乘法运算符><因子>}
<因子>   ::= <标识符> | <无符号整数> | '(' <表达式> ')'

要求在原有的递归下降分析框架中,补充属性和动作代码,输出形如以下格式的三地址代码:

T1:=c*d
T2:=b+T1
a:=T2
  • “减法同加法,除法同乘法”
  • 临时变量通过 newTemp() 生成
  • 在完成 expressionitemfactor 函数逻辑后,综合属性 E_valT_valF_val 保存子树计算结果或中间临时变量

原始框架代码未包含 treeNode 类型定义,导致编译期 “treeNode 未定义” 和“不完整类型”错误。此外,三地址码生成逻辑需插入到恰当位置,并用注释标注以便维护。


解决思路

  1. 补充 treeNode 定义
    在函数原型之前添加完整的 treeNode 类定义,保证解析树节点操作可用。
  2. 引入综合属性
    声明全局字符串变量 E_valT_valF_val,分别对应表达式、项、因子的计算结果或临时变量名。
  3. 插入语义动作
    • factor 函数中,将标识符或数字赋值给 F_val
    • item 函数循环中,每次乘除运算后生成临时变量并输出对应三地址码,更新 T_val
    • expression 函数中,处理一元加减、二元加减,生成相应的三地址码并更新 E_val
    • assi_sen 函数末尾,输出最终的赋值三地址码:变量 := E_val
  4. 严格保留框架代码
    原有注释和逻辑结构不作任何修改,仅在允许位置新增代码,并用 // === 新增 ... === 标注。

运行示例

假设输入文件 demo.txt 内容为:

a:=b+c*d;

运行输出:

T1:=c*d
T2:=b+T1
a:=T2

总结

本文演示了如何在已有递归下降分析框架中,通过补充属性和语义动作,生成赋值语句的三地址代码。同时,保留了原框架代码和注释,仅在允许位置新增代码,并用 // === 新增...=== 标注,确保可读性与可维护性。读者可直接参考此示例,将类似方法推广到更复杂的语法和中间代码生成场景中。


提示:登录后即可查看修正后完整代码。
tengmmvp

tengmmvp

China