意外的解析器规则匹配顺序
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
| ...
;
使用以下脚本语言语法(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
| ...
;