I am trying to parse Java class files using Java.g4(from Antlr4 github site) grammar and Antlr4. I am trying to parse
typeArguments
: '<' typeArgument (',' typeArgument)* '>'
;
typeArgument
: typeType
| '?' (('extends' | 'super') typeType)?
;
How can I parse strings which are of type "? extends typeType" or "? super typeType" ? Below is my visitor class.
public class TypeArgumentsVisitor extends JavaBaseVisitor<String> {
public String visitTypeArguments(JavaParser.TypeArgumentsContext ctx) {
String delimiter = "";
StringBuilder typArgSb = new StringBuilder("<");
for(TypeArgumentContext typArg :ctx.typeArgument()){
String arg = visit(typArg);
typArgSb.append(delimiter).append(arg);
delimiter = ",";
}
typArgSb.append(">");
return typArgSb.toString();
}
public String visitTypeArgument(JavaParser.TypeArgumentContext ctx) {
TypeTypeVisitor visitor = new TypeTypeVisitor();
TypeTypeContext typTypCtx = ctx.typeType();
if(//condition for first){
// Code for first rule typeType
}
else{
//Code for second rule '?' (('extends' | 'super') typeType)?
}
return null;
}
}
Edit: I have implemented in this way now. Thanks to @Mike
public String visitTypeArgument(JavaParser.TypeArgumentContext ctx) {
//TypeTypeVisitor visitor = new TypeTypeVisitor();
StringBuilder typArg = new StringBuilder();
if(ctx.getChild(0).getText().equalsIgnoreCase("?")){
// '?' (('extends' | 'super') typeType)?
typArg.append("?").append(" ");
TypeTypeContext typTypCtx = ctx.typeType();
if(typTypCtx != null){
typArg.append(ctx.getChild(1).getText()).append(" ");
typArg.append(this.visitTypeType(typTypCtx));
}
}
else{
TypeTypeContext typTypCtx = ctx.typeType();
typArg.append(this.visitTypeType(typTypCtx));
}
return typArg.toString();
}
All the context access functions like ctx.typeType()
and ctx.typeArgument
are simply convenience functions and ultimately end up at the child contexts of a parse context. So for special cases like that (and when you are not sure how to access invidivual elements) iterate over the child contexts to learn what was recognized.
In your case you probably can use the first child context to see if that is a question mark. If so the second alt was choosen, otherwise the first. For the second alt you can then check the second child to see if that is extends
or super
and finally the next child for typeType
(or use the context's typeType()
function for that, as you whish).