在离开多年之后回到词法分析器和解析器,出于上下文的目的,我发现自己对状态更改的概念感到困惑。我正在使用Lemon作为解析器,并将自己的词法分析器放在一起。
让我们看一个像这样的输入示例:
[groups]
syscon:
0x000 sysmemremap
0x004 presetctrl
[registers]
sysmemremap:
map 1-0
rsvd 31-2
presetctrl:32
mux 2-0
..etc...
所以"syscon:"one_answers"sysmemremap:"看起来是一样的,但是一个是GROUPNAME,另一个是REGISTERNAME。[组]和[寄存器]之间的上下文变化决定了每个令牌在现实中是什么。
是解析器,是在最好的位置,使上下文的变化?由于解析器没有分段语法(一组语法适用于一组情况,而另一组语法适用于另一组情况),我假定词法分析器应该决定"syscon:"是否生成GROUPNAME,如果模式是这样的话。
编辑:刚刚发现维基百科中总结了这个问题的"lexer hack"条目:
如果没有添加上下文,词法分析器就不能区分类型标识符从其他标识符,因为所有标识符具有相同的格式。.... 解决方案通常包括从将语义符号表返回到词法分析器中。那就是,而不是作为从词法分析器到解析器的纯单向管道,从语义分析到词法分析器有一个反向通道。
除了(这是我的问题)关于解析器对令牌的预读,你能假设什么?如果解析器提前读取更多标记以进行更好的匹配——我希望它至少在某种程度上做到这一点,那么它很可能会遇到这样的情况:解析器中的状态更改对于词法分析器来说太晚了,因为它已经遇到并处理了该标记!
还是我想太多了?我也许能回答我自己的问题。我认为任何依赖解析器内部所做的事情都可能是一个糟糕的计划。
现在我已经找到了Lex和Yacc的书(O'Reilly的那本),Lex部分中的一个例子是一个状态改变的例子——如果它看到"动词"这个词,它就开始定义动词,而不是查找它们。这个工作是在词法分析器中完成的所以我猜就是这样-在词法分析器中完成