I'm in the process of creating a programming language using ANTLR4 to create a simlpe calculator. I am pretty much stuck on this error, I've been looking around, but can't seem to fix it, any suggestions/help?
I've been looking through my java file, but can't understand why it gives me that error.
$ 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
Here's the part where I implement my grammar methods to my 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*/
The following errors are:
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);
}