7.1 词法分析的基本概念
词法分析也称为 分词 ,此阶段编译器从左向右扫描源文件,将其字符流分割成一个个的 词 ( token 、 记号 ,后文中将称为 token )。所谓 token ,就是源文件中不可再进一步分割的一串字符,类似于英语中单词,或汉语中的词。图7.1 词法分析示意图
英语中的单词的数量是有限的,程序语言中可用的 token 的类别也是有限的,而且是非常少的。一般来说程序语言中的 token 有:常数(整数、小数、字符、字符串等),操作符(算术操作符、比较操作符、逻辑操作符),分隔符(逗号、分号、括号等),保留字,标识符(变量名、函数名、类名等)等。如:
- 3 和 255 是整数常数 token
- “Fred” 和 “wilma” 是字符串 token
- numTickets 和 queue 是标识符 token
- while 是 T_WHILE token
上述的 3 、 “Fred” 和 while 等称为 token 的 字面值 。有些类别的 token 只有一个字面值,如保留字和分隔符类的 token,其他类别的 token 则有不同字面值,如整数常数 token 。下面是一些典型的 token 及其字面值:
- TOKEN-TYPE TOKEN-VALUE
- -----------------------------------------------
- T_IF if
- T_WHILE while
- T_ASSIGN =
- T_GREATTHAN >
- T_GREATEQUAL >=
- T_IDENTIFIER name / numTickets / ...
- T_INTEGERCONSTANT 100 / 1 / 12 / ....
- T_STRINGCONSTANT "This is a string" / "hello" / ...
编译器中的 token 中一般用一个 struct 来表示:
- typedef enum {
- T_IF, T_WHILE, T_ADD, T_INTCONSTANT, T_STRINGCONSTANT, T_IDENTIFIER, ...
- } TokenType;
- typedef struct _Token {
- TokenType type;
- union {
- char *stringval;
- int *intval;
- double *doubleval;
- } value;
- } TokenRecord;
词法分析器每扫描到一个完整的 token 后,立即 新建一个 TokenRecord ,将此 token 的类型记录在此结构的 type 域中,将其字面值记录在 value 域中对应的子域内,并将此 TokenRecord 结构传递给下一阶段的语法分析模块使用,然后接着扫描下一个 token 。这样从语法分析模块的角度来看,源程序就变成了一个连续的 token stream 了。
分词扫描的方法有直接扫描法和正则表达式匹配扫描法,下面先介绍直接扫描法。