如果集合只有一个条目,则Lemon解析器断言失败

时间:2016-10-07 17:55:41

标签: sqlite parsing debugging assertion lemon

这可能是我对解析器如何减少而不是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.

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

2 个答案:

答案 0 :(得分:1)

Lemon压缩shift表以从表的末尾删除默认操作。据推测,默认操作应该在别处处理,但事实并非如此。您的示例恰好有默认操作,因此表被压缩,YY_SHIFT_COUNTlemon.c不同步,并且触发了断言。

while( n>0 && lemp->sorted[n-1]->iTknOfst==NO_OFFSET ) n--; ,在第4235行附近,您可以注释掉这一行:

#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,
};

生成无压缩的代码:

If i have this          
store   item    tran-code   date
1788    2004635    1      17.05.27
1788    2004635    2      17.05.27
1788    2004635   30      17.05.26
1788    2004635    2      17.05.21
1788    2004635    1      17.05.21
1788    2004635    2      17.05.20
1788    2004635    1      17.05.20

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

答案 1 :(得分:0)