一、词法分析的概貌
一个程序,在我们看来往往是像下图这样的。
实际上,上面的程序本质上就是一个字符串,所以,它等价于下面这样的。
上面的字符串(字符流) ,就是编译器接收到的程序的形式。
所以,编译器首先要对字符流进行断句,即将输入字符串识别为有意义的子串,删去注释和无意义的换行符等字符。有意义的子串又叫词法单元(token)。
从程序字符流中获取词法单元集合的过程就是词法分析。
二、词法单元
词法单元(token)由一个记号名和一个可选的属性值(可为空)组成。即
token = <token_name, attribute_value>
属性记录词法单元的附加属性,具体有哪些附加属性,则要看编译器的设计者如何设计。
词法单元保存在符号表(Symbol table)中,以便编译的各个阶段取用。
例如:
有关词法单元的关键术语如下图所示。
举个例子。
三、正则表达式 (Regular Expression, RE)
(一)初识正则表达式
如何识别(匹配)词法单元呢?
我们可以考虑上面图中的模式的非形式描述,但显然在计算机中这是根本不可能的。
我们需要形式化地来设计模式,而这个模式就是正则表达式。
正则表达式是一个文本模式,使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
比如匹配正整数的正则表达式可以如下设计:
上图中的*表示闭包运算(某字符零次或多次出现),|表示选择运算符。
该正则表达式匹配正整数123的过程可如下表示。
匹配会从开始状态出发,不同的箭头代表不同的路径,能否走这条路径的条件是当前字符是否等于该路径上的字符(即是否匹配),终点是接受状态,用一对同心圆表示。
当一个词法单元能够通过上面过程到达接受状态,就说明:该词法单元可被该正则表达式匹配。
有关正则表达式的详细介绍,可参考下面的链接:
正则表达式 – 教程 | 菜鸟教程 (runoob.com)
而上图中的箭头与圆圈就组成了有限自动机(Finite Automata)。
所以,词法单元被某正则表达式所匹配,就等价于该词法单元被该正则表达式对应的有限自动机匹配。
(二)正则表达式的关键术语与概念
(三)正则表达式定义了语言
举个例子。
参考资料:
[1]USTC 编译原理和技术 2023 (ustc-compiler-principles.github.io)