В каждом курсе "Вступление к компиляторам" рассматриваются общепринятые подмножества контекстно-свободных грамматик: LL (k), SLR (k), LALR (k), LR (k). Нам также говорят, что для любого заданного k каждая из этих грамматик является подмножеством следующего.
То, что я никогда не видел, - это объяснение того, какие типы синтаксических функций языка программирования могут потребовать перехода к другому языковому классу. Там очевидная практическая мотивация для парсеров GLR, а именно, избежание нечестивого смешения парсера и таблицы символов при синтаксическом анализе С++. Но как насчет различий между двумя "стандартными" классами, LL и LR?
Два вопроса:
- Какие (общие) синтаксические конструкции могут быть проанализированы с помощью LR (k), но не LL (k ')?
- Каким образом, если таковые имеются, эти конструкции проявляются как желательные языковые конструкции?
Там есть правдоподобный аргумент в пользу уменьшения владения языком, делая k как можно меньшим, потому что язык, требующий многих, многих токенов взгляда, будет труднее для людей разобрать, а также "сложнее" для машин для разбора. Вопрос (2) неявно спрашивает, заканчивается ли то же рассуждение как между классами, так и внутри класса.
edit: Здесь один пример, чтобы проиллюстрировать виды ответов, которые я ищу, но для обычных языков вместо контекстно-свободных:
При описании обычного языка обычно получается три оператора: +
, *
и ?
. Теперь вы можете удалить +
без снижения мощности языка; вместо записи x+
вы пишете xx*
, и эффект тот же. Но если x
- какое-то большое и волосатое выражение, два x
, вероятно, расходятся во времени из-за забвения человека, давая синтаксически правильное регулярное выражение, которое не соответствует оригинальному намерению автора. Таким образом, даже если добавление +
не требует строгого добавления мощности, оно делает запись менее подверженной ошибкам.
Существуют ли конструкции с подобными практическими (человеческими?) эффектами, которые должны быть "удалены" при переключении с LR на LL?