I am working on a lexical and syntax analyser that I amimplementing semantic analysis and intermediate representation generation using ANTLR, and I've encountered a problem with my visitor implementation. Specifically, I'm unable to successfully enter the visitExpressFrag method in my EvalVisitor class. This method is crucial for handling expressions in my language.
Here's a simplified version of my problem:
In my EvalVisitor.java, I have the following methods:
@Override
public Integer visitAddMinusOp(CCALParser.AddMinusOpContext ctx) {
Integer left = visit(ctx.expression_fragment(0));
Integer right = visit(ctx.expression_fragment(1));
if (left == null || right == null) {
throw new RuntimeException("Left or right operand is null in AddMinusOp");
}
System.out.println("visitAddMinusOp - Left: " + left + ", Right: " + right);
// ...
}
@Override
public Integer visitExpressFrag(CCALParser.ExpressFragContext ctx) {
if (ctx.expression_fragment() == null) {
System.out.println("visitExpressFrag - Expression fragment context is null.");
} else {
System.out.println("visitExpressFrag - Expression Fragment Text: " + ctx.expression_fragment().getText());
}
// ...
}
However, when running my code, the visitExpressFrag method doesn't seem to be invoked as expected. I added print statements for debugging, but they don't get executed, indicating that the method isn't being entered.
I tried directly calling visitExpressFrag like so:
@Override
public Integer visitAddMinusOp(CCALParser.AddMinusOpContext ctx) {
Integer left = visitExpressFrag(0);
// ...
}
But this results in a compilation error:
EvalVisitor.java:297: error: incompatible types: int cannot be converted to ExpressFragContext
Integer left = visitExpressFrag(0);
^
This is the relevant part of my CCALParser.java (i am not fully sure if this is relevant):
// ExpressFragContext definition
public static class ExpressFragContext extends ExpressionContext {
public Expression_fragmentContext expression_fragment() {
return getRuleContext(Expression_fragmentContext.class,0);
}
// ...
}
And my CCAL.g4 looks like this:
expression : expression_fragment binary_arith_op expression_fragment #AddMinusOp
| LPAREN expression RPAREN #Parens
| ID LPAREN arg_list RPAREN #FunctionCallOp
| expression_fragment #ExpressFrag
;
binary_arith_op : PLUS | MINUS;
expression_fragment
: ID #ID
| MINUS ID #NegatedVariable
| NUMBER #NumberLiteral
| TRUE #TrueLiteral
| FALSE #FalseLiteral
| LPAREN expression RPAREN #NestedExpression
;
I'm not sure how to properly invoke visitExpressFrag or why it's not being called as expected. Any insights or suggestions on how to resolve this issue would be greatly appreciated.
visitExpressFrag(0)is incorrect, because it expects aParserRuleContextas a parameter, yet you provide anintas a parameter.It does with me. Using the visitor like this:
and small driver class:
will print
5as expected.You really don't need a
expression_fragmentrule (which contains a duplicate nested expression) and I suspect you also want to account for-(1+2), not just-ID. Anexpressionrule like this would be better: