这可能是我对解析器如何减少而不是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至少。我想了解这是否是我理解的错误。
答案 0 :(得分:1)
Lemon压缩shift表以从表的末尾删除默认操作。据推测,默认操作应该在别处处理,但事实并非如此。您的示例恰好有默认操作,因此表被压缩,YY_SHIFT_COUNT
和lemon.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)