Дана контекстно-свободная грамматика G с продукциями: S -> S S | "a" | "b"; покажите, что грамматика неоднозначна, приведите конкретную строку с двумя различными деревьями разбора, и предложите способ модификации грамматики или использования ограничений для получения неоднозначности-устойчивого синтаксического анализа

2 Окт в 17:16
19 +1
0
Ответы
1

Грамматика
S -> S S | "a" | "b"
неоднозначна. Интуитивно: S S — это бинарная операция конкатенации, и любую строку из n терминалов можно разбить на бинарную скобочную структуру по-разному (число структур равно числу каталановых деревьев), поэтому для n ≥ 3 существуют ≥ 2 различных деревьев разбора.

Конкретный пример. Возьмём строку "aaa". Два различных дерева разбора:

1) лево-ассоциативное ((a a) a):
S
├─ S
│ ├─ S
│ │ └─ "a"
│ └─ "a"
└─ "a"

или в виде вывода:
S ⇒ S S ⇒ S S S ⇒ "a" S S ⇒ "a" "a" S ⇒ "a" "a" "a"

2) право-ассоциативное (a (a a)):
S
├─ "a"
└─ S
├─ "a"
└─ "a"

или в виде вывода:
S ⇒ S S ⇒ S S S ⇒ S "a" S ⇒ "a" "a" "a"

Оба дерева дают одну и ту же терминальную строку "aaa", но имеют разную структуру — значит грамматика неоднозначна.

Как получить устойчивый (неоднозначности-устойчивый) разбор

Сделать грамматику неамбигуной, явно задав ассоциативность (список) вместо бинарной рекурсии:
Например, описать непустую последовательность терминалов однозначно:
S -> A | A S
A -> "a" | "b"
Эта грамматика порождает те же строки (все непустые строки над {a,b}), но даёт однозначный (право-рекурсивный) формат разбора — вся последовательность имеет фиксированное правое (или если нужно, левое) вложение.

Использовать н-арную конструкцию вместо бинарной: в семантике/AST хранить конкатенацию как n-арный узел (список терминалов/поддеревьев), и при разборе «свернуть» любые бинарные деревья в один список. Тогда разные бинарные деревья считаются эквивалентными и приводят к одному AST.

В парсерах/генераторах объявить ассоциативность и приоритет (например, declare concatenation как левую или правую ассоциативную операцию). Тогда парсер разрешит неоднозначность в одну сторону.

Использовать ограничения/семантические проверки: если грамматика остаётся амбигуной, можно обнаруживать неоднозначные разборы (в GLR/Earley) и отбрасывать все, кроме подходящих по семантике (например, по дополнительным атрибутам).

Коротко: простейший путь — заменить S -> S S | "a" | "b" на списокную форму S -> A | A S (или S -> S A | A), либо при построении AST сворачивать конкатенации в список. Тогда разбор будет однозначным.

2 Окт в 18:19
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир