Antlr 意外的解析器规则匹配顺序
使用以下(脚本语言的子集)语法:Antlr 意外的解析器规则匹配顺序,antlr,antlr4,Antlr,Antlr4,使用以下(脚本语言的子集)语法: expr ... | 'regex(' str=expr ',' re=expr ')' #regexExpr ... 类似于regex('s','re')的表达式解析为以下树,这很有意义: regexExpr 'regex(' expr: stringLiteral ('s') ',' expr: stringLiteral ('re') ')' 我现在尝试向我的正则表达式函数添加一个选项第三个参数,
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
...
expr
: 'regex' '(' str=expr ',' re=expr ',' n=expr ')' #regexExpr
| 'regex' '(' str=expr ',' re=expr ')' #regexExpr
| left=expr ',' right=expr #listExpr
| ...
;
我认为可以更好地定义这个listExpr
(通过定义周围的标记),但我现在对它的兼容性有一些顾虑
我不理解这里匹配优先级的解析器规则。有没有一种方法可以将可选的第三个参数添加到
regex()
,而不将前两个参数解析为listExpr
?尝试在两个单独的备选方案中使用相同的标签定义它们\regexxpr
:
expr
...
| 'regex(' str=expr ',' re=expr (',' n=expr)? ')' #regexExpr
...
| left=expr ',' right=expr #listExpr
...
expr
: 'regex' '(' str=expr ',' re=expr ',' n=expr ')' #regexExpr
| 'regex' '(' str=expr ',' re=expr ')' #regexExpr
| left=expr ',' right=expr #listExpr
| ...
;
有趣。
regex
和(
)的分解似乎是它工作的原因。上面没有分解的情况仍然符合不希望的方式。谢谢。