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

fli*_*eid 6 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)*
Run Code Online (Sandbox Code Playgroud)

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

(如果你对ID和id感到困惑,请提示:我想使用解析器规则id而不是ID,因为标识符可以是一个可能已被其他词法分析器规则匹配的文字)

问候

编辑 在"280Z28"的帮助下,我解决了这个问题.在解析器规则中,"id"是一个比需要更多的斜杠:BITTYPE | CREATE | PROC | | AS | EXEC |输出|

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

Sam*_*ell 6

来自Google搜索:

ErrorType.EPSILON_OPTIONAL

编译器警告154.

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

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

以下规则会生成此警告.

x  : ;
y  : x?;                                // warning 154
z1 : ('foo' | 'bar'? 'bar2'?)?;         // warning 154
z2 : ('foo' | 'bar' 'bar2'? | 'bar2')?; // ok
Run Code Online (Sandbox Code Playgroud)

自:
4.1

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

if (slowMethodThatAlwaysReturnsTrue()) {
  ...
}
Run Code Online (Sandbox Code Playgroud)