ANTLR:自定义解释器需要帮助

ANTLR:自定义解释器需要帮助,antlr,Antlr,我在“收集”数据方面有一些问题。我的代码似乎知道如何访问每个树并正确计算值,但由于结果总是空的,所以缺少了一些东西。谢谢你的帮助 .g4文件: grammar MyParser; ID: [a-z]+ ; Operator_I: '&'; Operator_U: '|'; EQ: '='; expr: '(' expr ')' #wParExpr | expr op=(Operator_I | Operator_

我在“收集”数据方面有一些问题。我的代码似乎知道如何访问每个树并正确计算值,但由于结果总是空的,所以缺少了一些东西。谢谢你的帮助

.g4文件:

grammar MyParser;

ID: [a-z]+ ;

Operator_I: '&';
Operator_U: '|';

EQ: '=';

expr: '(' expr ')'                              #wParExpr 
    | expr op=(Operator_I | Operator_U) expr    #wExpr
    | ID                                        wID
    ;

corr: 'C=' (expr)*                              #Result;
.java代码

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

import java.util.*;

public class EvalVisitor extends MyParserBaseVisitor<Value> {   

    @Override
    public Value visitWParExpr(MyParserParser.WParExprContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("visitWParExpr:"+ctx.getText());
        return visitChildren(ctx);
    }

    @Override
    public Value visitWID(MyParserParser.WIDContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("id:"+ctx.getText());
        String id=ctx.getText();
        Value v = getMemory().get(id);
        l("ret id:"+v.value);
        return v;
    }

    @Override
    public Value visitWExpr(MyParserParser.WExprContext ctx) {

        String left=ctx.expr(0).getText();
        String right=ctx.expr(1).getText();

        if (ctx.getText().contains("(")) {
            return visitChildren(ctx);
        }

        l("visitWExpr, left="+left+",right:"+right);

        String op=ctx.op.getText();         

        Value lefti = visit(ctx.expr(0));           
        Value righti = visit(ctx.expr(1));;
        Value v= null;      

        if (op.equals("&")) {
            v=new Value(lefti.asDouble()+righti.asDouble());
        } else if (op.equals("|")) {
            v=new Value(lefti.asDouble()+righti.asDouble());
        }

        l("return:"+v.asString());
        return v;           
    }

    public void l(String log) {
        System.out.println(log);
    }


    @Override public Value visitResult(MyParserParser.ResultContext ctx) { 

        String s1 = ctx.getText();
        String s2 = ctx.expr(0).getText();

        l("VisitResult:"+s1+", expr="+s2);

        Value v = visit(ctx.expr(0));
        l("VisitResult end:"+v);
        memory.put("result",v);
        return v; 
    }

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

    public EvalVisitor() {
        getMemory().put("a", new Value(new Double(5)));
        getMemory().put("b", new Value(new Double(9)));
        getMemory().put("c", new Value(new Double(12)));                        
    }

    public Map<String, Value> getMemory() {
        return memory;
    }

    public void setValues(Map<String, Value> values) {
        this.memory = values;
    }

}

public static void main(String[] args) throws Exception {
        MyParserLexer lexer = new MyParserLexer(new ANTLRFileStream("c:\\test.mu"));
        MyParserParser parser = new MyParserParser(new CommonTokenStream(lexer));
        ParseTree tree = parser.corr();

        EvalVisitor visitor = new EvalVisitor();
        visitor.visit(tree);

        System.out.println(visitor.getMemory());        
    }
编辑

我想我成功了。原因是我没有在wExpr上下文中进行评估。我不明白我需要计算子树(如果上下文包含“(”),除非我只有可以解析为双精度值的id)

是否可以以更高效的方式实现相同的功能,或者以其他方式实现相同的功能?例如,如果只有一个expr()函数可以获取所有表达式,是否可以实现相同的功能

如果有人感兴趣,下面是修改后的代码:

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

import java.util.*;

public class EvalVisitor extends MyParserBaseVisitor<Value> {   

