我使用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 |
所以| |包括解析器规则可以匹配空字符串。
答案 0 :(得分:6)
来自Google搜索:
编译器警告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 并可选地以类型开头。