学习编译原理之美(宫文学老师)
编译器前端技术分析
这里的“前端(Front End)”指的是编译器对程序代码的分析和理解过程,它通常只跟语言的语法有关,跟目标机器无关,而与之对应的“后端(Back End)”则是生成目标代码的过程,跟目标机器有关

词法分析(Lexical Analysis)
编译器的第一项工作叫做词法分析。就像阅读文章一样,文章是由一个个的中文单词组成的。程序处理也一样,只不过这里不叫单词,而是叫做“词法记号”,英文叫 Token
如下短语词法分析
2+3*5

语法分析 (Syntactic Analysis, or Parsing)
词法分析是识别一个个的单词,而语法分析就是在词法分析的基础上识别出程序的语法结构,这个结构是一个树状结构,是计算机容易理解和执行的。
程序的语法分析过程,就是构造这么一棵树。一个程序就是一棵树,这棵树叫做抽象语法树(Abstract Syntax Tree,AST)。树的每个节点(子树)是一个语法单元,这个单元的构成规则就叫“语法”。每个节点还可以有下级节点
层层嵌套的树状结构,是我们对计算机程序的直观理解。计算机语言总是一个结构套着另一个结构,大的程序套着子程序,子程序又可以包含子程序
如下语法分析
2+3*5

形成 AST 以后有什么好处呢?就是计算机很容易去处理。比如,针对表达式形成的这棵树,从根节点遍历整棵树就可以获得表达式的值。
如果再把循环语句、判断语句、赋值语句等节点加到 AST 上,并解释执行它,那么你实际上就实现了一个脚本语言。而执行脚本语言的过程,就是遍历 AST 的过程。
语义分析(Semantic Analysis)
语义分析就是要让计算机理解我们的真实意图,把一些模棱两可的地方消除掉。
计算机语言的语义一般可以表达为一些规则,你只要检查是否符合这些规则就行了。比如:
-
某个表达式的计算结果是什么数据类型?如果有数据类型不匹配的情况,是否要做自动转换?
-
如果在一个代码块的内部和外部有相同名称的变量,我在执行的时候到底用哪个? 就像“我喜欢又聪明又勇敢的你”中的“你”,到底指的是谁,需要明确。
-
在同一个作用域内,不允许有两个名称相同的变量,这是唯一性检查。你不能刚声明一个变量 a,紧接着又声明同样名称的一个变量 a,这就不允许了
总结
- 词法分析是把程序分割成一个个 Token 的过程,可以通过构造有限自动机来实现。
- 语法分析是把程序的结构识别出来,并形成一棵便于由计算机处理的抽象语法树。可以用递归下降的算法来实现。
- 语义分析是消除语义模糊,生成一些属性信息,让计算机能够依据这些信息生成目标代码。