Let's have two grammars:
grammar Grammar1;
NUMBER : [0-9]+ ;
WS : [ \r\n\t]+ -> skip ;
root : expr EOF
;
expr : '*' expr expr # Multiplication
| expr '+' expr # Addition
| NUMBER # Number
;
grammar Grammar2;
NUMBER : [0-9]+ ;
WS : [ \r\n\t]+ -> skip ;
root : expr EOF
;
expr : NUMBER '!' # Factorial
| NUMBER '^' NUMBER # Exponentiation
| expr '+' expr # Addition
| NUMBER # Number
;
We can see that they both share a number and addition while everything else is different.
The two convertors into an Expression AST will look like this:
public class Grammar1Converter extends Grammar1BaseVisitor<Expression> {
public Expression visitRoot(Grammar1Parser.RootContext ctx);
public Expression visitMultiplication(Grammar1Parser.MultiplicationContext ctx);
public Expression visitNumber(Grammar2Parser.NumberContext ctx);
public Expression visitAddition(Grammar1Parser.AdditionContext ctx);
}
public class Grammar2Converter extends Grammar2BaseVisitor<Expression> {
public Expression visitRoot(Grammar2Parser.RootContext ctx);
public Expression visitFactorial(Grammar2Parser.FactorialContext ctx);
public Expression visitExponentiation(Grammar2Parser.ExponentiationContext ctx);
public Expression visitNumber(Grammar2Parser.NumberContext ctx);
public Expression visitAddition(Grammar2Parser.AdditionContext ctx);
}
Both grammars share the structure they're converted into. How can we implement a shared converter for the visitNumber and visitAddition? Both converters already extend an abstract class so the basic inheritance is out of question. Both convertors have a different context type in the argument so we can't just have a general visitor for the shared method as we would have to convert between the contexts. Is there a way of avoiding repeating the code?