【问题标题】:Ambiguity in Context free Grammar上下文无关语法中的歧义
【发布时间】:2014-10-19 01:30:00
【问题描述】:

问题

证明上下文无关文法“S->SbS|ScS|a”是不明确的 为字符串 abaca 提供两个解析树。

我不明白字符串是如何模棱两可的?我正在读一本关于编译器和自学的书,所以我在书中做这个问题,我被难住了。

可能的解决方案

abaca         abaca
a(aba)aca     aba(aca)a 

谁能确认我的解决方案是否正确,如果不正确,请指导我。

【问题讨论】:

  • 您展示的不是解析树。您需要展示如何解析abaca。没有一种方法可以绘制解析树,但通常可以显示语法树(如果您在内存中想象它)或一系列推导(如@Mephy 的回答)。

标签: grammar context-free-grammar ambiguous-grammar


【解决方案1】:

使用笔和纸更容易做到这一点。在所有可能性中,我列出了通过推导初始符号S 找到的三种可能性。

S -> SbS -> abS -> abScS -> abacS -> abaca
S -> ScS -> Sca -> SbSca -> abSca -> abaca
S -> SbS -> SbScS -> abScS -> abSca -> abaca

还有其他的,这不难看出。然而,通常更容易将字符串 (abaca) 简化为原始符号 (S)。许多编译器这样做是为了避免无限递归:

abaca <- Sbaca <- SbSca <- Sca <- ScS <- S
abaca <- abacS <- abScs <- abS <- SbS <- S

这样做的方法是手动选择一种方法(推导或归约),然后通过反复试验,根据语法进行可能的替换,这将引导您找到一棵树。树中通向目标的节点(原始符号或最终字符串)是正确的节点。如果路径不止一条,那么它就是模棱两可的。


现在,这些推导和其他推导中的每一个都将产生一个所谓的Parse Tree。解析树表示能够从初始符号生成终端字符串的派生集。为了更好地可视化解析树,我在网上找到了一个工具来绘制这种树,你可以找到它here

它使用的格式是[NonTerminal terminal [NonTerminal terminal] terminal],几乎是一个类似 Lisp 的列表,带有方括号而不是括号。比如我构建的第一个推导S -&gt; SbS -&gt; abS -&gt; abScs -&gt; ...可以写成[S [S a] b [S [S a] c [S a]]],其中[S [S ...] b [S ...]]代表第一个推导,然后你将第一个[S ...]通过第二个推导扩展为[S a],以此类推。希望这个工具可以帮助您学习正式的语法!

【讨论】:

  • 这对我来说很重要,您是否可以通过在油漆中画出您的一条路径来向我展示,这样我就知道编写它的正确符号了。我赞成您并接受只有你的答案。再次感谢。
  • 我问是因为我相信有一种正确的方法来绘制解析树,所以如果你告诉我,它会有很大帮助,我可以做更多这样的问题。
  • 没有“正确”的方式,但我会尝试做一个视觉表示,稍后改进答案。
猜你喜欢
  • 1970-01-01
  • 2012-01-04
  • 2014-04-26
  • 2013-02-23
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
相关资源
最近更新 更多