0

这可能是我对解析器如何减少的误解,而不是 SQLite 的柠檬解析器中的潜在错误。我一直在试验数据库输入文件的简单语法。该数据库由至少一个条目集的列表组成,例如“命令”或“地图”或...

这是一个不起作用的语法 - 我已经开始创建条目集,到目前为止我只有一个“命令”:

database ::= entrylist.

entrylist ::= entrylist entryset.
entrylist ::= entryset.

entryset ::= command.

/* Commands are in the form %command [arguments] \n */

command ::= CMDNAME cmdargs EOL.
cmdargs ::= cmdargs cmdarg.
cmdargs ::= .

cmdarg ::= INTEGER.
cmdarg ::= TEXT.

如果我使用只输入令牌的测试程序运行它,我会得到:

$ test
Debug: Input 'CMDNAME'
Debug: Shift 'CMDNAME', go to state 3
Debug: Return. Stack=[CMDNAME]
Debug: Input 'INTEGER'
Assertion failed: stateno <= YY_SHIFT_COUNT, file testpar.c, line 513

如果我给入口集一个额外的选择:

entryset ::= command.
entryset ::= map.
...
map ::= MAPNAME EOL.

然后整个事情按预期工作。我认为也许您不允许创建 a::=b 和 b::=c 的情况。你必须有 b ::= c | d 至少。我想了解这是否是我的理解错误。

4

2 回答 2

1

Lemon 压缩班次表以从表的末尾删除默认操作。据推测,默认操作应该在其他地方处理,但事实并非如此。您的示例恰好具有默认操作,因此表被压缩,YY_MAX_SHIFT并且YY_SHIFT_COUNT不同步,并且触发了断言。

lemon.c4235 行附近,您可以注释掉这一行:

while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--;

以防止压缩并防止错误。

生成的压缩代码:

#define YY_MAX_SHIFT         3
#define YY_SHIFT_COUNT    (2)
#define YY_SHIFT_USE_DFLT (13)
static const unsigned char yy_shift_ofst[] = {
 /*     0 */     7,    1,    6,
};

没有压缩的生成代码:

#define YY_MAX_SHIFT         3
#define YY_SHIFT_COUNT    (3)
#define YY_SHIFT_USE_DFLT (13)
static const unsigned char yy_shift_ofst[] = {
 /*     0 */     7,    1,    6,   13,
};

今年早些时候,我将详细信息提交给了 SQLite 邮件列表,但还没有发生任何事情。正确的解决方案可能是继续压缩但处理模板中的默认操作。

于 2017-05-29T17:36:35.267 回答
0

记录到 SQLite 邮件列表的错误:

http://www.mail-archive.com/sqlite-users@mailinglists.sqlite.org/msg99712.html

http://www.mail-archive.com/sqlite-users@mailinglists.sqlite.org/msg99716.html

于 2016-11-13T18:12:18.333 回答