意外的解析器规则匹配顺序

Unexpected parser rule matching order

使用以下脚本语言语法(a 的子集):

expr
    ...
    | 'regex(' str=expr ',' re=expr ')'  #regexExpr
    ...

regex('s', 're') 这样的表达式解析为以下有意义的树:

regexExpr
   'regex('
   expr: stringLiteral ('s')
   ','
   expr: stringLiteral ('re')
   ')'

我现在正尝试向我的正则表达式函数添加一个选项第三个参数,所以我使用了这个修改后的规则:

'regex(' str=expr ',' re=expr (',' n=expr )? ')'

这导致 regex('s', 're', 1) 以一种我意想不到的方式被解析:

regexExpr
   'regex('
   expr:listExpression
      expr: stringLiteral ('s') 
      ','
      expr: stringLiteral ('re')
   ','
   expr: integerLiteral(1)
   ')'

其中 listExpression 是下面定义的另一个规则 regexExpr:

expr
    ...
    | 'regex(' str=expr ',' re=expr (',' n=expr)? ')' #regexExpr
    ...
    | left=expr ',' right=expr                        #listExpr
    ... 

我认为这个 listExpr 可以定义得更好(通过定义周围的标记),但我现在更改它有兼容性问题。

我不明白这里的解析器规则匹配优先级。有没有一种方法可以将可选的第三个参数添加到 regex() 而不会导致前两个参数被解析为 listExpr?

尝试在两个不同的替代方案中定义它们并使用相同的标签#regexExpr:

expr
 : 'regex' '(' str=expr ',' re=expr ',' n=expr ')' #regexExpr
 | 'regex' '(' str=expr ',' re=expr ')'            #regexExpr
 | left=expr ',' right=expr                        #listExpr
 | ...
 ;