我在Antlr3中遇到以下(简化)问题。 我有一套带有特殊字符串和常规字符串的语法词法分析器规则。两者都是单引号。特殊字符串符合模式(例如,假设它们只包含字母)。还有一个函数可以确定匹配的字符串是否特殊。空格被忽略。
现在假设例如isSpecial仅对字符串“foo”返回true。如果我正在查看“'foo''bar''123'”,那么词法分析器应为foo生成1个特殊字符串标记,然后生成2个常规字符串标记。
我正在尝试做这样的事情:
SpecialLiteral : { isSpecial(getText()) }?=> '\'' (Letter)+ '\'' ;
StringLiteral : '\'' ( ~('\') )* '\'' ;
这不起作用,因为getText()尚未在门控谓词中填充,因此空字符串传递给isSpecial,“'foo'”变为StringLiteral。
如果我将选通谓词更改为验证谓词,我在isSpecial中有正确的getText,但是当它返回false时(例如,对于“'bar'”),lexer不会回溯并使“'bar'”a StringLiteral,它只是失败。
有可能解决这个问题吗?如果我只是手动编辑词法分析器,它似乎应该是可行的。我们知道mSpecialLiteral之前的位置,所以我们可以回到那里然后像门控谓词一样行动。 如何使用语法/传递给isSpecial?
答案 0 :(得分:0)
您可以在同一规则中匹配两者,然后在文字匹配的类型后进行检查,并在SpecialLiteral
为真时将类型更改为isSpecial(getText())
:
grammar T;
...
tokens {
SpecialLiteral;
}
...
StringLiteral
: '\'' ( ~( '\'' ) )* '\''
{
if(isSpecial(getText())) {
$type = SpecialLiteral;
}
}
;