如何使lexer回溯基于Antlr 3(或4)中的谓词



我在Antlr3中有以下(简化的)问题。我有一套特殊字符串和常规字符串语法的lexer规则。两者均为单引号。特殊字符串符合一种模式(例如,假设它们只包含字母)。还有一个函数可以确定匹配的字符串是否特殊。空白被忽略。

现在假设isSpecial只对字符串"foo"返回true。如果我看到的是"'fo'bar''123'",lexer应该为foo生成1个特殊字符串标记,然后生成2个常规字符串标记。

我正在尝试做这样的事情:

SpecialLiteral : { isSpecial(getText()) }?=> ''' (Letter)+ ''' ;
StringLiteral : ''' ( ~('') )* ''' ;

这不起作用,因为getText()还没有填充在门控谓词中,所以空字符串被传递给isSpecial,"'o'"变成StringLiteral。

如果我将门控谓词更改为验证谓词,我在isSpecial中有正确的getText,但当它返回false时(例如,对于"'bar'"),lexer不会回溯并使"'bar''"成为StringLiteral,它只是失败了。

有可能解决这个问题吗?如果我只是手动编辑lexer,它似乎是可行的。我们知道mSpecialLiteral之前的位置,所以我们可以回到那里,然后像选通谓词之后那样操作。如何使用语法/传递给isSpecial的内容?

您可以在同一规则中匹配两者,然后在文字匹配了哪种类型后进行检查,并在isSpecial(getText())为true时将类型更改为SpecialLiteral

grammar T;
...
tokens {
  SpecialLiteral;
}
...
StringLiteral
 : ''' ( ~( ''' ) )* '''
   {
     if(isSpecial(getText())) {
       $type = SpecialLiteral;
     }
   }
 ;

相关内容

  • 没有找到相关文章

最新更新