简体   繁体   English

含糊不清的语法?

[英]Ambiguous grammar?

hi there is this question in the book that said 嗨,书中有这个问题说

Given this grammer 鉴于这个语法

A --> AA | (A) | epsilon

a- what it generates\\ a-它产生什么

b- show that is ambiguous b-显示含糊不清

now the answers that i think of is 现在我想到的答案是

a- adjecent paranthesis a-adjecent paranthesis

b- it generates diffrent parse tree so its abmbiguous and i did a draw showing two scenarios . b-它生成不同的解析树,所以它的不明确,我画了两个场景。

is this right or there is a better answer ? 这是对的还是有更好的答案?

a is almost correct. a几乎是正确的。
Grammar really generates () , ()() , ()()() , … sequences. 语法实际上生成()()()()()() ,...序列。
But due to second rule it can generate (()) , ()((())) , etc. 但由于第二个规则,它可以生成(())()((()))等。

b is not correct. b不正确。
This grammar is ambiguous due ot immediate left recursion: A → AA . 由于立即左递归,该语法是模糊的: A → AA

How to avoid left recursion: one , two . 如何避免左递归:

a) Nearly right... a)差不多......

This grammar generates exactly the set of strings composed of balanced parenthesis. 该语法完全生成由平衡括号组成的字符串集。 To see why is that so, let's try to make a quick demonstration. 要知道为什么会这样,让我们​​试着快速演示。

First: Everything that goes out of your grammar is a balanced parenthesis string. 第一:语法中的一切都是平衡的括号字符串。 Why?, simple induction: 为什么?,简单的归纳:

  • Epsilon is a balanced (empty) parenthesis string. Epsilon是一个平衡(空)括号字符串。
  • if A is a balanced parenthesis string, the (A) is also balanced. 如果A是平衡括号字符串,则(A)也是平衡的。
  • if A1 and A2 are balanced, so is A1A2 (I'm using too different identifiers just to make explicit the fact that A -> AA doesn't necessary produces the same for each A). 如果A1和A2是平衡的,那么A1A2也是如此(我使用太多不同的标识符只是为了明确A - > AA不必为每个A产生相同的事实)。

Second: Every set of balanced string is produced by your grammar. 第二:每组平衡字符串都是由你的语法产生的。 Let's do it by induction on the size of the string. 让我们通过对字符串大小的归纳来做到这一点。

  • If the string is zero-sized, it must be Epsilon. 如果字符串为零,则必须为Epsilon。
  • If not, then being N the size of the string and M the length of the shortest prefix that is balanced (note that the rest of the string is also balanced): 如果不是,那么N是字符串的大小,M是平衡的最短前缀的长度(注意字符串的其余部分也是平衡的):
    • If M = N then you can produce that string with (A). 如果M = N,那么你可以用(A)产生该字符串。
    • If M < N the you can produce it with A -> AA, the first M characters with the first A and last N - M with the last A. In either case, you have to produce a string shorter than N characters, so by induction you can do that. 如果M <N,你可以使用A - > AA生成它,前M个字符带有第一个A,最后一个N - M带有最后一个A.在任何一种情况下,你必须产生一个短于N个字符的字符串,所以感应你可以做到这一点。 QED. QED。

For example: (()())(()) 例如: (()())(())

We can generate this string using exactly the idea of the demonstration. 我们可以使用演示的想法生成此字符串。

A -> AA -> (A)A -> (AA)A -> ((A)(A))A -> (()())A -> (()())(A) -> (()())((A)) -> (()())(()) A - > AA - >(A)A - >(AA)A - >((A)(A))A - >(()())A - >(()())(A) - >( ()())((A)) - >(()())(())

b) Of course left and right recursion is enough to say it's ambiguous, but to see why specially this grammar is ambiguous, follow the same idea for the demonstration: b)当然左右递归足以说明它是模棱两可的,但要明白为什么特别是这个语法含糊不清,请遵循同样的想法进行演示:

It is ambiguous because you don't need to take the shortest balanced prefix. 这是不明确的,因为您不需要采用最短的平衡前缀。 You could take the longest balanced (or in general any balanced prefix) that is not the size of the string and the demonstration (and generation) would follow the same process. 您可以采用最长的平衡(或通常任何平衡前缀),而不是字符串的大小,演示(和生成)将遵循相同的过程。

Ex: (())()() 例如:(())()()

You can chose A -> AA and generate with the first A the (()) substring, or the (())() substring. 您可以选择A - > AA并使用第一个A(())子字符串或(())()子字符串生成。

Yes you are right. 是的,你是对的。

That is what ambigious grammar means. 这就是ambigious语法的含义。

the problem with mbigious grammars is that if you are writing a compiler, and you want to identify each token in certain line of code (or something like that), then ambigiouity wil inerrupt you in identifying as you will have "two explainations" to that line of code. mbigious语法的问题在于,如果你正在编写一个编译器,并且你想要识别某些代码行中的每个标记(或者类似的东西),那么你将在识别时对你进行“两个解释”。代码行。

It sounds like your approach for part B is correct, showing two independent derivations for the same string in the languages defined by the grammar. 听起来你的B部分方法是正确的,显示了语法定义的语言中相同字符串的两个独立派生。

However, I think your answer to part A needs a little work. 但是,我认为你对A部分的回答需要一点工作。 Clearly you can use the second clause recursively to obtain strings like (((((epsilon))))), but there are other types of derivations possible using the first clause and second clause together. 显然,您可以递归地使用第二个子句来获取像(((((epsilon)))))这样的字符串,但是使用第一个子句和第二个子句可以有其他类型的派生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM