如何在解析规则中获取令牌行?

How to get the line of a token in parse rules?

我到处找都找不到解决办法。我是 ANTLR 的新手,对于一项任务,当我的解析器遇到带有行号和标记的未识别标记时,我需要打印出(使用下面的类似语法)一条错误消息。 documentation for antlr4 表示 line 是 Token 对象的一个​​属性,它给出了“[t] 出现令牌的行号,从 1 开始计数;转换为对 getLine 的调用。示例:$ID.line."

我试图在以下代码块中实现这一点:

not_valid : not_digit { System.out.println("Line " + $not_digit.line + " Contains  Unrecognized  Token " $not_digit.text)}; 
not_digit :  ~( DIGIT );

但我一直收到错误

unknown attribute line for rule not_digit in $not_digit.line

我的第一个想法是我正在将词法分析器 token 的属性应用到解析器 rule 因为文档拆分了 Token 和 Rule属性到两个不同的表中。所以我将代码更改为:

not_valid : NOT_DIGIT { System.out.println("Line " + $NOT_DIGIT.line + " Contains  Unrecognized  Token " $NOT_DIGIT.text)}; 
NOT_DIGIT :  ~ ( DIGIT ) ;

还有

not_valid : NOT_DIGIT { System.out.println("Line " + $NOT_DIGIT.line + " Contains  Unrecognized  Token " $NOT_DIGIT.text)}; 
NOT_DIGIT :  ~DIGIT ;

喜欢文档中的示例,但两次我都收到错误

rule reference DIGIT is not currently supported in a set

我不确定我错过了什么。我所有的搜索都在解析器之外的 Java 中找到了如何执行此操作,但我需要在解析器中处理操作代码(我认为这就是它的名称)。

{ ... } 这样的块称为 动作 。您在其中嵌入目标特定代码。所以如果你使用 Java,那么你需要在 {}

之间写 Java

快速演示:

grammar T;

parse
 : not_valid EOF
 ;

not_valid
 : r=not_digit
   {
     System.out.printf("line=%s, charPositionInLine=%s, text=%s\n",
         $r.start.getLine(),
         $r.start.getCharPositionInLine(),
         $r.start.getText()
     );
   }
 ;

not_digit
 :  ~DIGIT
 ;

DIGIT
 : [0-9]
 ;

OTHER
 : ~[0-9]
 ;

使用代码进行测试:

String source = "a";
TLexer lexer = new TLexer(CharStreams.fromString(source));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.parse();

这将打印:

line=1, charPositionInLine=0, text=a