Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Antlr 意外的解析器规则匹配顺序_Antlr_Antlr4 - Fatal编程技术网

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
)的分解似乎是它工作的原因。上面没有分解的情况仍然符合不希望的方式。谢谢。