ANTLR4备用规则的访问者方法

时间:2017-07-22 12:02:58

标签: java parsing antlr4 visitor-pattern

我正在尝试使用Java.g4(来自Antlr4 github站点)语法和Antlr4解析Java类文件。我正在尝试解析

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

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

如何解析#34;类型的字符串?扩展typeType&#34;或&#34;? super typeType&#34; ?以下是我的访客班。

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

编辑:我现在已经以这种方式实施了。感谢@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();
}

1 个答案:

答案 0 :(得分:0)

所有上下文访问函数(如ctx.typeType()ctx.typeArgument)都只是简便函数,最终最终会出现在解析上下文的子上下文中。因此,对于像这样的特殊情况(以及当您不确定如何访问invidivual元素时)迭代子上下文以了解识别的内容。

在您的情况下,您可能可以使用第一个子上下文来查看这是否是问号。如果是这样,则选择第二个alt,否则为第一个。对于第二个替代,您可以检查第二个孩子,看看它是extends还是super,最后是typeType的下一个孩子(或使用上下文的typeType()功能那个,就像你说的那样。)