编译器的前端技术之语法分析

277 阅读2分钟

语法分析 (Syntactic Analysis, or Parsing)

在词法分析之后,编译器下一个阶段的工作是语法分析。词法分析是识别一个个的单词,而语法分析就是在词法分析的基础上识别出程序的语法结构。这个结构是一个树状结构,是计算机容易理解和执行的。

和自然语言类似,可以拆分为主谓宾 image.png

AST抽象语法树

程序也有定义良好的语法结构,它的语法分析过程,就是构造这么一棵树。一个程序就是一棵树,这棵树叫做抽象语法树(Abstract Syntax Tree,AST)。树的每个节点(子树)是一个语法单元,这个单元的构成规则就叫“语法”。每个节点还可以有下级节点。

这个网址可以看JavaScript的抽象语法树JavaScript AST Visualiser – Demo applications & examples (jointjs.com)

抽象语法树的好处就是计算机很容易去处理,针对表达式形成的这棵树,从根节点遍历整棵树就可以获得表达式的值。执行脚本语言的过程,就是遍历 AST 的过程。

如何使用程序构造AST

递归下降算法(Recursive Descent Parsing)

一种非常直观的构造思路是自上而下进行分析。首先构造根节点,代表整个程序,之后向下扫描 Token 串,构建它的子节点。当它看到一个 int 类型的 Token 时,知道这儿遇到了一个变量声明语句,于是建立一个“变量声明”节点;接着遇到 age,建立一个子节点,这是第一个变量;之后遇到 =,意味着这个变量有初始化值,那么建立一个初始化的子节点;最后,遇到“字面量”,其值是 45。这样,一棵子树就扫描完毕了。程序退回到根节点,开始构建根节点的第二个子节点。这样递归地扫描,直到构建起一棵完整的树。 image.png

递归下降算法是一种自顶向下的算法,与之对应的,还有自底向上的算法。这个算法会先将最下面的叶子节点识别出来,然后再组装上一级节点。有点儿像搭积木,我们总是先构造出小的单元,然后再组装成更大的单元。

现成的工具

Comparison of parser generators_宫文学Richard的博客-CSDN博客

此文章为3月Day21学习笔记,内容来源于极客时间《01 | 理解代码:编译器的前端技术 (geekbang.org)