一个简单的句法制导转换的例子
需要有一套自洽的理论结构
如何将一个语言转换为另外一种语言,比如将 c 语言转换为 javascript, 是有需要这种场景的。抽象语法树可能是各种语言能够最终转换一致的一种形式,比如 if 语句,都是包含执行条件和执行语句。这种形式是不能够再拆分的,否则就会无法理解。
要做的事情
从一个小的例子开始,类似于 9-5+2 或者是 count = count+1 这样的中缀表达式首先将先被转换成后缀表达式(postfix),后缀表达式能够更好的说明执行的顺序(比如 3+5*2 这种比较模糊的表达式,变成后缀表达式是 3+52*),一种中间形态,称为三地址形式(three-address code 简写为 TAC),然后是机器能够理解的机器语言(0 1)
将表达式转换为中间形式,称为编译器的前端,将中间形式生成目标代码称为编译器的后端。
syntax(句法)、semantic(语义)、lexical(词法)
* 为了说明什么叫做 syntax, 需要介绍一种叫做 context-free grammer(无上下文语法) 的标记形式,用于指导编译的过程。
- semantics 就是这段程序表达了什么,解释起来会更加的抽象。
中间表示形式(intermediate representive )
中间形式分为两种 AST(抽象语法树)和 三地址代码
无上下文语法
无上下文语法,简称语法,用来说明什么是句式(syntax),比如 if else 语句,if 的后面需要一对括号(parenthense)接着是一条语句
statement -> if(expression) statement else statement
//for short
stmt --> if(expr) stmt else stmt
句法的构成
终结符 terminal <,=,+ 还有 if else where
非终结符 nonterminal 由一系列产生式和终结符构成
产生式 production
加减法的产生式
括号的派生(derivation )
Parse(解析)
解析树(Parse tree)
9-5+2 的两种解析树
如果一个操作数(operand)在左右两边都有两个操作符号,那么需要将哪个操作符号作用在这个操作数上,称为操作符的结合性(associative of Operators),如果是左边的,称为左结合,大部分语言是左结合的
操作符的优先级(precedence)乘除相对于加减有更高的优先级。(In ordinary arithmetic,multiplication and division have higher precedence than addition and subtraction.)
expr -> digit + term | digit - term | term
term -> term * factor | term / factor | factor
factor -> digit | expr
- 为什么要转换为后缀表达式,后缀表达式的产生式
语法制导的定义
- 由产生式和语义规则