c - 在不求助于 GLR-Parser 的情况下解决模棱两可的语法

标签 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匹配/不匹配的 block 。

我的( 非常 简化)语法基本上是:
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 分支。对于这种情况,公认的做法是什么,没有切换到完全不同的扫描仪/解析器(这对我来说学习和重写代码需要做很多工作)或更改语言(我不能这样做)?是否有使用 GLR 或调整语法的简单解决方案(以某种方式定义 %dprec ?)?

最佳答案

经典的悬空-else 问题是通过坚持 来解决的。否则 附上最近的如果 ,这(在概念上)解决了歧义。您需要以某种方式将该想法传达给解析器生成器,以使歧义真正消失。

大多数解析器生成器(包括 YACC 和 Bison)都有某种方式表示,当 token 存在 shift-vs-reduce 冲突时,更喜欢“shift”,它可以用来为 实现这种效果。否则 关键词。我不知道YACC或Bison的成语是什么,但是在语法描述信息中应该很容易找到。

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

关于c - 在不求助于 GLR-Parser 的情况下解决模棱两可的语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4326963/

相关文章:

c++ - 在 flex、bison、c++ 中实现 Wolfram 语言

c - Bison-Flex extern FILE *yyin 不工作(C 语言)

在需要附加属性的文件描述符上使用轮询的规范方式

Java飞行记录器以编程方式解析

c - 请解释这段C代码的输出

python - 递归解析类似 lisp 的语法

c# - 如何从 UWP 中的 Assets 文件夹中解析 JSON 文件 - 已关闭

C、Flex 和 Bison : error: conflicting types for ‘yyerror’

c - 为什么函数参数动态分配的内存在退出函数时会丢失?

c++ - 在 win32 中创建自定义消息类型?