Метод посетителя ANTLR4 для альтернативных правил

Я пытаюсь разобрать файлы классов Java, используя грамматику Java.g4 (с сайта Antlr4 github) и Antlr4. я пытаюсь разобрать

typeArguments
:   '<' typeArgument (',' typeArgument)* '>'
;

typeArgument
:   typeType
|   '?' (('extends' | 'super') typeType)?
;

Как я могу анализировать строки типа «? extends typeType» или «? super typeType»? Ниже представлен мой класс посетителей.

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;
}
}

Изменить: сейчас я реализовал таким образом. Спасибо @Майку

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();
}

person MSS    schedule 22.07.2017    source источник


Ответы (1)


Все функции доступа к контексту, такие как ctx.typeType() и ctx.typeArgument, являются просто вспомогательными функциями и в конечном итоге оказываются в дочерних контекстах контекста синтаксического анализа. Поэтому для таких особых случаев (и когда вы не уверены, как получить доступ к отдельным элементам) перебирайте дочерние контексты, чтобы узнать, что было распознано.

В вашем случае вы, вероятно, можете использовать первый дочерний контекст, чтобы увидеть, является ли это знаком вопроса. Если да, то был выбран второй альт, иначе первый. Для второго alt вы можете затем проверить второй дочерний элемент, чтобы увидеть, является ли он extends или super, и, наконец, следующий дочерний элемент для typeType (или использовать для этого функцию typeType() контекста, как вы хотите).

person Mike Lischke    schedule 23.07.2017