Практические последствия формальной грамматической силы? - PullRequest
14 голосов
/ 16 декабря 2009

В каждом курсе бакалавриата «Введение в компиляторы» рассматриваются общепринятые подмножества контекстно-свободных грамматик: LL (k), SLR (k), LALR (k), LR (k). Нас также учат, что для любого данного k каждая из этих грамматик является подмножеством следующего.

То, что я никогда не видел, - это объяснение того, какие виды синтаксических функций языка программирования могут потребовать перехода на другой языковой класс. Существует очевидная практическая мотивация для синтаксических анализаторов GLR, а именно: избегать нечестивого объединения синтаксического анализатора и таблицы символов при синтаксическом анализе C ++. Но как насчет различий между двумя «стандартными» классами, LL и LR?

Два вопроса:

  1. Какие (общие) синтаксические конструкции можно анализировать с помощью LR (k), но не LL (k ')?
  2. Как, если таковые имеются, эти конструкции проявляются как желательные языковые конструкции?

Есть правдоподобный аргумент в пользу уменьшения языковой мощности, сделав k как можно меньшим, потому что язык, требующий много-много жетонов упреждения, будет труднее для людей, а также "труднее" для машин. Вопрос (2) неявно спрашивает, имеет ли место то же рассуждение между классами, а также внутри класса.


edit: Вот один пример, иллюстрирующий разного рода ответы, которые я ищу, но для обычных языков вместо контекстно-свободных:

При описании обычного языка обычно получают три оператора: +, * и ?. Теперь вы можете удалить + без снижения мощности языка; вместо записи x+ вы пишете xx*, и эффект тот же. Но если x - какое-то большое и волосатое выражение, два x, скорее всего, со временем будут расходиться из-за забывчивости человека, что приведет к синтаксически правильному регулярному выражению, которое не соответствует намерению первоначального автора. Таким образом, несмотря на то, что добавление + не добавляет мощности, оно делает запись менее подверженной ошибкам.

Существуют ли конструкции с аналогичными практическими (человеческими?) Эффектами, которые необходимо "удалить" при переключении с LR на LL?

Ответы [ 4 ]

7 голосов
/ 17 декабря 2009

Синтаксический анализ (я утверждаю) немного похож на сортировку: эта проблема была предметом пристального внимания в первые дни CS, что привело к набору хорошо понятых решений с некоторыми хорошими теоретическими результатами.

Я утверждаю, что картина, которую мы получаем (или даем для тех из нас, кто преподает) в классе компиляторов, в некоторой степени является прекрасным ответом на неправильный вопрос.

Чтобы ответить на ваш вопрос более прямо, грамматика LL (1) не может проанализировать все виды вещей, которые вы, возможно, захотите проанализировать; «естественная» формулировка «если» с необязательным «еще», например.

Но подожди! Разве я не могу переформулировать свою грамматику как грамматику LL (1), а затем залатать исходное дерево, пройдя по нему потом? Что вы можете! В какой-то степени именно это и делает вопрос о том, какую грамматику использует ваш синтаксический анализатор.

Кроме того, еще когда я был студентом (1990-94), грамматики, чувствительные к пробелам, были явно работой Дьявола; теперь проекты Python и Haskell возвращают светочувствительность обратно в свет. Кроме того, синтаксический анализ Packrat говорит: «Черт с твоей теоретической чистотой: я просто собираюсь определить парсер как набор правил, и мне все равно, к какому классу относится моя грамматика». (Перефразировал)

Таким образом, я бы согласился с тем, что я считаю вашим подразумеваемым предложением: в 2009 году четкое понимание различия между классами LL (k) и LR (k) само по себе менее важно, чем способность формулировать и отладить грамматику, которая сделает ваш генератор парсера счастливым.

1 голос
/ 19 декабря 2009

Разница между LL и LR заключается в основном в механизме прогнозирования.Люди обычно говорят, что парсеры LR несут больше «контекста».Чтобы увидеть это на практике, рассмотрим определение рекурсивной грамматики с символом S в качестве начального символа:

A -> Ax | x 
B -> Ay
C -> Az
S -> B | C

Когда k - небольшое фиксированное значение, разбор строки, такой как xxxxxxy, является задачей, лучше подходящей для синтаксического анализатора LR.Однако в наши дни популярные парсеры LL, такие как ANTLR, не ограничивают k такими маленькими значениями, и большинству людей это больше не нужно.

Надеюсь, это более или менее соответствует вашему вопросу.Конечно, Кнут показал, что любой однозначный контекстно-свободный язык может быть распознан по некоторой грамматике LR (1).Однако на практике нас также интересует перевод.

В качестве примечания: Вам также может понравиться чтение http://www.antlr.org/article/needlook.html.

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

.,,,,|,,,,.

Скорее, я ожидаю, что с такими короткими узорами, как этот, люди буквально не читают "точка-точка-точка-точка-точка-точка-точка-точка-точка-точка" слева направо, а скорее обрабатывают шаблон параллельно или вхотя бы в какой-то нечеткой итеративной манере.Другими словами, я не верю, что мы обязательно читаем все шаблоны слева направо с видом линейного просмотра, который использует анализатор LL / LR.

Более того, если мы можем описать любой контекст-свободный язык, использующий грамматику LR (1), тогда ясно, что простое распознавание строки - это не то же самое, что «понимание» ее.

0 голосов
/ 16 декабря 2009

ну, во-первых, левые рекурсивные определения невозможны в LL (k) грамматиках (насколько я знаю), не знаю о других. Это не делает невозможным определить другие вещи, просто массивная боль, чтобы сделать иначе. Например, составление выражений может быть простым на леворекурсивном языке (в псевдокоде):

lexer rule expression = other rules
                        | expression
                        | '(' expression ')';

Насколько синтаксически полезные вещи, которые можно сделать с помощью левой рекурсии, умнее считать простые грамматики синтаксически полезными?

0 голосов
/ 16 декабря 2009

Возможности языка не ограничены его синтаксисом и грамматикой.

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

...