【问题标题】:ANTLR: expression evaluation with custom object and methodANTLR:使用自定义对象和方法进行表达式评估
【发布时间】:2015-05-27 06:18:12
【问题描述】:

是否可以在 Java 程序内部使用 ANTLR 并使用自定义类来执行实际操作?我希望能够解析简单的表达式并为我自己的 Java 类中定义的它们执行自定义操作。

示例表达式:

((AB1 op1 BC2) op2 BB)

AB1、BC2 和 BB 代表自定义 Java 类,例如 MyObj。 op1 和 op2 是非常简单的操作,可以认为是 + 或 -

假设我有:

interface Operation {
    public MyObj operation(MyObj obj1, MyObj obj2);
}

class SomeOperation implements Operation {
    public MyObj operation(MyObj obj1, MyObj obj2) {

    };
}

class Some2Operation implements Operation {
    public MyObj operation(MyObj obj1, MyObj obj2) {

    };
}

SomeOperation 是指 op1,Some2Operation 是指 op2。

在评估表达式之前,AB1、BC2 和 BB 的实际对象被赋值。

如果有比使用 ANTLR 更简单/更简单的方法来完成此任务,请告诉我。

编辑:在这里继续...

grammar MyTest;

ID: [a-z]+;

Operator_I: 'I';
Operator_U: 'U';


prog:   (expr)* #myProg;
expr:   expr op=(Operator_I | Operator_U) expr  #myExpr
    | ID    #myID
    |   '(' expr ')' #myWithPar
    ;


import org.antlr.v4.runtime.misc.NotNull;
import org.antlr.v4.runtime.tree.TerminalNode;

import java.util.*;

public class EvalVisitor extends MyTestBaseVisitor<Value> {

    @Override
    public Value visitMyProg(MyTestParser.MyProgContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("prog:"+ctx.getText());
        return super.visitMyProg(ctx);
    }

    @Override
    public Value visitMyWithPar(MyTestParser.MyWithParContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("par:"+ctx.getText());
        return super.visitMyWithPar(ctx);
    }

    @Override
    public Value visitMyID(MyTestParser.MyIDContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("id:"+ctx.getText());
        return super.visitMyID(ctx);
    }

    @Override
    public Value visitMyExpr(MyTestParser.MyExprContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("expr:"+ctx.getText());
        return super.visitMyExpr(ctx);
    }

    private Map<String, Value> memory = new HashMap<String, Value>();   
    private Map<String, Value> values = new HashMap<String, Value>();

    public EvalVisitor() {
        values.put("a", new Value(new Double(5)));
        values.put("u", new Value(new Double(9)));

    }

}

 public static void main(String[] args) throws Exception {
        MyTestLexer lexer = new MyTestLexer(new ANTLRFileStream("c:\\test.mu"));
        MyTestParser parser = new MyTestParser(new CommonTokenStream(lexer));
        ParseTree tree = parser.prog();
        EvalVisitor visitor = new EvalVisitor();
        visitor.visit(tree);
    }

test.mu 包含:

(aIu)U(aUu)

程序的输出:

prog:(aIu)U(aUu)
expr:(aIu)U(aUu)
par:(aIu)
expr:aIu
id:a
id:u
par:(aUu)
expr:aUu
id:a
id:u

【问题讨论】:

    标签: expression antlr


    【解决方案1】:

    ANTLR 只为您的语言提供解析器。实际的解释器(评估您的输入)取决于您。您可以使用 ANTLR 的访问者轻松创建解释器。可以在此问答中找到演示:If/else statements in ANTLR using listeners

    如果您不想自己编写解释器,则需要找到适合您需求的库。有关可用库的列表,请参阅此问答:Evaluating a math expression given in string form

    【讨论】:

    • 在主要问题区域添加了更多数据。我很快就完成了基本的事情。为此非常感谢。谢谢!我想知道在实际回调函数 visitMyExpr 等中要做什么。我应该在哈希表中保存“expr”的值还是什么?我的语法也正确吗?我也想这样做: ((aUb)Ic) 现在看来它会省略最后一个 'Ic)' ?
    • @knocker_d,我现在没时间。我建议不要编辑您的原始问题(这是一个简短的问题,因此我回答了它),而是建议提出一个新问题。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 2011-06-21
    • 2016-09-12
    • 1970-01-01
    • 2017-10-04
    • 2016-05-04
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    相关资源
    最近更新 更多