antlr 4 - 警告:规则包含一个可选块,其中至少有一个替代方法可以匹配空字符串

时间:2014-09-25 14:34:42

标签: antlr antlr4

我使用antlr v4编写一个t-sql解析器。 这个警告有问题吗?

  

“rule'sqlCommit'包含一个可选块,其中至少有一个替代方法可以匹配空字符串”

我的代码:

sqlCommit: COMMIT (TRAN | TRANSACTION | WORK)? id?;

id:
ID  | CREATE | PROC | AS | EXEC | OUTPUT| INTTYPE |VARCHARTYPE |NUMERICTYPE |CHARTYPE |DECIMALTYPE | DOUBLETYPE | REALTYPE
|FLOATTYPE|TINYINTTYPE|SMALLINTTYPE|DATETYPE|DATETIMETYPE|TIMETYPE|TIMESTAMPTYPE|BIGINTTYPE|UNSIGNEDBIGINTTYPE..........
;

ID: (LETTER | UNDERSCORE | RAUTE) (LETTER | [0-9]| DOT | UNDERSCORE)*

在我直接使用词法规则ID而不是sqlCommit中的解析器规则ID之前的版本中。但是在将ID更改为id之后会出现警告。

提示如果您对ID和ID感到困惑:我想使用解析器规则ID而不是ID,因为标识符可能是一个可能已与其他词法分析器规则匹配的文字)< / p>

此致

修改 在“280Z28”的帮助下,我解决了这个问题。在解析器规则中,“id”是一个比需要更多的斜杠:     BITTYPE创建| PROC |     | AS | EXEC | OUTPUT |

所以| |包括解析器规则可以匹配空字符串。

2 个答案:

答案 0 :(得分:6)

来自Google搜索:

ErrorType.EPSILON_OPTIONAL

  

编译器警告154。

     

规则规则包含一个可选块,其中至少有一个替代方法可以匹配空字符串

     

规则包含围绕空替代方案的可选块((...)?)。

     

以下规则会产生此警告。

x  : ;
y  : x?;                                // warning 154
z1 : ('foo' | 'bar'? 'bar2'?)?;         // warning 154
z2 : ('foo' | 'bar' 'bar2'? | 'bar2')?; // ok
     

自:
  4.1

此警告所描述的问题主要是性能问题。通过在可选块中包装零长度字符串,您为语法添加了一个完全不必要的决定(是否进入可选块),这很可能会迫使预测算法通过其最慢的路径。它类似于以下包装Java代码:

if (slowMethodThatAlwaysReturnsTrue()) {
  ...
}

答案 1 :(得分:0)

我正在努力了解此规则如何也受到此警告的影响(使用 antlr 4.7.1)

join_type: (INNER | (left_right_full__join_type)? (OUTER)?)? JOIN;

left_right_full__join_type: LEFT | RIGHT | FULL;

JOIN:        J O I N;
INNER:       I N N E R;
OUTER:       O U T E R;

AFAICT it always 返回 JOIN 并可选地以类型开头。