当前位置: 首页 > 知识库问答 >
问题:

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

凤高翰
2023-03-14

我使用antlr v4编写了一个t-sql解析器。此警告是否有问题?

“规则‘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)*

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

(如果您混淆了ID和ID,则提示:我想使用解析器规则ID而不是ID,因为标识符可以是可能已经被其他lexer规则匹配的文本)

当做

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

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

共有2个答案

安毅
2023-03-14

我很难理解这个规则是如何受到这个警告的影响的(使用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它总是返回JOIN,并且可以选择前面有类型。

顾单弓
2023-03-14

从Google搜索:

<代码>错误类型。EPSILON\u可选

编译器警告154。

rule rule包含一个可选块,其中至少有一个可选块可以匹配空字符串

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

以下规则产生此警告。

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

自:4.1

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

if (slowMethodThatAlwaysReturnsTrue()) {
  ...
}
 类似资料:
  • 问题内容: 我正在查询以获取具有特定标题的文档的URI。我的查询是: 的值实际在哪里,因为查询字符串是通过以下方式生成的: 通过上面的查询,我仅获得标题与完全相同的文档。想象一下,是由多个词组成的。我想获得文档,即使文档标题上仅出现一个字形(例如)。我该怎么办? 问题答案: 假设您有一些数据(在Turtle中): 然后,您可以使用类似以下的查询: 得到像 这样做特别整洁的是,由于您正在动态生成模式

  • 本文向大家介绍一个try块在Java中可以有多个catch块吗?,包括了一个try块在Java中可以有多个catch块吗?的使用技巧和注意事项,需要的朋友参考一下 是的,单个try块可以有多个catch块。 示例 以下Java程序包含一个数字数组(显示)。从用户那里,它接受此数组中的两个位置,然后将第一个位置的数字除以第二个位置的数字。 输入值时- 如果选择的位置不在显示的数组中,则抛出Array

  • 我研究了一段时间,还没有找到匹配以下模式的线索(不过,我对regex也很陌生),它看起来像 或 所以我想将上面的字符串匹配并捕获为/abc/foo/bar。现在,“/stop”是一个可选字符串,可以附加在模式的末尾。目标是获得所需的捕获,同时忽略“stop”(如果“stop”存在多次,则在第一个“stop”处停止),同时允许在中间设置尽可能多的斜线(行尾的斜线除外)。 但它与以下任何项都不匹配:

  • 问题内容: 我正在尝试Sphere Online Judge(SPOJ)的“下一个回文”问题,在该问题中,我需要找到最多100万个整数的回文。我曾考虑过使用Java的函数来反转字符串,但是它们是否允许字符串这么长? 问题答案: 你应该能够得到一个长度为String的字符串 总是2147483647(2 31 - 1) (由Java规范定义,阵列的最大尺寸,这对于内部存储String类用途) OR

  • 问题内容: 我想用python伪造一个包。我想定义一些东西,以便代码可以做 somefakepackage是在代码中定义的,它下面的所有内容也是如此。那可能吗?这样做的原因是为了欺骗我的单元测试,因为我在python路径中得到了一个包(或者正如我在标题中所说的,是一个模块),而这实际上只是对此单元测试的模仿。 谢谢! 问题答案: 当然。定义一个类,将所需的内容放入其中,将该类分配给。 您还可以使用

  • 例如,我知道在检查字符串时,可以执行如下操作 但是是否有一种方法来检查一个字符是否匹配一个可能性列表?或者我必须逐一检查,例如 ...等。