编译技术教程:语法分析
系列导航: 《编译技术教程:前言》 《编译技术教程:词法分析》 《编译技术教程:抽象语法树》 《编译技术教程:语法分析》 《编译技术教程:符号表与类型系统》 《编译技术教程:语义分析》 《编译技术教程:附录 - 项目测试》 在词法分析阶段,我们将输入的源程序解析为一个个单词;而在语法分析部分,我们将依照文法对单词序列进行进一步的分析,从而构建结构化的抽象语法树。 一、语法分析的作用 进行语法分析的必要性在于,句子是线性结构,不包含相应的语法结构信息。因此直接对线性的句子进行处理非常困难。而语法树的层次化结构能够表现语法结构以及语法成分之间的关系,且方便利用递归等方法来进行处理。 例如,对于上表达式 a + (3 + b) * 2 对于人来说,可以很容易地确定表达式的运算顺序。但是,从计算机角度而言,要编写一个程序仅仅根据这个线性字符串来确定运算的顺序是比较困难的,尤其是当表达式更为复杂的时候。如果我们建立了语法树,则可以很轻松地利用递归等方法来进行计算。 实际上,我们人类确定表达式运算顺序的方法,或许也在一定程度上与语法分析所采用的方法类似。这一点将在下一章节中说明。 还举上面的表达式为例。我们给定文法,并给出表达式在该文法上的语法树 LVal: Ident PrimaryExp: '(' Exp ')' | LVal | Number UnaryExp: PrimaryExp | Ident '(' [FuncRParams] ')' | UnaryOp UnaryExp UnaryOp: '+' | '-' | '!' MulExp: UnaryExp | MulExp ('*' | '/' | '%') UnaryExp AddExp: MulExp | AddExp ('+' | '-') MulExp Exp: AddExp 在上面的例子中,我们要求表达式 Exp 的值(图中序号1),那么我们只需要求出 AddExp(序号2)和 MulExp(序号3)的值并将它们相加即可。要求 MulExp(序号3)的值,我们只需要求出 MulExp(序号4)和 UnaryExp(序号5)的值并将它们相乘即可。同样地,要求 MulExp(序号4)的值,我们只需要求出 AddExp(序号6)和 MulExp(序号7)的值并将它们相乘即可。对于每种语法成分的处理,如 AddExp 和 MulExp 的计算求值,我们都可以采用递归的方法很方便地实现,而且语法树的层次结构自然保证了计算顺序的正确性。...