野牛如何在语法中描述可选语法而没有移位-减少冲突?

时间:2018-09-11 08:41:08

标签: bison flex-lexer shift-reduce-conflict ambiguous-grammar

我有一个用语法描述的文件。它的部分可以包含一种或两种内容,并且可以按任意顺序排列:

...
type_a_thing
type_b_thing
type_b_thing
type_a_thing
....

或者只是

...
type_a_thing
...

...
type_b_thing
type_b_thing
...

或任意组合,发生的次数不限。 type_a_thing和type_b_thing都具有定义良好的结构。我设法描述了这一点,以使解析器可以正常工作,但是仍然出现移位/减少错误。 我在这里上传了一个最小的示例:

https://github.com/waszil/minimal_bison_parser

这是解决此问题的正确方法吗?我做错了吗? 我为此做了很多尝试,使用详细标志检查了由bison生成的.output文件,但我不知道该如何正确完成。它有点类似于Flex&Bison O'Reilly书中描述的嵌套列表语法问题,但不完全相同

感谢任何提示!

1 个答案:

答案 0 :(得分:1)

看看语法的这一部分:

contents:
    foobar
    | contents foobar
    ;
foobar:
    foos
    | bars
    ;
foos:
    foo
    | foos foo
    ;
bars:
    bar
    | bars bar
;

因此contentsfoobar的列表,而foobarfoo的列表或bar的列表。这是模棱两可的,因为通过将两个foo解释为包含两个{{1}的单个contents可以将包含两个连续foo的输入解析为foobar }}或两个foo,每个包含一个foobar

摆脱这种歧义的一种简单方法是放弃内部列表:

foo

如果需要以不同的方式处理连续的contents: foobar | contents foobar; foobar: foo | bar; ,则在后期处理期间仍可以检测到它们。如果您绝对需要在语法中处理此问题,则可以重组语法,以便foo之后只能是foos(不能是另一个bars),反之亦然。 / p>