Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

字符怎样组成词

复习

  • 从字符串变为程序:编译器分阶段处理源码
  • 语言与文法:用规则描述语言
  • 字符串:字符的序列

TL;DR

  • 词法分析把字符流切成一个个“词法单元”
  • 常见词法单元:关键字、标识符、数字、符号
  • 它们的边界由规则决定
  • 词法单元是语法分析的基本单位

正文

  编译器读进来的,是一长串字符。可它真正想处理的,是“一个个有意义的词”。把这串字符切成词的这一步,叫词法分析(lexical analysis),切出来的每个单位叫词法单元(token)。

切成一个个词

  看一句简单的代码:

int x = 42 + y;

  在人眼里,它是由几个词拼成的。词法分析要做的,就是把它切成:

int   x   =   42   +   y   ;
关键字 标识符 符号 数字 符号 标识符 符号

  每切一刀,都要判断这个词属于哪一类。常见的类别有:

  • 关键字:语言保留的特殊词,如 intif
  • 标识符:变量名、函数名等,如 xy
  • 数字:如 42
  • 符号:如 =+;

  切出来的词法单元,通常还带着“类别”和“具体内容”两部分信息,方便后续使用。

边界由规则决定

  “切在哪里”不是随便定的,而由语言的规则决定。比如标识符通常是“字母或下划线开头,后面跟字母、数字或下划线”。词法分析器就按这些规则,一路扫过去。

  这里有个经典的细节:遇到 ifx 这样的输入,该切成关键字 if 加标识符 x,还是整个标识符 ifx?通常的规则是“最长匹配”:只要能构成一个合法的标识符,就整体当作标识符。所以 ifx 是一个标识符,而不是 if 后面跟 x

  至于空白和注释,词法分析器一般会直接跳过——它们对人有用,对语法结构却没意义。

为什么要先切词

  为什么不直接对着字符做语法分析,而要先切词?

  因为把问题分层:词法分析只需回答“这个字符序列是什么词”,不用管语法;语法分析则只需面对一个个干净的词,不用再操心字符层面的细节。各管一段,各自简单——这正是编译器分层设计的一贯思路。

  切好词之后,就可以进入下一关:把这些词组织成有结构的语法树。

思考题 1

  为什么编译器要先把字符流切成词法单元,而不是直接解析字符?

思考题 2

  遇到 ifx 这样的输入,词法分析器应该切出关键字 if 还是标识符 ifx?依据是什么?

小结

知识点

  • 词法分析把字符流切分并分类为词法单元
  • 常见类别:关键字、标识符、数字、符号
  • 分词依据语言规则,通常采用最长匹配
  • 空白与注释一般被跳过

参考资料

  1. Wikipedia(zh):词法分析:把字符流切分为词法单元
  2. Wikipedia(zh):词法单元:语法分析处理的基本单位

思考题答案(仅供参考)

思考题 1

  因为分层能让问题各自简化:词法分析只负责从字符判断词,语法分析只面对一个个词,不必再处理字符细节。各层职责单一,编译器整体更容易实现和维护。

思考题 2

  通常切作标识符 ifx,依据“最长匹配”规则:只要连续的字符能构成一个合法标识符,就整体识别为一个标识符,而不是拆出其中的关键字前缀。

协议

  本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

封面图

设计师 | 南国微雪