嗨,书中有一个问题说
鉴于这个语法
A --> AA | (A) | epsilon
a- 它产生什么\
b- 表明这是模棱两可的
现在我想到的答案是
a- 邻接括号
b-它生成不同的解析树,所以它模棱两可,我做了一个画图,显示了两个场景。
这是正确的还是有更好的答案?
a) 几乎正确...
该文法准确地生成由平衡括号组成的字符串集。要了解为什么会这样,让我们尝试快速演示一下。
第一:语法之外的所有内容都是平衡的括号字符串。为什么?,简单的归纳:
第二:每组平衡的字符串都是由你的语法产生的。让我们通过对字符串大小的归纳来做到这一点。
例如: (()())(())
我们可以完全使用演示的想法来生成这个字符串。
A -> AA -> (A)A -> (AA)A -> ((A)(A))A -> (()())A -> (()())(A) -> ( ()())((A)) -> (()())(())
b)当然左右递归足以说它是模棱两可的,但是要了解为什么特别是这个语法是模棱两可的,请按照相同的想法进行演示:
这是模棱两可的,因为您不需要采用最短的平衡前缀。您可以采用不是字符串大小的最长平衡(或通常任何平衡前缀),并且演示(和生成)将遵循相同的过程。
前任: (())()()
您可以选择 A -> AA 并使用第一个 A 生成 (()) 子字符串或 (())() 子字符串。
是的你是对的。
这就是模棱两可的语法的意思。
歧义语法的问题在于,如果您正在编写一个编译器,并且您想在某些代码行(或类似的代码)中识别每个标记,那么歧义会干扰您的识别,因为您将对此有“两个解释”行代码。
听起来您对 B 部分的方法是正确的,显示了语法定义的语言中同一字符串的两个独立派生。
但是,我认为您对 A 部分的回答需要做一些工作。显然,您可以递归地使用第二个子句来获得类似 (((((epsilon))))) 的字符串,但是同时使用第一个子句和第二个子句还有其他类型的推导。