Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/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 - Fatal编程技术网

Antlr 为什么这个规则中有递归溢出?

Antlr 为什么这个规则中有递归溢出?,antlr,Antlr,这是对这个问题的“跟进”:(知道root规则现在已重命名为atom) 在我的ANTLR语法中,我现在尝试添加对强制转换的支持: cast : '(' type ')' atom -> ^(CAST type atom); 现在,我需要让它成为价值树的一部分。由于强制转换本身是原子的,可以作为层次结构的基础,并且可以用于任何二进制操作(因子、求和、比较),因此我认为它必须符合原子(以前是根)规则 幸运的是,这次一切似乎都足够了。但是,我得到了从type到type的无限递归: type :

这是对这个问题的“跟进”:(知道
root
规则现在已重命名为
atom

在我的ANTLR语法中,我现在尝试添加对强制转换的支持:

cast : '(' type ')' atom -> ^(CAST type atom);
现在,我需要让它成为价值树的一部分。由于强制转换本身是原子的,可以作为层次结构的基础,并且可以用于任何二进制操作(因子、求和、比较),因此我认为它必须符合
原子
(以前是
)规则

幸运的是,这次一切似乎都足够了。但是,我得到了从
type
type
的无限递归:

type : name=IDENTIFIER (LESSER (generics+=type (SEPARATOR generics+=type)*) GREATER)? -> ^(TYPE $name ^(GENERICS $generics*));
[ruleatom]备选方案1[cast]:在匹配诸如PAREN_OPEN IDENTIFIER LESSER IDENTIFIER LESSER IDENTIFIER LESSER IDENTIFIER LESSER IDENTIFIER{LESSER,SEPARATOR}之类的输入后,由于从类型到类型的递归溢出,决策无法预测接下来会发生什么


这个案例反映了一些东西,比如
(x),我甚至不想说ANTLR的错误消息(全部)是无法穿透的,但是是的,这个错误是

在这种情况下,ANTLR在区分关系表达式
IDENTIFIER
IDENTIFIER
之间存在问题,后者是
类型的一部分

您可以通过更改泛型类型的开头,使其与关系LT表达式的开头不同来验证这一点:

type
 : IDENTIFIER ('@' (type (',' type)*) '>')?
 ;
或者将LT符号保留在泛型类型中,但从
atom
规则中删除
标识符

type
 : IDENTIFIER ('<' (type (',' type)*) '>')?
 ;

atom
 : cast 
 //| IDENTIFIER
 | SELF
 | literal
 | constructor
 | call
 | indexer
 | '('! value ')'!
 ;
这迫使解析器首先向前看,并确保确实存在要匹配的
cast
备选方案,如果没有,则在
atom
规则中使用后面的备选方案

但更好的选择是不允许语法匹配关系表达式,如:

a < b < c
做:


然后,在
atom
规则中,您不需要在
type
前面使用谓词,而且运算符的优先级是正确的。

1.4.3这里:感谢您的深入解释和建议。我没有考虑到关系运算符的优先级,像
a
a==b!=c
是允许的。你解决这些问题的理由是什么?不客气@LazloBonin。不确定我是否理解:你是说我回答关于ANTLR的问题的理由是什么,等等?
atom
 : (cast)=> cast 
 | IDENTIFIER
 | SELF
 | literal
 | constructor
 | call
 | indexer
 | '('! value ')'!
 ;
a < b < c
value      : comparison;
comparison : sum (comparison_operator^ sum)?;
...

comparison_operator : EQUAL | NOT_EQUAL | GREATER | LESSER
                    | GREATER_OR_EQUAL | LESSER_OR_EQUAL 
                    | AND | OR
                    ;
value : or;
or    : and (OR^ and)*;
and   : eq (AND^ eq)*;
eq    : rel ((EQUAL | NOT_EQUAL)^ rel)?; // note the '?' and no '*'
rel   : sum ((GREATER | LESSER | GREATER_OR_EQUAL | LESSER_OR_EQUAL)^ sum)?; // note the '?' and no '*'
sum   : factor ((PLUS | MINUS)^ factor)*;
...