    @Override
    public Value visitWParExpr(MyParserParser.WParExprContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("visitWParExpr:"+ctx.getText()+", expr:"+ctx.expr().getText());
        String expr= ctx.expr().getText();
        Value v = visit(ctx.expr());
        l("WParExpr:"+v);
        memory.put(expr, v);
        return v;
    }

    @Override
    public Value visitWID(MyParserParser.WIDContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("VisitWID:"+ctx.getText());
        String id=ctx.getText();
        Value v = getMemory().get(id);
        l("ret id:"+v.value);
        return v;
    }

    @Override
    public Value visitWExpr(MyParserParser.WExprContext ctx) {

        String left=ctx.expr(0).getText();
        String right=ctx.expr(1).getText();

        l("visitWExpr:"+ctx.getText()+", left="+left+",right:"+right);

        Value v=null;
        Value lv=null;
        Value rv=null;

        if (ctx.getText().contains("(")) {
            lv = visit(ctx.expr(0));
            rv = visit(ctx.expr(1));            
        } else {                                                                
            lv = visit(ctx.expr(0));            
            rv = visit(ctx.expr(1));;
        }                   


        String op=ctx.op.getText();
        l("lv="+lv+",rv="+rv+",op="+op);
        if (op.equals("&")) {
            v=new Value(lv.asDouble()+rv.asDouble());
        } else if (op.equals("|")) {
            v=new Value(lv.asDouble()*rv.asDouble());
        }

        l("return:"+v.asString());      
        return v;                   
    }

    public void l(String log) {
        System.out.println(log);
    }


    @Override public Value visitResult(MyParserParser.ResultContext ctx) { 

        String s1 = ctx.getText();
        String s2 = ctx.expr().getText();

        l("VisitResult:"+s1+", expr="+s2);

        Value v = visit(ctx.expr());
        l("VisitResult end:"+v);
        memory.put("result",v);
        return v; 
    }

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

    public EvalVisitor() {
        getMemory().put("a", new Value(new Double(5)));
        getMemory().put("b", new Value(new Double(9)));
        getMemory().put("c", new Value(new Double(12)));                        
    }

    public Map<String, Value> getMemory() {
        return memory;
    }

    public void setValues(Map<String, Value> values) {
        this.memory = values;
    }

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

import java.util.*;

public class EvalVisitor extends MyParserBaseVisitor<Value> {   

    @Override
    public Value visitWParExpr(MyParserParser.WParExprContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("visitWParExpr:"+ctx.getText()+", expr:"+ctx.expr().getText());
        String expr= ctx.expr().getText();
        Value v = visit(ctx.expr());
        l("WParExpr:"+v);
        memory.put(expr, v);
        return v;
    }

    @Override
    public Value visitWID(MyParserParser.WIDContext ctx) {
        // TODO Auto-generated method stub
        System.out.println("VisitWID:"+ctx.getText());
        String id=ctx.getText();
        Value v = getMemory().get(id);
        l("ret id:"+v.value);
        return v;
    }

    @Override
    public Value visitWExpr(MyParserParser.WExprContext ctx) {

        String left=ctx.expr(0).getText();
        String right=ctx.expr(1).getText();

        l("visitWExpr:"+ctx.getText()+", left="+left+",right:"+right);

        Value v=null;
        Value lv=null;
        Value rv=null;

        if (ctx.getText().contains("(")) {
            lv = visit(ctx.expr(0));
            rv = visit(ctx.expr(1));            
        } else {                                                                
            lv = visit(ctx.expr(0));            
            rv = visit(ctx.expr(1));;
        }                   


        String op=ctx.op.getText();
        l("lv="+lv+",rv="+rv+",op="+op);
        if (op.equals("&")) {
            v=new Value(lv.asDouble()+rv.asDouble());
        } else if (op.equals("|")) {
            v=new Value(lv.asDouble()*rv.asDouble());
        }

        l("return:"+v.asString());      
        return v;                   
    }

    public void l(String log) {
        System.out.println(log);
    }


