ANTLR4 - 分配给不是集合的块的标签

Cor*_* Wu 2 antlr antlr4

我收到错误label assigned to a block which is not a set。我的标签,会出现此错误:childleftrightfirst,和last。我正在做的是为一组备选方案分配一个标签;这不应该被支持吗?

我的语法片段:

expr:
      unaryExpr '(' child=(stat | expr | NUMBER) ')'                                                #labelUnaryExpr
    | binaryExpr '(' left=(stat | expr | constant) ',' right=(stat | expr | constant) ')'           #labelBinaryExpr
    | multipleExpr '(' first=(stat | expr | constant) (',' rest=(stat | expr | constant))+ ')'      #labelMultipleExpr
    ;   
Run Code Online (Sandbox Code Playgroud)

GRo*_*erg 6

问题是替代元素可以是不同的类型:终端节点、各种规则上下文和两者的列表。 NUMBER并且expr显然是不同的类型。所以分配给单个标签(单个变量类型)通常是不可能的。

将备选方案提取为子规则:

....
| multipleExpr '(' first=altExpr (',' rest+=altExpr)+ ')'
;

altExpr   : stat | expr | constant ;
Run Code Online (Sandbox Code Playgroud)

在这种特殊情况下,您不一定需要标签,因为 altExpr 将在 multipleExpr 上下文类中的列表中捕获——列表的第一个元素将始终是第一个遇到的 altExpr。

查看生成的解析器中的相关上下文类,以了解标签是如何实现为变量的。

并且,在构建标签列表时,+=需要赋值操作。

更新:

侦听器将有一个方法

enterMultipleExpr(YourParser.MultipleExprContext ctx);
Run Code Online (Sandbox Code Playgroud)

YourParser 嵌入类 MultipleExprContext 将有一个方法

    public List<AltExprContext> altExpr() {
        return getRuleContexts(AltExpr.class);
    }
Run Code Online (Sandbox Code Playgroud)

所以ctx.altExpr()返回列表。如果你实现了标签,上下文也将有公共变量:

public AltExprContext first;
public List<AltExprContext> rest;
Run Code Online (Sandbox Code Playgroud)

再次查看生成的解析器中的相关上下文类,以了解您必须使用哪些生成的访问器。