在不诉诸GLR-Parser的情况下解决模糊语法

时间:2010-12-01 17:10:02

标签: c parsing bison flex-lexer

在解析'if' expr 'then'时,我有一种语法有两种不同的可能性。有一个简单的“赋值”,例如if foo then bar=1; else bar=0;然后就是我所谓的“if_block”代码,它可以包含一个或多个“赋值”:

if foo then
{
    bar = 1;
    if xyz then abc = -1;
}
else
{
    bar = 0;
    if xyz then
    {
       abc = 0;
    }
}

我正在通过dangling else匹配/不匹配的块处理嵌套的if_blocks。

我的(非常简化)语法基本上是:

program : if_blocks
if_blocks : if_block | if_block if_blocks
if_block : assignments
assignments : assignment | assignment assignments
assignment : simple_assignment | if_assignment

所以我的困境是一个赋值,然后是if_block。例如:

foo = bar;
if foo then
{
   foo = foo + 1;
}

foo = bar;是一个赋值,在这种情况下,应该简化为if_block。 if foo then { ... }本身就是一个if_block。因此,整个代码是if_block + if_block(简化为if_blocks)。但是,在foo = bar;简化为赋值之后,没有足够的先行知道if foo then是否是另一个赋值(在foo = bar; if_block中)或者它是否是单独的if_block。

我添加了%glr-parser,这似乎解决了这个问题,但我遇到了解析的多个分支存活的其他情况,我似乎无法协调不同的S / R分支。在没有切换到完全不同的扫描仪/解析器(这对我来说学习和重写代码很多工作)或改变语言(我不能做)的情况下,这种情况的公认惯例是什么?是否有一个简单的解决方案(以某种方式定义%dprec?)使用GLR或对语法进行调整?

1 个答案:

答案 0 :(得分:1)

通过坚持将 else 附加到最近的 if 来解决悬空 - 其他问题,这(概念上)解决了歧义。不知何故,你需要将这个想法传达给解析器生成器,以使歧义真正消失。

大多数解析器生成器(包括YACC和Bison)都有一些方法可以说当一个令牌存在shift-vs-reduce冲突时,更喜欢“shift”,这可以用来为 else 关键字。我不知道YACC或Bison的成语是什么,但在语法描述信息中应该很容易找到。

(我使用自己的GLR解析器,说这个仍然很有用,因为它以简单的方式摆脱了模糊的解析)。

相关问题