    @Override public Value visitResult(MyParserParser.ResultContext ctx) { 

        String s1 = ctx.getText();
        String s2 = ctx.expr().getText();

        l("VisitResult:"+s1+", expr="+s2);

        Value v = visit(ctx.expr());
        l("VisitResult end:"+v);
        memory.put("result",v);
        return v; 
    }

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

    public EvalVisitor() {
        getMemory().put("a", new Value(new Double(5)));
        getMemory().put("b", new Value(new Double(9)));
        getMemory().put("c", new Value(new Double(12)));                        
    }

    public Map<String, Value> getMemory() {
        return memory;
    }

    public void setValues(Map<String, Value> values) {
        this.memory = values;
    }

}
C=((a&b)&(b&c))|(c&c)|((b&a)&(c&b))|(c|c)

VisitResult:C=((a&b)&(b&c))|(c&c)|((b&a)&(c&b))|(c|c), expr=((a&b)&(b&c))|(c&c)|((b&a)&(c&b))|(c|c)
visitWExpr:((a&b)&(b&c))|(c&c)|((b&a)&(c&b))|(c|c), left=((a&b)&(b&c))|(c&c)|((b&a)&(c&b)),right:(c|c)
visitWExpr:((a&b)&(b&c))|(c&c)|((b&a)&(c&b)), left=((a&b)&(b&c))|(c&c),right:((b&a)&(c&b))
visitWExpr:((a&b)&(b&c))|(c&c), left=((a&b)&(b&c)),right:(c&c)
visitWParExpr:((a&b)&(b&c)), expr:(a&b)&(b&c)
visitWExpr:(a&b)&(b&c), left=(a&b),right:(b&c)
visitWParExpr:(a&b), expr:a&b
visitWExpr:a&b, left=a,right:b
VisitWID:a
ret id:5.0
VisitWID:b
ret id:9.0
lv=5.0,rv=9.0,op=&
return:14.0
WParExpr:14.0
visitWParExpr:(b&c), expr:b&c
visitWExpr:b&c, left=b,right:c
VisitWID:b
ret id:9.0
VisitWID:c
ret id:12.0
lv=9.0,rv=12.0,op=&
return:21.0
WParExpr:21.0
lv=14.0,rv=21.0,op=&
return:35.0
WParExpr:35.0
visitWParExpr:(c&c), expr:c&c
visitWExpr:c&c, left=c,right:c
VisitWID:c
ret id:12.0
VisitWID:c
ret id:12.0
lv=12.0,rv=12.0,op=&
return:24.0
WParExpr:24.0
lv=35.0,rv=24.0,op=|
return:840.0
visitWParExpr:((b&a)&(c&b)), expr:(b&a)&(c&b)
visitWExpr:(b&a)&(c&b), left=(b&a),right:(c&b)
visitWParExpr:(b&a), expr:b&a
visitWExpr:b&a, left=b,right:a
VisitWID:b
ret id:9.0
VisitWID:a
ret id:5.0
lv=9.0,rv=5.0,op=&
return:14.0
WParExpr:14.0
visitWParExpr:(c&b), expr:c&b
visitWExpr:c&b, left=c,right:b
VisitWID:c
ret id:12.0
VisitWID:b
ret id:9.0
lv=12.0,rv=9.0,op=&
return:21.0
WParExpr:21.0
lv=14.0,rv=21.0,op=&
return:35.0
WParExpr:35.0
lv=840.0,rv=35.0,op=|
return:29400.0
visitWParExpr:(c|c), expr:c|c
visitWExpr:c|c, left=c,right:c
VisitWID:c
ret id:12.0
VisitWID:c
ret id:12.0
lv=12.0,rv=12.0,op=|
return:144.0
WParExpr:144.0
lv=29400.0,rv=144.0,op=|
return:4233600.0
VisitResult end:4233600.0
{result=4233600.0, a=5.0, c&c=24.0, b=9.0, c=12.0, (a&b)&(b&c)=35.0, c|c=144.0, a&b=14.0, b&a=14.0, (b&a)&(c&b)=35.0, b&c=21.0, c&b=21.0}