在给定上下文无关语法的情况下查找含糊不清的语句

时间:2012-04-18 13:53:52

标签: bison lex context-free-grammar ambiguous

我有一个家庭作业,考虑到定义语句的语法,我应该在语句中检测歧义。

示例:

Grammar: S -> S + S | S * S | id
Statement: id * id + id

上述陈述含糊不清,因为可能有两个解析树。

到目前为止,我有以下含糊之处:

1) Operator precedence (example above)
2) If-else dangling case
3) Infinite loop (example above is left recursive)
4) Associativity

你能告诉我哪些是可行的吗?

我必须使用lex和bison(yacc)设计这个解析器,并在2天内提交它,所以任何指针都会对语法和语句中的歧义有所帮助。

2 个答案:

答案 0 :(得分:1)

好吧,如果你有你的命令中的lex和bison,你可以简单地将语法提供给野牛,它会告诉你它是否含糊不清。

否则,您将必须构造整个LALR1解析器生成器算法,以确定是否存在使语法不明确的冲突。这些冲突在解析器构建阶段很晚才被检测到(我的解析器生成器在表生成步骤中找到它们)。也许你可以从我的代码如何做到这一点,它可以在https://github.com/Dervall/Piglet

找到

当您尝试填充已填充了与您的令牌具有相同优先级的条目的操作表的一部分时,会发生自下而上解析器中的shift / reduce和reduce / reduce的经典情况试着加入它。

如果你在谈论LL解析器,那么无限循环实际上不是一个含糊不清的语法 - 语法可以被重构为非模糊的。

声明本身不会以任何方式影响语法模糊。无论给出什么输入,它都是模棱两可的。

答案 1 :(得分:1)

一般情况下你不能 - 语法歧义是undecidable

尽管如此,你可以识别出一些明显含糊不清的语法模式。

  • 左右递归的任何(非无用的)非终端都是不明确的(包括上面提到的所有情况,除了悬挂其他情况)。
  • 任何(非无用的)具有两个右递归规则的非终端,其中一个是另一个的前缀是不明确的(涵盖悬空 - 否则)。