Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

手写词法分析器

复习

  • 字符怎样组成词:词法单元及其类别
  • 字符串:逐字符处理
  • 状态机:根据当前状态和输入决定下一步

TL;DR

  • 手写词法分析器逐字符读取,边走边判断
  • 它维护“当前状态”,遇到字符就做相应处理
  • 读满一个词,就产出一个词法单元
  • 它本质上是一个简单的状态机

正文

  上一章讲了词法分析要产出什么。这一章看看,怎样亲手写一个词法分析器。

一个循环,扫过所有字符

  词法分析器的主干非常朴素:用一个大循环,从头到尾扫描字符。

  每一轮大致做几件事:

  1. 跳过空白和注释
  2. 看当前字符属于哪一类(字母?数字?符号?)
  3. 按这一类的规则,继续往后吃字符,直到这个词结束
  4. 产出一个词法单元,然后从下一个字符继续

  比如看到字母或下划线,就一路吃到“不再是字母数字下划线”为止,得到标识符;看到数字,就一路吃到“不再是数字”为止,得到数字字面量。

用“状态”来想

  把上面的过程换个角度描述:分析器始终处于某个状态,读到一个字符就决定“接下来怎么处理、状态变成什么”。

  - 一开始是“空闲”状态   - 读到字母,进入“正在读标识符”状态,继续吃字符   - 读到不等于字母数字下划线的字符,说明一个词结束,产出词法单元,回到“空闲”

  这正是我们前面讲过的状态机:当前状态 + 输入 → 下一状态 + 动作。词法分析器本质上就是一个为分词而生的状态机。

别忘了出错的情况

  现实输入不一定规范,比如出现一个语言里根本没有的字符。这时词法分析器不能默默忽略,而应报告一个词法错误,指出位置,方便使用者改正。

  “正常路径 + 错误处理”,是任何合格分析器都要考虑的两面。手写词法分析器虽然简单,也逃不掉这一条。

  手写的好处是直观、可控;但如果词法规则很多、很复杂,手写既枯燥又容易出错。有没有更省力的办法?下一章先引入一种描述词法规则的工具——正则表达式。

思考题 1

  手写词法分析器的循环里,每一轮大致做哪几件事?

思考题 2

  为什么说词法分析器本质上是一个状态机?

小结

知识点

  • 词法分析器用循环逐字符扫描
  • 每轮跳过空白、判断类别、读取完整词、产出词法单元
  • 它的行为可用“状态 + 输入”描述
  • 需要报告非法的词法错误

参考资料

  1. Wikipedia(zh):词法分析:词法分析器的构造
  2. Wikipedia(zh):有限状态机:词法分析器背后的模型

思考题答案(仅供参考)

思考题 1

  大致是:跳过空白与注释,查看当前字符的类别,按该类别的规则继续读取字符直到词结束,产出一个词法单元,然后再从下一个字符继续下一轮。

思考题 2

  因为它始终处于某个状态,读入一个字符后据此决定如何处理、状态如何改变,并可能产出词法单元。这种“当前状态 + 输入决定动作与下一状态”的模式,正是状态机的定义。

协议

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

封面图

设计师 | 南国微雪