Неоднозначная грамматика? - PullRequest
4 голосов
/ 19 декабря 2010

привет есть вопрос в книге, которая сказала

Учитывая этот грамматик

A --> AA | (A) | epsilon

a- что он генерирует \

b- шоу неоднозначное

теперь ответы, о которых я думаю, это

a- прилагательный парантез

b - он генерирует различное дерево разбора, поэтому его аббревиатура, и я нарисовал два сценария.

это правильно или есть лучший ответ?

Ответы [ 4 ]

2 голосов
/ 19 декабря 2010

a почти правильно.
Грамматика действительно генерирует последовательности (), ()(), ()()(),….
Но из-за второго правила он может генерировать (()), ()((())) и т. Д.

b неверно.
Эта грамматика неоднозначна из-за немедленной левой рекурсии: A → AA.

Как избежать рекурсии слева: один , два .

1 голос
/ 02 мая 2012

а) Почти справа ...

Эта грамматика генерирует ровно набор строк, составленных из сбалансированных скобок.Чтобы понять, почему это так, давайте попробуем сделать быструю демонстрацию.

Во-первых: все, что выходит из вашей грамматики, является строкой со сбалансированными скобками.Почему ?, простая индукция:

  • Epsilon - строка сбалансированных (пустых) скобок.
  • если A - строка сбалансированных скобок, (A) также сбалансирован.
  • если А1 и А2 сбалансированы, то же самое относится и к А1А2 (я использую слишком разные идентификаторы просто для того, чтобы четко указать, что А -> АА не обязательно производит одинаковое для каждого А).

Второе: каждый набор сбалансированных строк создается вашей грамматикой.Давайте сделаем это по индукции для размера строки.

  • Если строка имеет нулевой размер, это должно быть значение Epsilon.
  • Если нет, то N равно размеру строки.string и M - длина самого короткого префикса, который сбалансирован (обратите внимание, что остаток строки также сбалансирован):
    • Если M = N, вы можете создать эту строку с (A).
    • Если M AA, первые M символов с первым A и последним N - M с последним A. В любом случае вы должны создать строку короче, чем N символов,так что по индукции вы можете сделать это.QED.

Например: (() ()) (())

Мы можем сгенерировать эту строку, используя именно идею демонстрации.

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

b) Конечно, рекурсии влево и вправо достаточно, чтобы сказать, что она неоднозначна, но длячтобы понять, почему эта грамматика является неоднозначной, следуйте той же идее для демонстрации:

Она неоднозначна, потому что вам не нужно брать самый короткий сбалансированный префикс.Вы можете взять самый длинный сбалансированный (или вообще любой сбалансированный префикс), который не соответствует размеру строки, и демонстрация (и генерация) будут следовать тому же процессу.

Пример: (()) () ()

Вы можете выбрать A -> AA и сгенерировать с первой A подстроку (()) или подстроку (()) ().

0 голосов
/ 19 декабря 2010

Похоже, что ваш подход к части B правильный, показывая два независимых вывода для одной и той же строки на языках, определенных грамматикой.

Однако я думаю, что ваш ответ на часть A требует небольшой работы.Ясно, что вы можете использовать второе предложение рекурсивно для получения таких строк, как (((((epsilon))))), но существуют и другие типы дериваций, которые могут использовать первое предложение и второе предложение вместе.

0 голосов
/ 19 декабря 2010

Да, вы правы.

Вот что означает неоднозначная грамматика.

Проблема с многоплановыми грамматиками заключается в том, что если вы пишете компилятор, и вы хотите идентифицировать каждый токен в определенныхстрока кода (или что-то в этом роде), тогда двусмысленность помешает вам идентифицировать, поскольку у вас будет «два объяснения» к этой строке кода.

...