如何省略不重要的节点?

Mic*_*ael 5 java antlr abstract-syntax-tree antlr4

我正在使用 ANTLR 4.9.2 来解析表示汇编指令的语法。

grammar IrohAsm;
main: line* | EOF;

line: (rangedec | instruction | comment)? EOL;

instruction: MNEMONIC firstoperand COMMA secondoperand;
rangedec : range assignment?;
firstoperand : range | mem | REGISTER;
secondoperand : range | mem | IMM | REGISTER;
range : IDENTIFIER OPENBRACKETS IMM CLOSEDBRACKETS;
assignment : EQUALS OPENCURL IMM (COMMA IMM)* CLOSECURL;
mem : AT IMM;
comment : '#' ~EOL*;

WHITESPACE : (' ') -> skip ;

// remember to append \n to input
EOL : '\n';

OPENCURL : '{';
CLOSECURL : '}';
OPENBRACKETS : '[';
CLOSEDBRACKETS : ']';
COMMA : ',';
EQUALS : '=';
AT : '@';
MNEMONIC : ('jmp' | 'add' | 'sub' | 'jez' | 'mov' | 'wrt' | 'get');
REGISTER: ('ab' | 'bb' | 'cb' | 'db');
IMM : DIGITS RADIX?;
RADIX : ('d' | 'b' | 'h');
DIGITS : [0-9]+;
IDENTIFIER: ([a-zA-Z0-9] | '$' | '_' | '\u00C0'..'\uFFFF')+ ;
Run Code Online (Sandbox Code Playgroud)

语法工作正常,但会生成如下所示的树;

解析树示例

当给出以下输入时:

mov ab,ab

Run Code Online (Sandbox Code Playgroud)

正如您所看到的,COMMA 被包含为指令的子项之一。它的位置对于语言来说很重要,但解析后我并不真正关心它。有什么办法可以让我把它完全从最后一棵树上去掉吗?如果是这样,这是否是对语法或解析树的代码的更改?

删除无关节点

我当前获取树的代码:

CharStream inputStream = CharStreams.fromFileName("src/test/assembly/cool.asm");
IrohAsmLexer lexer = new IrohAsmLexer(inputStream);
IrohAsmParser parser = new IrohAsmParser(new CommonTokenStream(lexer));
ParseTree parseTree = parser.main();
Run Code Online (Sandbox Code Playgroud)

Bar*_*ers 5

您的问题归结为:“如何将解析树转换为抽象语法树?”。简单的答案是:“你不能”:)。至少,不使用内置的 ANTLR 机制。您必须遍历解析树(使用 ANTLR 的访问者或侦听器机制)并手动构建 AST。

从解析树更轻松地创建 AST 的功能经常出现在 ANTLR 的 Github 存储库中:

以及 stackoverflow 上: