为什么在java-ANTLR4中ExpressionContext.expression()返回列表而不是单个ExpressionContext

为什么在java-ANTLR4中ExpressionContext.expression()返回列表而不是单个ExpressionContext,java,antlr4,Java,Antlr4,我使用Java.g4语法。表达式解析规则如下所示: expression : primary | expression '.' Identifier | expression '.' 'this' | expression '.' 'new' nonWildcardTypeArguments? innerCreator | expression '.' 'super' superSuffix | expression '.'

我使用Java.g4语法。表达式解析规则如下所示:

expression
    :   primary
    |   expression '.' Identifier
    |   expression '.' 'this'
    |   expression '.' 'new' nonWildcardTypeArguments? innerCreator
    |   expression '.' 'super' superSuffix
    |   expression '.' explicitGenericInvocation
    |   expression '[' expression ']'
    |   expression '(' expressionList? ')'
    |   'new' creator
    |   '(' type ')' expression
    |   expression ('++' | '--')
    |   ('+'|'-'|'++'|'--') expression
    |   ('~'|'!') expression
    |   expression ('*'|'/'|'%') expression
    |   expression ('+'|'-') expression
    |   expression ('<' '<' | '>' '>' '>' | '>' '>') expression
    |   expression ('<=' | '>=' | '>' | '<') expression
    |   expression 'instanceof' type
    |   expression ('==' | '!=') expression
    |   expression '&' expression
    |   expression '^' expression
    |   expression '|' expression
    |   expression '&&' expression
    |   expression '||' expression
    |   expression '?' expression ':' expression
    |   <assoc=right> expression
        (   '='
        |   '+='
        |   '-='
        |   '*='
        |   '/='
        |   '&='
        |   '|='
        |   '^='
        |   '>>='
        |   '>>>='
        |   '<<='
        |   '%='
        )
        expression
    ;
expression
   :   primary
   |   idExpr = expression '.' Identifier
   |   thisExpr = expression '.' 'this'
   //..
   |   leftAndExpression = expression '&&' rightAndExpression = expression
表达式
:主要
|表达式“.”标识符
|表达式''''this'
|表达式“.”“新”非通配符类型参数?内在创造者
|表达式“.”“超级”超级uffix
|表达式“.”显式通用位置
|表达式“[”表达式“]”
|表达式“(“expressionList?”)”
|“新”创造者
|“('type')”表达式
|表达式(“++”|“--”)
|(“+”|“-”|“++”|“--”)表达式
|(“~”|“!”)表达式
|表达式(“*”|“/”|“%”)表达式
|表达式(“+”|“-”)表达式
|表达式(''>'|'>'>'>')表达式
|表达式('='|'>'|'>='
|   '>>>='

|’Short:因为在具体案例中可能涉及到零到两个表达式

  • 如果它是
    ExpressionContext.expression()
    将返回一个空列表,因为没有匹配的表达式
  • 如果它是一个
    表达式&“表达式”
    ,它将返回两个
    表达式
    s
  • 如果它是一个
    表达式'。'标识符
    ,它将返回单个
    表达式
您可以这样做:

expression
    :   primary
    |   expression '.' Identifier
    |   expression '.' 'this'
    |   expression '.' 'new' nonWildcardTypeArguments? innerCreator
    |   expression '.' 'super' superSuffix
    |   expression '.' explicitGenericInvocation
    |   expression '[' expression ']'
    |   expression '(' expressionList? ')'
    |   'new' creator
    |   '(' type ')' expression
    |   expression ('++' | '--')
    |   ('+'|'-'|'++'|'--') expression
    |   ('~'|'!') expression
    |   expression ('*'|'/'|'%') expression
    |   expression ('+'|'-') expression
    |   expression ('<' '<' | '>' '>' '>' | '>' '>') expression
    |   expression ('<=' | '>=' | '>' | '<') expression
    |   expression 'instanceof' type
    |   expression ('==' | '!=') expression
    |   expression '&' expression
    |   expression '^' expression
    |   expression '|' expression
    |   expression '&&' expression
    |   expression '||' expression
    |   expression '?' expression ':' expression
    |   <assoc=right> expression
        (   '='
        |   '+='
        |   '-='
        |   '*='
        |   '/='
        |   '&='
        |   '|='
        |   '^='
        |   '>>='
        |   '>>>='
        |   '<<='
        |   '%='
        )
        expression
    ;
expression
   :   primary
   |   idExpr = expression '.' Identifier
   |   thisExpr = expression '.' 'this'
   //..
   |   leftAndExpression = expression '&&' rightAndExpression = expression

然后您可以按名称访问它们,如
ExpressionContext.leftAndExpression
(如果此选项真的匹配)。

是的,我现在看到了。在我看来,它适用于任何N元操作。它适用于规则中引用的任何子规则。如果您想要一个字段(如
.leftAndExpression
,而不是
.expression()之类的方法)
必须使用名称子规则(子规则前面的
=
部分)。在某些语法错误的情况下,语法标签可能无法分配,即使该元素的节点确实存在于解析树中。出于这个原因,以及内存效率,我建议尽可能避免使用带标签的语法元素。@280Z28出于清晰的原因,我更喜欢它们,但不知道这可能不会被分配你能提供一个链接来描述它们在什么情况下可能无效吗?我假设至少在解析没有错误的情况下,它们总是有效的?