ANTLR 4树注入/重写运算符

ANTLR 4树注入/重写运算符,antlr,antlr3,antlr4,Antlr,Antlr3,Antlr4,在ANTLR 3中,您可以执行以下操作: andExpression : (andnotExpression -> andnotExpression) (AND? a=andnotExpression -> ^(AndNode $andExpression $a))* ; 你知道如何在新版本中实现吗?ANTLR 4没有像ANTLR 3那样的重写操作符或output=AST选项。ANTLR 4解析器生成的树是解析树,其形状由语法规则隐式定义

在ANTLR 3中,您可以执行以下操作:

    andExpression
  :  (andnotExpression        -> andnotExpression)
     (AND? a=andnotExpression -> ^(AndNode $andExpression $a))* 
  ;

你知道如何在新版本中实现吗?

ANTLR 4没有像ANTLR 3那样的重写操作符或
output=AST
选项。ANTLR 4解析器生成的树是解析树,其形状由语法规则隐式定义。

如Sam(280Z28)所述,ANTLR 4没有重写运算符

在生成解析器时,ANTLR 4创建一些侦听器类,您可以使用这些类来侦听所有解析器规则的“enter”和“exit”事件

此外,ANTLR 4支持“直接左递归规则”,因此可以在单个规则中定义表达式规则,如下所示:

grammar Expr;

parse
 : expression EOF
 ;

expression
 : '(' expression ')'
 | IDENTIFIER
 | NOT expression
 | expression AND? expression
 | expression OR expression
 ;

LPAREN     : '(';
RPAREN     : ')';
NOT        : 'NOT';
AND        : 'AND';
OR         : 'OR';
IDENTIFIER : [a-zA-Z_] [a-zA-Z_0-9]*;
SPACE      : [ \t\r\n]+ -> skip;
解析输入时,将创建以下解析树:“a b是否为c和d”:

(图像创建使用,谢谢山姆!非常令人印象深刻的IDE,我喜欢它!)

生成解析器和侦听器类:

java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Expr.g4 然后重新生成解析器和侦听器,您将看到
ExprBaseListener
现在是这样的:

公共类ExprBaseListener实现ExprListener{
@重写公共void enter和_EXPR(ExprParser.AND _exprcontextctx){}
@重写public void exitAND_EXPR(ExprParser.AND_EXPRContext ctx){}
@重写公共无效的enterOR_EXPR(ExprParser.OR_EXPRContext ctx){}
@重写公共无效exitOR_EXPR(ExprParser.OR_EXPRContext ctx){}
@重写公共无效enterEXPR(ExprParser.EXPRContext ctx){}
@重写公共void exitEXPR(ExprParser.EXPRContext ctx){}
@重写公共无效enterNOT_EXPR(ExprParser.NOT_EXPRContext ctx){}
@重写public void exitNOT_EXPR(ExprParser.NOT_EXPRContext ctx){}
@重写公共无效enterID_EXPR(ExprParser.ID_EXPRContext ctx){}
@重写公共void exitID_EXPR(ExprParser.ID_EXPRContext ctx){}
@重写公共void enterprase(ExprParser.ParseContext ctx){}
@重写公共void exitpasse(ExprParser.ParseContext ctx){}
@重写公共void entereverylule(ParserRuleContext ctx){}
@重写公共void exitEveryRule(ParserRuleContext ctx){}
@重写公共无效VisiterMinal(TerminalNode节点){}
@重写公共无效visitErrorNode(ErrorNode节点){}
}
即,对于
表达式中的每个标签
创建一个单独的输入和退出方法

现在,假设您只对输入
表达式的事件感兴趣。您可以创建一个自定义类来扩展此
ExprBaseListener
并重写
enterAND\u EXPR

public类ExprWalker扩展了ExprBaseListener{
@凌驾
public void enter和_EXPR(ExprParser.AND _exprcontextctx){
java.util.List e=ctx.expression();
System.out.println(“AND->”+e.get(0.getText()+”,“+e.get(1.getText());
}
}
要测试这一切,请创建一个小型驱动程序类:

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;

public class Main {

    public static void main(String[] args) throws Exception {

        String input = "a b OR NOT c AND d";
        ExprLexer lexer = new ExprLexer(new ANTLRInputStream(input));
        ExprParser parser = new ExprParser(new CommonTokenStream(lexer));
        ParseTree tree = parser.parse();
        ParseTreeWalker walker = new ParseTreeWalker();
        walker.walk(new ExprWalker(), tree);
    }
}
然后运行它:

java -cp antlr-4.0-complete.jar org.antlr.v4.Tool Expr.g4 javac -cp antlr-4.0-complete.jar *.java java -cp .:antlr-4.0-complete.jar Main java-cp antlr-4.0-complete.jar org.antlr.v4.Tool Expr.g4 javac-cp antlr-4.0-complete.jar*.java java-cp.:antlr-4.0-complete.jar Main 之后,您将看到以下内容被打印到控制台:

AND -> a, bORNOTcANDd AND -> NOTc, d 和->a,Bornotcand
还有->NOTc,dThank你的答案是不是意味着我必须像
andExpr:andExpr那样重写它?(AND?andnotExpression)
?Hy Sam!这仍然有效吗?仍然没有重写解析树吗?github()上的ANTLR语法规则声明语法在其文本中包含“rewrite”。。。这是v3留下的吗? AND -> a, bORNOTcANDd AND -> NOTc, d