如何解决 ANTLR 错误 "Attribute references not allowed in lexer actions"

How to solve ANTLR error "Attribute references not allowed in lexer actions"

看完《The Definitive ANTLR 4 Reference》第10章后,我试着写了一个简单的分析器来获取词法属性,但是报错了。如何获取词法属性?

lexer grammar TestLexer;

SPACE:                       [ \t\r\n]+ -> skip;

LINE:                        INT DOT [a-z]+ {System.out.println($INT.text);};
INT:                         [0-9]+;
DOT:                         '.';
[INFO] 
[INFO] --- antlr4-maven-plugin:4.9.2:antlr4 (antlr) @ parser ---
[INFO] ANTLR 4: Processing source directory /Users/Poison/IdeaProjects/parser/src/main/antlr4
[INFO] Processing grammar: me.tianshuang.parser/TestLexer.g4
[ERROR] error(128): me.tianshuang.parser/TestLexer.g4:5:65: attribute references not allowed in lexer actions: $INT.text
[ERROR] /Users/Poison/IdeaProjects/parser/me.tianshuang.parser/TestLexer.g4 [5:65]: attribute references not allowed in lexer actions: $INT.text

ANTLR4 版本:4.9.2.

参考:
antlr4/actions.md at master · antlr/antlr4 · GitHub
How to get the token attributes in Antlr-4 lexer rule's action · Issue #1946 · antlr/antlr4 · GitHub

尝试 separate the concerns 词法分析器和其他输出问题:这是 Antlr VS 的主要关注点 Bison/Flex。例如,您可以使用本书其他章节中的 visitor/listener 模式。

How can I get the lexical attributes?

你不能:词法分析器规则根本不支持标签。你可能会说,“好吧,但我没有使用任何标签!”。但以下内容:

INT DOT [a-z]+ {System.out.println($INT.text);}

只是一个shorthand表示法:

some_var_name=INT DOT [a-z]+ {System.out.println($some_var_name.text);}

其中 some_var_name 称为 标签

如果你删除嵌入代码({}之间的东西),在INT之前添加一个标签,然后生成一个词法分析器,你会看到以下警告正在打印到标准错误:

labels in lexer rules are not supported in ANTLR 4; actions cannot reference elements of lexical rules but you can use getText() to get the entire text matched for the rule

最后一部分意味着您可以像这样获取词法分析器规则的整个文本:

LINE
 : INT DOT [a-z]+ {System.out.println(getText());}
 ;

但是从词法分析器规则的各个部分抓取文本是不可能的。