我遇到了一些问题"收集"数据。似乎我的代码知道如何访问每个树并正确计算值,但缺少某些东西,因为结果始终为null。感谢帮助。
.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());
}
输出:
VisitResult:C=(a&b)&(b&c)|(c&c), expr=(a&b)&(b&c)|(c&c)
visitWParExpr:(a&b)
visitWExpr, left=a,right:b
id:a
ret id:5.0
id:b
ret id:9.0
return:14.0
visitWParExpr:(b&c)
visitWExpr, left=b,right:c
id:b
ret id:9.0
id:c
ret id:12.0
return:21.0
visitWParExpr:(c&c)
visitWExpr, left=c,right:c
id:c
ret id:12.0
id:c
ret id:12.0
return:24.0
VisitResult end:null
{result=null, a=5.0, b=9.0, c=12.0}
修改
我想我已经开始工作了。原因是我没有在wExpr上下文中进行评估。我不明白我需要评估子树(如果上下文包含&#34;(&#34;)除非我只有可用的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;
}
}
示例输出:string:
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}