You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

《Crafting Compilers》中Switch实现的Tokenizer与形式化等概念的关联困惑

正则语言、词法语法与Switch-Case分词器的关联解析

1. 先把核心概念掰扯清楚

  • 词法语法(Lexical Grammar):说白了就是一套规则,规定怎么把输入的字符流拆成一个个合法的token。比如“标识符必须以字母或下划线开头,后面可以跟字母、数字或下划线”“整数是一串连续的数字”,这些都是词法语法的具体规则。
  • 正则语言(Regular Language):是一类可以用正则表达式描述的语言,对应的计算模型是有限状态自动机(FSM)。它最大的特点是处理不了嵌套/递归结构,只能搞定扁平的字符序列——这也是为什么它刚好适合做词法分析:毕竟token都是扁平的(比如单个运算符、一串数字、一个标识符),不需要嵌套逻辑;但像(1+(2*3))这种带嵌套括号的表达式,正则语言就无能为力了,得靠后面的上下文无关文法来处理。

2. Switch-Case分词器就是正则语言的“代码实现版”

你看到的Java switch case分词器,本质上是手写的有限状态自动机,而有限状态自动机正是正则语言的实现载体——换句话说,那段switch case代码,就是把词法语法的规则(属于正则语言范畴)用硬编码的方式写了出来,只是没给你写形式化的正则表达式而已。

拿书中处理数字的逻辑举例:
当读到一个数字字符时,代码会进入“收集数字”的逻辑,循环读取后续所有数字字符,直到碰到非数字的字符才停下,然后生成一个NUMBER token。这个过程对应的正则规则就是[0-9]+,而switch case的分支判断(比如判断当前字符是数字、字母还是符号),就是在模拟有限状态自动机的状态转移:

  • 初始状态:等着读下一个字符
  • 读到数字:切换到“数字收集状态”
  • 在“数字收集状态”继续读到数字:保持状态,接着收集
  • 读到非数字:退出状态,生成token,回到初始状态

再比如处理标识符:初始状态读到字母/下划线,就切换到“标识符收集状态”,后续只要是字母、数字或下划线就继续收集,直到碰到其他字符为止,生成IDENTIFIER token——对应的正则规则就是[a-zA-Z_][a-zA-Z0-9_]*。

书中没直接给形式化的词法语法定义,是因为它用代码逻辑替代了形式化描述,每一段switch分支、每一次状态跳转,都是在表达词法语法的规则,而这些规则全都是正则语言能覆盖的范围。

3. 为什么它适合扁平token,搞不定嵌套?

因为switch case实现的有限状态自动机,没有“记录嵌套层级”的能力。比如读到左括号(,它只能生成一个LEFT_PAREN token,但没法记住现在是第几层嵌套;而表达式的嵌套(比如((a+b)*c))需要跟踪嵌套深度,这得用到栈结构,而正则语言的模型里没有栈——所以词法分析只负责拆出扁平的token,嵌套逻辑是后面语法分析的活儿。

内容的提问来源于stack exchange,提问作者Finlay Weber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 03:10:23