语境中的歧义自由语法

时间:2014-10-19 01:30:01

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

问题

  

显示无上下文语法" S-> SbS | ScS | a"是暧昧的   为字符串abaca提供两个解析树。

我不知道字符串是多么含糊不清?我正在读一本关于编译器和自学的书,所以我在书中做了这个问题而且我很难过。

可能的解决方案

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

任何人都可以确认我的解决方案是否正确,如果没有,有人可以指导我。

1 个答案:

答案 0 :(得分:2)

使用笔和纸更容易。在所有可能性中,我通过推导出初始符号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 -> SbS -> abS -> abScs -> ...可以写成[S [S a] b [S [S a] c [S a]]],其中[S [S ...] b [S ...]]表示第一个派生,然后将第一个[S ...]展开为[S a]通过二次推导等等。希望这些工具可以帮助您正式学习语法!