Jflex歧义

Jflex ambiguity

我从 jflex 代码中得到了这两条规则:

Bool = true
Ident = [:letter:][:letterdigit:]*

如果我尝试分析单词“trueStat”,它会被识别为 Ident 表达式而不是 Bool。 我怎样才能在 Jflex 中避免这种类型的歧义?

在几乎所有语言中,只有当关键字是一个完整的词时,它才会被识别为关键字。否则,您最终会禁止使用 formatdowntimeendurance 等标识符(它们会以关键字 fordo 和 [=16= 开头) ], 分别)。这对程序员来说是相当混乱的,尽管它不是 unheard-of。词法扫描器生成器,如 Flex 和 JFlex,通常试图使常见情况变得简单;因此,您提供的片段将 trueStat 识别为标识符。但是,如果您真的想将其识别为后跟标识符的关键字,则可以通过向所有关键字添加 trailing context 来实现:

Bool = true/[:letterdigit:]*
Ident = [:letter:][:letterdigit:]*

对于那对模式,true 将匹配 Bool 规则,即使它出现为 trueStat。该模式匹配 true 和紧随其后的任何字母数字字符串,然后倒回输入光标,以便匹配的标记只是 true.

注意像Lex和Flex一样,JFlex接受当前输入位置的最长匹配;如果有多个规则接受此匹配项,则执行与第一个此类规则对应的操作。 (有关匹配算法的稍微更长的解释,请参阅 manual section "How the Input is Matched"。)出于此规则的目的,尾随上下文被视为匹配的一部分(但是,如上所述,然后从匹配中删除)。

此规则的结果是您应该始终将更具体的模式放在它们可能覆盖的一般模式之前,无论特定模式是否使用尾随上下文。所以 Bool 规则必须在 Ident 规则之前。