ANTLR4:取决于状态的语义谓词不起作用

时间:2014-03-08 16:56:59

标签: parsing state antlr4 lexer

为了让ANTLR4的词法分析器在一个规则中识别不同类型的令牌,我使用语义谓词。该谓词评估辅助类的静态字段。看看一些语法摘录:

// very simplified

@header {
  import static ParserAndLexerState.*;
}
@members {
  private boolean fooAllowed() {
    System.out.println(fooAllowed);
  }
...
methodField 
: t = type 
  { fooAllowed = false; } 
    id = Identifier 
  { fooAllowed = true; /* do something with t and id*/  }
...

fragment CHAR_NO_OUT_1 : [a-eg-zA-Z_] ;
fragment CHAR_NO_OUT_2 : [a-nq-zA-Z_0-9] ;
fragment CHAR_NO_OUT_3 : [a-nq-zA-Z_0-9] ;
fragment CHAR_1 : [a-zA-Z_] ;
fragment CHAR_N : CHAR_1 | [0-9] ;

Identifier
// returns every possible identifier
: { fooAllowed() }? (CHAR_1 CHAR_N*)
// returns everything but 'foo'
| { !fooAllowed() }? CHAR_NO_OUT_1 (CHAR_NO_OUT_2 (CHAR_NO_OUT_3 CHAR_N*)?)? ;

Identifier现在的行为似乎fooAllowed具有ParserAndLexerState中定义的初始值。因此,如果这是真的Identifier将只使用规则的第一个替代,否则总是第二个。这是一些奇怪的行为,特别是考虑到fooAllowed将正确的值输出到控制台。

ANTLR4中有什么东西可以阻止我在语义谓词中使用全局状态吗?我该如何避免这种行为?

1 个答案:

答案 0 :(得分:0)

ANTLR 4使用具有非确定性终止条件的无界前瞻预测过程。虽然TokenStream实现会懒惰地调用TokenSource.nextToken,但是假设到目前为止所消耗的令牌数量有限是不安全的。

换句话说,使用解析器操作来改变词法分析器行为的实际语义是未定义的。不同版本的ANTLR 4,或者你输入的输入中的细微变化,都会产生完全不同的结果。