Java antlr4简化数学表达式

Java antlr4简化数学表达式,java,math,expression,antlr4,Java,Math,Expression,Antlr4,我正在做一个项目,用antlr4来简化数学表达式 例如: x^2+2SQRT4*8+x^2-->2x^2+16SQRT4 我已经创建了gramma: grammar Short INT :[0-9]+; POW :'^'; NL :'\n'; WS :[ \t\r]+ -> skip; ID :[a-zA-Z_][a-zA-Z_0-9]*; PLUS :'+'; EQUALS :'='; MINUS :'-'; MULT :'*'; DIV :'/'; LPAR

我正在做一个项目,用antlr4来简化数学表达式

例如:

x^2+2SQRT4*8+x^2-->2x^2+16SQRT4

我已经创建了gramma:

grammar Short
INT :[0-9]+;
POW :'^';
NL  :'\n';
WS  :[ \t\r]+ -> skip;
ID  :[a-zA-Z_][a-zA-Z_0-9]*;

PLUS    :'+';
EQUALS  :'=';
MINUS   :'-';
MULT    :'*';
DIV :'/';
LPAR    :'(';
RPAR    :')';
SQRT    :'SQRT';

input
    : setVar NL input   # ToSetVar
    | plusOrMinus NL? EOF   # Calculate
    ;

setVar
    : ID EQUAL plusOrMinus  # SetVariable
    ;

plusOrMinus
    : plusOrMinus PLUS multOrDiv    # Plus
    | plusOrMinus MINUS multOrDiv   # Minus
    | multorDiv         # ToMultOrDiv
    ;

multOrDiv
    : multOrDiv MULT pow # Multiplication
    | multOrDiv DIV pow  # Division
    | pow                # ToPow
    ;

pow
    : sqrt (POW pow)? # Power
    ;

sqrt
    :unaryMinus (SQRT sqrt)? # Sqrt
    ;
unaryMinus
    : MINUS unaryMinus # ChangeSign
    | atom             # ToAtom
    ;

atom
    | INT                   # Int
    | ID                    # Variable
    | LPAR plusOrMinus RPAR # Braces
    ;
现在我想使用侦听器遍历树并更改输入。 有没有办法从内部更改侦听器使用的输入

更新:

使用您的答案,我使用我的自定义树编写代码:

public class Node {

private double firstN = 0;
private String firstS = null;
private String key = "";
private double secondN = 0;
private String secondS = null;

private boolean brances = false;
private int bbrances = 0;
private int ebrances = 0;
private Node parent = null;
private Node right = null;
private Node left = null;

public Node(Node l, String keye, Node r) {
    left = l;
    key = keye;
    right = r;
}

public Node(int fNumber, String keye, int sNumber) {
    firstN = fNumber;
    secondN = sNumber;
    key = keye;
}

public Node(String fLetter, String keye, int sNumber) {
    firstS = fLetter;
    secondN = sNumber;
    key = keye;
}

public Node(String fLetter, String keye, String sLetter) {
    firstS = fLetter;
    secondS = sLetter;
    key = keye;
}

public Node(int fNumber, String keye, String sLetter) {
    firstN = fNumber;
    secondS = sLetter;
    key = keye;
}

public Node(int fNumber, String fLetter, String keye, int sNumber) {
    firstN = fNumber;
    firstS = fLetter;
    secondN = sNumber;
    key = keye;
}

public Node(int fNumber, String fLetter, String keye, String sLetter) {
    firstN = fNumber;
    firstS = fLetter;
    secondS = sLetter;
    key = keye;
}

public Node(String fLetter, String keye, int sNumber, String sLetter) {
    firstS = fLetter;
    secondN = sNumber;
    secondS = sLetter;
    key = keye;
}

public Node(int fNumber, String keye, int sNumber, String sLetter) {
    firstN = fNumber;
    secondN = sNumber;
    secondS = sLetter;
    key = keye;
}

public Node(int fNumber, String fLetter, String keye, int sNumber,
        String sLetter) {
    firstN = fNumber;
    firstS = fLetter;
    secondN = sNumber;
    secondS = sLetter;
    key = keye;
}

public Node() {
    // TODO Auto-generated constructor stub
}

public double getFirstNumber() {
    return firstN;
}

public double getSecondNumber() {
    return secondN;
}

public String getFirstString() {
    return firstS;
}

public String getSecondString() {
    return secondS;
}

public String getKey() {
    return key;
}

public boolean getBrances() {
    return brances;
}

public int getBBrances() {
    return bbrances;
}

public int getEBrances() {
    return ebrances;
}


public Node getParent() {
    return parent;
}

public Node getLeftNode() {
    return left;
}

public Node getRightNode() {
    return right;
}

public void changeFirstNumber(double number) {
    firstN = number;
    return;
}

public void changeSecondNumber(double number) {
    secondN = number;
    return;
}

public void changeFirstString(String letter) {
    firstS = letter;
    return;
}

public void changeSecondString(String letter) {
    secondS = letter;
    return;
}

public void changeKey(String letter) {
    key = letter;
    return;
}

public void changeBrances(boolean number) {
    brances = number;
    return;
}

public void changeBBrances(int number) {
    bbrances = number;
    return;
}

public void changeEBrances(int number) {
    ebrances = number;
    return;
}

public void changeParent() {
    parent = null;
    return;
}

public void changeParent(Node node) {
    parent = node;
    return;
}

public void changeLeftNode() {
    left = null;
    return;
}

public void changeLeftNode(Node node) {
    left = node;
    return;
}

public void changeRightNode() {
    right = null;
    return;
}

public void changeRightNode(Node node) {
    right = node;
    return;
}

public void display() {
    if (brances == true) {
        System.out.print("(");
        left.display();
        System.out.print(key);
        right.display();
        System.out.print(")");
    } else {
        if (left == null) {
            if (firstN != 0)
                System.out.print(firstN);
            if (firstS != null)
                System.out.print(firstS);
            if (key != null)
                System.out.print(key);
            if (secondN != 0)
                System.out.print(secondN);
            if (secondS != null)
                System.out.print(secondS);
        } else {
            left.display();
            System.out.print(key);
            right.display();
        }
    }
}

public void displayNode() {
      //  System.out.println("brances" + bbrances + " "+ ebrances);
        if (bbrances > 0)   for (int i=0; bbrances > i; i++) System.out.println("(");
        if (left == null && right == null) {
            System.out.println(firstN + firstS + key + secondN + secondS);
            System.out.println("back");
        } else if (left == null){
            System.out.println(firstN + firstS + key + secondN + secondS);
            System.out.println("right");
            right.displayNode();

        }
        else if (right == null){
            System.out.println("left");
            left.displayNode();
            System.out.println(firstN + firstS + key + secondN + secondS);
            System.out.println("back");
        }
        else {
            System.out.println("left");
            left.displayNode();
            System.out.println(key);
            System.out.println("right");
            right.displayNode();
            System.out.println("back");
        }
        if (ebrances > 0)   for (int i=0; ebrances > i; i++) System.out.println(")");

}
}

