字符怎样组成词
复习
- 从字符串变为程序:编译器分阶段处理源码
- 语言与文法:用规则描述语言
- 字符串:字符的序列
TL;DR
- 词法分析把字符流切成一个个“词法单元”
- 常见词法单元:关键字、标识符、数字、符号
- 它们的边界由规则决定
- 词法单元是语法分析的基本单位
正文
编译器读进来的,是一长串字符。可它真正想处理的,是“一个个有意义的词”。把这串字符切成词的这一步,叫词法分析(lexical analysis),切出来的每个单位叫词法单元(token)。
切成一个个词
看一句简单的代码:
int x = 42 + y;
在人眼里,它是由几个词拼成的。词法分析要做的,就是把它切成:
int x = 42 + y ;
关键字 标识符 符号 数字 符号 标识符 符号
每切一刀,都要判断这个词属于哪一类。常见的类别有:
- 关键字:语言保留的特殊词,如
int、if - 标识符:变量名、函数名等,如
x、y - 数字:如
42 - 符号:如
=、+、;
切出来的词法单元,通常还带着“类别”和“具体内容”两部分信息,方便后续使用。
边界由规则决定
“切在哪里”不是随便定的,而由语言的规则决定。比如标识符通常是“字母或下划线开头,后面跟字母、数字或下划线”。词法分析器就按这些规则,一路扫过去。
这里有个经典的细节:遇到 ifx 这样的输入,该切成关键字 if 加标识符 x,还是整个标识符 ifx?通常的规则是“最长匹配”:只要能构成一个合法的标识符,就整体当作标识符。所以 ifx 是一个标识符,而不是 if 后面跟 x。
至于空白和注释,词法分析器一般会直接跳过——它们对人有用,对语法结构却没意义。
为什么要先切词
为什么不直接对着字符做语法分析,而要先切词?
因为把问题分层:词法分析只需回答“这个字符序列是什么词”,不用管语法;语法分析则只需面对一个个干净的词,不用再操心字符层面的细节。各管一段,各自简单——这正是编译器分层设计的一贯思路。
切好词之后,就可以进入下一关:把这些词组织成有结构的语法树。
思考题 1
为什么编译器要先把字符流切成词法单元,而不是直接解析字符?
思考题 2
遇到
ifx这样的输入,词法分析器应该切出关键字if还是标识符ifx?依据是什么?
小结
知识点
- 词法分析把字符流切分并分类为词法单元
- 常见类别:关键字、标识符、数字、符号
- 分词依据语言规则,通常采用最长匹配
- 空白与注释一般被跳过
参考资料
- Wikipedia(zh):词法分析:把字符流切分为词法单元
- Wikipedia(zh):词法单元:语法分析处理的基本单位
思考题答案(仅供参考)
思考题 1
因为分层能让问题各自简化:词法分析只负责从字符判断词,语法分析只面对一个个词,不必再处理字符细节。各层职责单一,编译器整体更容易实现和维护。
思考题 2
通常切作标识符 ifx,依据“最长匹配”规则:只要连续的字符能构成一个合法标识符,就整体识别为一个标识符,而不是拆出其中的关键字前缀。
协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
封面图
设计师 | 南国微雪