Antlr 添加新标记(重写)以创建不在输入steam上的AST节点的正确方法是什么
我这里有一个关于ANTLR的非常基本的数学表达式语法,感兴趣的是处理括号之间隐含的Antlr 添加新标记(重写)以创建不在输入steam上的AST节点的正确方法是什么,antlr,antlr3,Antlr,Antlr3,我这里有一个关于ANTLR的非常基本的数学表达式语法,感兴趣的是处理括号之间隐含的*运算符,例如(2-3)(4+5)(6*7)实际上应该是(2-3)*(4+5)*(6*7) 给定输入(2-3)(4+5)(6*7)我试图在解析时将缺少的*操作符添加到AST树中,在下面的语法中,我想我已经成功地实现了这一点,但我想这是否是正确的、最优雅的方法 grammar G; options { language = Java; output=AST; ASTLabelType=Common
*
运算符,例如(2-3)(4+5)(6*7)
实际上应该是(2-3)*(4+5)*(6*7)
给定输入(2-3)(4+5)(6*7)
我试图在解析时将缺少的*
操作符添加到AST树中,在下面的语法中,我想我已经成功地实现了这一点,但我想这是否是正确的、最优雅的方法
grammar G;
options {
language = Java;
output=AST;
ASTLabelType=CommonTree;
}
tokens {
ADD = '+' ;
SUB = '-' ;
MUL = '*' ;
DIV = '/' ;
OPARN = '(' ;
CPARN = ')' ;
}
start
: expression EOF!
;
expression
: mult (( ADD^ | SUB^ ) mult)*
;
mult
: atom (( MUL^ | DIV^) atom)*
;
atom
: INTEGER
| (
OPARN expression CPARN -> expression
)
(
OPARN expression CPARN -> ^(MUL expression)+
)*
;
INTEGER : ('0'..'9')+ ;
WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
此语法在AntlWorks中输出正确的AST树:
我只是刚刚开始掌握解析和ANTLR,没有太多经验,所以非常感谢您的反馈
提前谢谢!卡尔首先,考虑到您以前从未使用过ANTLR,您做得非常出色 您可以省略默认值
language=Java
和ASTLabelType=CommonTree
。所以你可以做:
options {
output=AST;
}
此外,不必分别为每个操作符指定根节点。所以你不必做:
(ADD^ | SUB^)
但以下几点:
(ADD | SUB)^
就够了。由于只有两个操作符,没有太大区别,但是在实现关系操作符(
=
,
和哇,谢谢你的帮助,巴特,太棒了!我必须先研究一下,让它消化一下!@橡皮擦头IRL,是的,我可以想象。重写规则->^(MUL$atom$e)
可能会引起一些头痛。要知道,$atom
引用的是匹配的整个规则,所以第一个OPARN表达式CPARN
就是因为它才被包含在内的。现在明白了!我想AntlWorks和ANTLR IDE让我大吃一惊,因为我注意到有些语法不会在那些IDE中运行,但在Java中运行得很好,我猜是这样的他们自己并不完全支持ANTLR的语法,或者有一点错误。@EraserHead IRL,是的,我只使用ANTLRWorks编辑语法,而不是测试解析器,因为解释器有很多错误。最好使用单独的类IMO来完成。
atom
: INTEGER
| (
OPARN expression CPARN -> expression
)
(
OPARN e=expression CPARN -> ^(MUL $atom $e)
)*
;