微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

测试我的语法程序时出现错误

如何解决测试我的语法程序时出现错误

我正在使用ANTLR4创建编程语言来创建Simlpe计算器。 我一直在寻找这个错误,我一直在寻找,但是似乎无法解决它,有什么建议/帮助吗?

我一直在浏览我的java文件,但是不明白为什么它会给我这个错误

$ make test 
Exception in thread "main" java.lang.NullPointerException 
at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) 
at Interpreter.visitWhileLoop(main.java:79) 
at Interpreter.visitWhileLoop(main.java:47) 
at implParser$WhileLoopContext.accept(implParser.java:377) 
at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) 
at Interpreter.visitStart(main.java:52)
at Interpreter.visitStart(main.java:47) 
at implParser$startContext.accept(implParser.java:123) 
at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) 
at main.main(main.java:38) 
make: *** [Makefile:18: test] Error 1

这是我对main.java实现语法方法的部分:

import org.antlr.v4.runtime.tree.ParseTreeVisitor;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import org.antlr.v4.runtime.CharStreams;
import java.io.IOException;
public class main {
public static void main(String[] args) throws IOException{

// we expect exactly one argument: the name of the input file
if (args.length!=1) {
    System.err.println("\n");
    System.err.println("Simple calculator\n");
    System.err.println("=================\n\n");
    System.err.println("Please give as input argument a filename\n");
    System.exit(-1);
}
String filename=args[0];

// open the input file
CharStream input = CharStreams.fromFileName(filename);
    //new ANTLRFileStream (filename); // depricated

// create a lexer/scanner
implLexer lex = new implLexer(input);

// get the stream of tokens from the scanner
CommonTokenStream tokens = new CommonTokenStream(lex);

// create a parser
implParser parser = new implParser(tokens);

// and parse anything from the grammar for "start"
ParseTree parseTree = parser.start();

// Construct an interpreter and run it on the parse tree
Interpreter interpreter = new Interpreter();
interpreter.visit(parseTree);
}
}
// We write an interpreter that implements interface
// "implVisitor<T>" that is automatically generated by ANTLR
// This is parameterized over a return type "<T>" which is in our case
// simply a Double.
class Interpreter extends AbstractParseTreeVisitor<Double> implements implVisitor<Double> {
static Environment env=new Environment();
public Double visitStart(implParser.StartContext ctx){
for(implParser.CommandContext c:ctx.cs) visit(c);
return null;
};

public Double visitSingleCommand(implParser.SingleCommandContext ctx){
return visit(ctx.c);
}

public Double visitMultipleCommands(implParser.MultipleCommandsContext ctx){
for(implParser.CommandContext c:ctx.cs) visit(c);
return null;
}

public Double visitAssignment(implParser.AssignmentContext ctx){
Double v=visit(ctx.e);
env.setvariable(ctx.x.getText(),v);
return null;
}

public Double visitOutput(implParser.OutputContext ctx){
Double v=visit(ctx.e);
System.out.println(v);
return null;
}

public Double visitWhileLoop(implParser.WhileLoopContext ctx){
while(visit(ctx.c).equals(1.0)){
    visit(ctx.p);
}
return null;
}
public Double visitIfStatement(implParser.IfStatementContext ctx){
while(visit(ctx.c1).equals(1.0)){
    visit(ctx.p1);
}
return null;
}
/*public Double visitSubstraction(implParser.SubstractionContext ctx) {
return visit(ctx.e1);
}
public Double visitDivison(implParser.DivisonContext ctx) {
return visit(ctx.e1);
}*/
 public Double visitMUL(implParser.MULContext ctx) {
    Double left = this.visit(ctx.expr(0));
    Double right = this.visit(ctx.expr(1));
    switch (ctx.op.getType()) {
        case implParser.MULT:
            return left * right;
        case implParser.DIV:
            return left / right;
        case implParser.MOD:
            return left % right;
        default:
            throw new RuntimeException("unkNown operator: " + implParser.tokenNames[ctx.op.getType()]);
    }
}

public Double visitOP(implParser.OPContext ctx) {
    Double left = this.visit(ctx.expr(0));
    Double right = this.visit(ctx.expr(1));
    switch (ctx.op.getType()) {
        case implParser.PLUS:
            //return left && right;
                    return left + right;
        case implParser.MINUS:
            return left - right;
        default:
            throw new RuntimeException("unkNown operator: " + implParser.tokenNames[ctx.op.getType()]);
    }
}

public Double visitParenthesis(implParser.ParenthesisContext ctx){
return visit(ctx.e);
};

public Double visitvariable(implParser.VariableContext ctx){
return env.getvariable(ctx.x.getText());
};
/*public Double visitAddition(implParser.AdditionContext ctx){
return visit(ctx.e1)+visit(ctx.e2);
};

public Double visitMultiplication(implParser.MultiplicationContext ctx){
return visit(ctx.e1)*visit(ctx.e2);
};
*/
public Double visitConstant(implParser.ConstantContext ctx){
return Double.parseDouble(ctx.c.getText()); 
};

public Double visitUnequal(implParser.UnequalContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitEqual(implParser.EqualContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitLess(implParser.LessContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitLessOrEqual(implParser.LessOrEqualContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitGreater(implParser.GreaterContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitGreaterOrEqual(implParser.GreaterOrEqualContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitAND(implParser.ANDContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitOR(implParser.ORContext ctx){
Double v1=visit(ctx.e1);
Double v2=visit(ctx.e2);
if (v1.equals(v2))  return 0.0;
else return 1.0;
}
public Double visitNum(implParser.NumContext ctx){
    return null;
}
}
/*
class Expr{};
class var extends Expr{}; //Subclass
class Const extends Expr{}; //Subclass
class Multiplication extends Expr{}; //Subclass*/

以下错误是:

public Double visitStart(implParser.StartContext ctx){
[52]for(implParser.CommandContext c:ctx.cs) visit(c);
return null;
};

public Double visitWhileLoop(implParser.WhileLoopContext ctx){
while(visit(ctx.c).equals(1.0)){
[79]  visit(ctx.p);
}

解决方法

异常消息显示:

Exception in thread "main" java.lang.NullPointerException 
at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) 
at Interpreter.visitWhileLoop(main.java:79) 
at Interpreter.visitWhileLoop(main.java:47) 
at implParser$WhileLoopContext.accept(implParser.java:377) 
...

这意味着AbstractParseTreeVisitor的visit()方法中发生了NullPointerException。它是由visitWhileLoop()上下文中的调用引起的,该调用本身是从visitWhileLoop()上下文中调用的。它看起来像递归调用,但是错误的行号使它看起来好像有两个单独的方法。您发布的代码似乎只有一种叫做visitWhileLoop()的方法,所以我不确定那里发生了什么。

public Double visitWhileLoop(implParser.WhileLoopContext ctx){
    while(visit(ctx.c).equals(1.0)){
        visit(ctx.p);
    }
    return null;
}

有两次从visit()visitWhileLoop()的呼叫。我猜想其中一个或多个正在将null传递给visit()。换句话说,ctx.cctx.p的值为null

您可以在IDE的调试器中使用visitWhileLoop()方法的断点来运行此程序,以查找有关正在发生的事情的更多信息。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。