语法树
是啥
在知道了文法的定义后,我们就要根据文法分析生成语法树了。
语法树可以表达是文法展开的过程,比如i+i*i
对应文法是
E ::= T | E + T | E - T
T ::= F | T * F | T / F
F ::= i
文法展开过程是:
E -> E + T -> T + T -> F + T -> i + T
-> i + T * F -> i + F * F -> i + i * i
根据文法构造的语法树就是:
E
/|\
F + T
| /|\
i F * F
| |
i i
就很清楚了,我们得到语法树后可以计算”中序”遍历的序列,并对每个节点加括号,那么就可以还原原算式和文法的结构。
(i+(i*i))
(-E-----)
F+(-T-)
i F*F
i i
如果是连等式,那么有
a=b=c=d=e=1
=
/ \
a =
/ \
b =
/ \
c =
/ \
d =
/ \
e 1
因为=是右结合的,所以语法树是右偏的。
可以说语法树展现了语句的结构,也展现文法的展开方式。
前置离散数学和数据结构。
语法树实现及节点类型表示参见
https://github.com/huanghongxun/Compiler/blob/master/compiler/syntax_tree.h
https://github.com/huanghongxun/Compiler/blob/master/compiler/syntax_descriptors.h
求值
我们有必要实现一个在语法树上直接运算的程序,这样我们可以在编译期完成常量的计算,计算数组定义时各维大小的表达式(如int a[2 * 3][(int) 3.0 / 2]
),以及实现constexpr。
说简单其实可以说简单,我们可以这么写(伪代码)
object eval(AST ast)
{