编译原理-第二章 一个简单的语法指导编译器-2.8 生成中间代码
生成中间代码:
- 两种中间表示形式:
- 树形结构:语法分析树、抽象语法树
- 抽象语法树的构造:
- 可以为任意的构造创建抽象语法树,每个构造用一个结点表示,其子结点代表此构造中具有语义含义的组成部分
- 在语法分析过程中,将创建抽象语法树的结点来表示有意义的程序构造,随着分析的进行,信息以与结点相关的属性的形式被添加到这些结点上
- 例:
- 树节点:类Node
- 子类:expr(代表各种表达式)、stmt(代表各种语句)
- 语句的语法树:
- 一个叶子结点null表示一个空语句序列
- 运算符seq表示一个语句序列
- 抽象语法树的构造:
- 线性结构:三地址代码
- 三地址代码:由一个基本程序步骤(如将两个值相加)组成的序列,无层次化的结构,
- 组成:由x = y op z形式的指令组成的序列,x、y和z可以是名字,常量或由编译器生成的临时量,而op表示一个运算符
- 语句的翻译:
- 通过跳转指令实现语句内部的控制流,就可以将语句转换成为三地址代码
- 使用一些跳转指令在语句的各个组成部分对应的代码之间进行跳转
- 例:
- 对 if expr then stmt1 的翻译:
- 跳转指令:if False x goto after
- 类if是类stmt的一个子类,stmt的每一个子类都有一个构造函数及一个为此类语句生成三地址代码的函数gen
- 构造函数if构建了if语句的语法树特点,有两个参数,一个表达式结点x和一个语法树结点y,分别被存放在属性E和S中
- 同时,构造函数调用了函数newlable()给属性after赋予一个唯一的新标号
- 一旦源程序的整个抽象语法树被创建完毕,函数gen在此抽象语法树的根结点处被调用
- 对 if expr then stmt1 的翻译:
- 表达式的翻译:
- Access(y,z)表示数组操作:y数组名,z数组下标
- 例:
- 改进:
- 优化阶段减少拷贝指令的数目
- 充分考虑上下文的情况
- 作用:优化代码,可以将组成程序很长的三地址语句序列分解为基本块,“基本块”就是一个总是逐个顺序执行的语句序列,执行时不会出现分支跳转
- 三地址代码:由一个基本程序步骤(如将两个值相加)组成的序列,无层次化的结构,
- 树形结构:语法分析树、抽象语法树
- 静态检查:
- 作用:编译器前端会检查源程序是否遵循源语言的语法和语义规则,确保一些特定类型的程序错误,包括类型不匹配,能在编译过程中被检测并报告
- 组成:
- 语法检查:语法要求比文法中的要求多,它们并不包括在用于语法分析的文法中
- 类型检查:
- 确保一个构造的类型符合其上下文对它的期望
- 一种语言的类型规则确保一个运算符或函数被应用到类型和数量都正确的运算分量中
- 类型检查规则按照抽象语法中运算符/运算分量的结构进行描述
参考——《编译原理(第二版)》
作者:方知有
Motto: 热爱可抵岁月漫长
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。
所有评论和私信都会在第一时间处理,如有问题或建议,请多多赐教!
支持博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是作者坚持原创和持续写作的最大动力!