访客:

import org.antlr.v4.runtime.misc.NotNull;
公共类NewVisitor扩展了HelloBaseVisitor{

    @Override
    public Node visitPlus(@NotNull HelloParser.PlusContext ctx) {
        Node node =new Node();
        Node left = visit(ctx.plusOrMinus());
        left.changeParent(node);
        Node right = visit(ctx.multOrDiv());
        right.changeParent(node);

        node.changeKey("+");
        node.changeLeftNode(left);
        node.changeRightNode(right);

        return node;
    //    return visit(ctx.plusOrMinus()) + visit(ctx.multOrDiv());
    }

    @Override
    public Node visitMinus(@NotNull HelloParser.MinusContext ctx) {
     //   return visit(ctx.plusOrMinus()) - visit(ctx.multOrDiv());
        Node node =new Node();
        Node left = visit(ctx.plusOrMinus());

        Node right = visit(ctx.multOrDiv());
        left.changeParent(node);
        right.changeParent(node);
        node.changeKey("-");
        node.changeLeftNode(left);
        node.changeRightNode(right);


        return node;
    }

    @Override
    public Node visitMultiplication(@NotNull HelloParser.MultiplicationContext ctx) {
       // return visit(ctx.multOrDiv()) * visit(ctx.pow());
        Node node =new Node();
        Node left = visit(ctx.multOrDiv());
        Node right = visit(ctx.pow());
        left.changeParent(node);
        right.changeParent(node);
        node.changeKey("*");
        node.changeLeftNode(left);
        node.changeRightNode(right);



        return node;
    }

    @Override
    public Node visitDivision(@NotNull HelloParser.DivisionContext ctx) {
       // return visit(ctx.multOrDiv()) / visit(ctx.pow());
        Node node =new Node();
        Node left = visit(ctx.multOrDiv());
        Node right = visit(ctx.pow());
        left.changeParent(node);
        right.changeParent(node);
        node.changeKey("/");
        node.changeLeftNode(left);
        node.changeRightNode(right);



        return node;
    }

    @Override
    public Node visitPower(@NotNull HelloParser.PowerContext ctx) {

            Node node =new Node();
            Node left = visit(ctx.sqrt());
            Node right = visit(ctx.pow());

            left.changeParent(node);
            right.changeParent(node);
            node.changeKey("^");
            node.changeLeftNode(left);
            node.changeRightNode(right);



            return node;    


    }
    @Override
    public Node visitSqurt(@NotNull HelloParser.SqurtContext ctx) {

            Node node =new Node();
            Node left = visit(ctx.unaryMinus());
            Node right = visit(ctx.sqrt());

            left.changeParent(node);
            right.changeParent(node);
            node.changeKey("SQRT");
            node.changeLeftNode(left);
            node.changeRightNode(right);

            return node;    
    }

    @Override
    public Node visitBraces(@NotNull HelloParser.BracesContext ctx) {
        Node node =visit(ctx.plusOrMinus());
        node.changeBrances(true);
        return node;
    }

    @Override
    public Node visitInt(@NotNull HelloParser.IntContext ctx) {
        //return Double.parseDouble(ctx.INT().getText());
        Node node = new Node();
        node.changeFirstNumber(Integer.valueOf(ctx.INT().getText()));
        return node;
    }

    @Override
    public Node visitVariable(@NotNull HelloParser.VariableContext ctx) {
     //   return variables.get(ctx.ID().getText());
        Node node = new Node();
        node.changeFirstString(ctx.ID().getText());
        return node;
    }


    @Override
    public Node visitCalculate(@NotNull HelloParser.CalculateContext ctx) {
        return visit(ctx.plusOrMinus());
    }
A现在我遇到了问题,因为在我的树上行走,寻找像x*(5+y)这样的表达式,并将它们更改为x*5+x*y是很困难的。我在想,如果我使用:

INT MULT LPAR plusOrMinus RPAR
但我不知道antlr树应该如何表达

现在我想使用侦听器遍历树并更改输入。有没有办法从内部更改侦听器使用的输入


好吧,目前还不可能。在上面构建自己的结构并将其转换为您的需要更容易。也许以后:

对访问者进行此操作可能更容易。您希望对侦听器进行此操作是有原因的吗?您是对的,我写它是为了使用访问者