2013-08-28 4 views
0

Я пытаюсь создать парсер LALR (1) для следующей грамматики и найти конфликты смены/уменьшения.Есть ли общий способ преобразования однозначной контекстно-свободной грамматики в грамматику LALR (1)?

S := expr 
expr := lval | ID '[' expr ']' OF expr 
lval := ID | lval '[' expr ']' 

The conflicts

Таким образом, анализатор не может разобрать строку "ID [ID]" правильно. Мои вопросы,

  1. Существуют ли какие-либо общие способы преобразования таких не-LALR (1) грамматик в LALR (1) грамматик?
  2. Если две грамматики генерируют точно такие же языки, и мы знаем, что это не LALR (1), можем ли мы знать, является ли другой LALR (1)?

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

Заранее спасибо.

ответ

2

1. Существуют ли какие-либо общие способы преобразования таких не-LALR (1) грамматик в грамматики LALR (1)?

Нет. Может быть или не будет возможно преобразовать произвольную контекстно-свободную грамматику (CFG) в грамматику LALR (1). Для этого нет общего алгоритма, даже если вы как-то знаете, что это возможно. Более того, если у вас есть CFG и LALR (1) грамматика, вы не можете определить, распознают ли они один и тот же язык. (Хуже, нет алгоритма, который даже скажет вам, будет ли произвольный CFG распознавать каждую возможную строку для своего алфавита.)

2. Если две грамматики генерируют точно такие же языки, и мы знаем, что это не LALR (1), можем ли мы знать, является ли другой LALR (1)?

Опять же, нет. Как и выше, нет алгоритма, который может проверить, что два грамматики генерируют один и тот же язык, но даже предполагая, что вы знаете, что две грамматики генерируют один и тот же язык, тот факт, что один из них не LALR (1) ничего не говорит о другом один.

Существует, однако, один полезный результат. Если у вас есть грамматика LALR (k) с конечным k > 1, вы можете сгенерировать грамматику LALR (1). Другими словами, нет такой вещи, как LALR (k) язык для k > 1; если язык имеет грамматику LALR (k), он имеет грамматику LALR (k ') для любого k' такой, что 1 ≤ k '< k.

Это не поможет вам с вашей грамматикой, потому что конфликт не может быть устранен путем увеличения взгляда до любого конечного значения.

Существует простой способ избавиться от этого конкретного конфликта сдвига, однако, и это техника, которая часто работает.Рассмотрим две противоречащие друг другу правила:

lval := lval '[' expr ']' 
expr := ID '[' expr ']' OF expr 

Проблема заключается в том, что в первом случае, ID должна быть уменьшена до lval немедленно (или, по крайней мере, до следующего expr уменьшается), но во втором случае это не может сокращаться до lval. Но мы не можем сказать, в каком случае мы находимся, пока мы не уменьшим expr и не столкнемся с OF (или нет).

Если бы мы могли закончить lval производства, не делая сокращение интерьера lval, то мы бы не проблема, потому что фактическое сокращение будет происходить, когда маркер после ] виден.

Возможно, для этого существует технический термин, но я этого не знаю. Я всегда описывал это как «сокращение отсрочки», и во многих случаях это не очень сложно:

lval' := ID `[` expr `]` 
     | lval' `[` expr `]` 
lval := ID 
     | lval' 
expr := lval 
     | ID '[' expr ']' OF expr 
+0

Очень информативный ответ. Вопрос о тех методах, которые вы использовали в ответе, как я могу найти эти общие методы для грамматических преобразований? Большое спасибо. – MingyanGuo

+0

@MingyanGuo: Мне жаль, что у меня нет ссылки. Я уверен, что я не думал, что это один, но я не смог отправить ссылку на Google, и я использовал ее так долго, что не могу вспомнить, откуда она взялась. Сожалею. Результат неразрешимости прост и хорошо известен; он основан на построении грамматики, которая представляет собой вычисление машины Тьюринга. Я почти уверен, что это у Хопкрофта и Ульмана. Я получил LALR (k> 1) сокращение от Sippu & Soisalon-Soinenen (Теория парсинга), но я думаю, вы можете найти его в любой хорошей ссылке. – rici

+1

Собственно, теперь, когда я думаю об этом, техника, которую я использовал, очень похожа на алгоритм покрытия LR (k), как описано S & S-S. Предположим, вы построили парсер LR (k) для грамматики; по сути, вы вычислили множество возможных взглядов для каждой продукции. Таким образом, вы можете заменить каждый нетерминальный N множеством нетерминалов (N, L1, L2 ... Lk-1), выработать подстановки для каждого нетерминального в RHS. Это, очевидно, дает вам грамматику LR (1). Иногда вы можете сделать что-то подобное с неканоническими (например, не-терминалами). Я думаю, что это то, что я сделал. – rici

 Смежные вопросы

  • Нет связанных вопросов^_^