7.1 词法分析的基本概念

词法分析也称为 分词 ,此阶段编译器从左向右扫描源文件,将其字符流分割成一个个的 token记号 ,后文中将称为 token )。所谓 token ,就是源文件中不可再进一步分割的一串字符,类似于英语中单词,或汉语中的词。images/lexical_analysis.png图7.1 词法分析示意图

英语中的单词的数量是有限的,程序语言中可用的 token 的类别也是有限的,而且是非常少的。一般来说程序语言中的 token 有:常数(整数、小数、字符、字符串等),操作符(算术操作符、比较操作符、逻辑操作符),分隔符(逗号、分号、括号等),保留字,标识符(变量名、函数名、类名等)等。如:

  • 3255 是整数常数 token
  • “Fred”“wilma” 是字符串 token
  • numTicketsqueue 是标识符 token
  • while 是 T_WHILE token

上述的 3“Fred”while 等称为 token 的 字面值 。有些类别的 token 只有一个字面值,如保留字和分隔符类的 token,其他类别的 token 则有不同字面值,如整数常数 token 。下面是一些典型的 token 及其字面值:

  1. TOKEN-TYPE TOKEN-VALUE
  2. -----------------------------------------------
  3. T_IF if
  4. T_WHILE while
  5. T_ASSIGN =
  6. T_GREATTHAN >
  7. T_GREATEQUAL >=
  8. T_IDENTIFIER name / numTickets / ...
  9. T_INTEGERCONSTANT 100 / 1 / 12 / ....
  10. T_STRINGCONSTANT "This is a string" / "hello" / ...

编译器中的 token 中一般用一个 struct 来表示:

  1. typedef enum {
  2. T_IF, T_WHILE, T_ADD, T_INTCONSTANT, T_STRINGCONSTANT, T_IDENTIFIER, ...
  3. } TokenType;
  4.  
  5. typedef struct _Token {
  6. TokenType type;
  7. union {
  8. char *stringval;
  9. int *intval;
  10. double *doubleval;
  11. } value;
  12. } TokenRecord;

词法分析器每扫描到一个完整的 token 后,立即 新建一个 TokenRecord ,将此 token 的类型记录在此结构的 type 域中,将其字面值记录在 value 域中对应的子域内,并将此 TokenRecord 结构传递给下一阶段的语法分析模块使用,然后接着扫描下一个 token 。这样从语法分析模块的角度来看,源程序就变成了一个连续的 token stream 了。

分词扫描的方法有直接扫描法和正则表达式匹配扫描法,下面先介绍直接扫描法。