0

我有一个基本上看起来像这样的语法:

start ::= groups.
groups ::= groups group.
groups ::= group.
group(A) ::= IDENTIFIER identparams CURLY_OPEN assignments CURLY_CLOSE SEMICOLON.
group(A) ::= IDENTIFIER CURLY_OPEN assignments CURLY_CLOSE SEMICOLON.
assignments ::= assignments assignment.
assignment ::= IDENTIFIER ASSIGNMENT bool_expr SEMICOLON.

它解析类似:

name {
     name = "value";
     name2 = "value";
};

这确实是一个类似配置的名称。会发生什么:

name = "value" 导致 assignments ::= assignments 分配。减少。我希望 assignments 是一个常量值,但事实并非如此:

P assignment(0x807e778) ::= IDENTIFIER(0x807e728) ASSIGNMENT mvalue SEMICOLON.

P assignments((nil)) ::= assignments((nil)) assignment(0x807e778).
P append 0x807e778 to 0x807e838
P mvalue ::= string.
P assignment(0x807e750) ::= IDENTIFIER(0x807e7c8) ASSIGNMENT mvalue SEMICOLON.
P assignments((nil)) ::= assignments(0x807e838) assignment(0x807e750).
P append 0x807e750 to 0x807e910
P mvalue ::= string.
P assignment(0x807e7f0) ::= IDENTIFIER(0x807e7a0) ASSIGNMENT mvalue SEMICOLON.
P assignments((nil)) ::= assignments(0x807e910) assignment(0x807e7f0).
P append 0x807e7f0 to 0x807e9e8
P group(0x807e7a0) assignments(0x807e9e8) : bind
P groups ::= group(0x807e7a0).

柠檬调试输出是http://pastebin.com/yHNkNRpf

这导致 name2 仅添加到列表中。我对此感到困惑。我理解减少,但不明白为什么分配者一直被设置为空。有办法解决这个问题,但我更喜欢适当的修复。

柠檬调试输出是http://pastebin.com/yHNkNRpf

有什么线索吗?

4

2 回答 2

0

pastebin 上的 Lemon 解析器调试输出表明它可以很好地解析您的输入标记。它可以得出结论,完整的语法是正确的。这个问题不清楚的是如何在减少操作中处理解析的值。

考虑以下实现。引入了两级列表来存储解析的数据——它是轮流分配列表中的组列表。在减少每个分配规则解析器时调用一个将条目添加到临时分配列表的操作。在减少组规则时,此临时列表作为新组条目包含在组列表中。如果出现语法错误,整个列表将被删除。它包含解析成功完成时的所有解析值。

根据您的程序输出,您似乎使用了新列表或每个新分配值:

P append 0x807e778 to 0x807e838
P append 0x807e750 to 0x807e910
P append 0x807e7f0 to 0x807e9e8

它解释了为什么在解析结束时只有最后一个值。分配的新列表应该在第一组的解析开始时初始化,并在下一组的组规则的操作处理程序中初始化。

于 2013-06-07T14:32:40.110 回答
0

迟到总比从不好:使用的 re2c 词法分析器没有涵盖所有令牌路径。换句话说:一些令牌不匹配规则,并且没有设置默认值。在这种情况下,行为是未定义的。在这种情况下,它返回了错误的令牌。

于 2016-07-21T10:53:34.417 回答