Задан контекстно‑свободный грамматический фрагмент: S -> S S | 'a' | 'b'. Докажите или опровергните её однозначность (ambiguous/не ambiguous), приведите пример строки с двумя разными деревьями разбора или докажите невозможность такого, и обсудите, как модификация грамматики влияет на парсинг LR(1) vs LL(1)
Грамматика S→S S∣a∣bS \to S\ S \mid a \mid bS→SS∣a∣b
амбигуозна. Пример строки с двумя разными деревьями разбора: возьмём w=abaw = abaw=aba. Два различных вывода (скобочная группировка отражает структуру двоичного конкатенирования): 1) ((a b) a)((a\ b)\ a)((ab)a): S⇒S S⇒S S S⇒a S S⇒a b S⇒a b aS \Rightarrow S\ S \Rightarrow S\ S\ S \Rightarrow a\ S\ S \Rightarrow a\ b\ S \Rightarrow a\ b\ aS⇒SS⇒SSS⇒aSS⇒abS⇒aba. 2) (a (b a))(a\ (b\ a))(a(ba)): S⇒S S⇒a S⇒a S S⇒a b S⇒a b aS \Rightarrow S\ S \Rightarrow a\ S \Rightarrow a\ S\ S \Rightarrow a\ b\ S \Rightarrow a\ b\ aS⇒SS⇒aS⇒aSS⇒abS⇒aba. Эти два дерева дают один и тот же выводный ряд символов abaabaaba, но имеют разную структуру — отсюда неоднозначность. Следствия для парсинга: - Поскольку грамматика неоднозначна, она не может быть распознаваема как детерминированная LR(1)-грамматика (всякая LR(k)-грамматика однозначна), следовательно исходная грамматика не является LR(1). - Она также не является LL(1) (LL(1) требует единственного выбора продукции по первому символу при предсказании; неоднозначность и пересекающиеся FIRST-наборы препятствуют этому). Как модификации влияют: - Чтобы получить однозначную и LL(1)-совместимую грамматику для множества всех непустых строк над {a,b}\{a,b\}{a,b}, можно факторизовать по первому символу, например S→a A∣b A,A→a A∣b A∣ε.
S \to a\ A \mid b\ A,\qquad A \to a\ A \mid b\ A \mid \varepsilon. S→aA∣bA,A→aA∣bA∣ε.
Здесь FIRST-альтернатив для SSS раздельны ({a}\{a\}{a} и {b}\{b\}{b}), грамматика однозначна и является LL(1) (а значит и LR(1)). - Если сделать левую рекурсию, например S→S a∣S b∣a∣b,
S \to S\,a \mid S\,b \mid a \mid b, S→Sa∣Sb∣a∣b,
то грамматика может быть однозначной, но из‑за левой рекурсии она не LL(1) без преобразований; LR(1)-парсер с такими правилами справится (LR(1) нормально обрабатывает левую рекурсию). - В общем: устранение двоичного правила конкатенации S→S SS\to S\ SS→SS в пользу правых/левых линейных или факторизованных правил делает грамматику однозначной; факторизация даёт LL(1), а леворекурсивная форма — удобна для LR(1).
S→S S∣a∣bS \to S\ S \mid a \mid bS→S S∣a∣b амбигуозна.
Пример строки с двумя разными деревьями разбора: возьмём w=abaw = abaw=aba.
Два различных вывода (скобочная группировка отражает структуру двоичного конкатенирования):
1) ((a b) a)((a\ b)\ a)((a b) a):
S⇒S S⇒S S S⇒a S S⇒a b S⇒a b aS \Rightarrow S\ S \Rightarrow S\ S\ S \Rightarrow a\ S\ S \Rightarrow a\ b\ S \Rightarrow a\ b\ aS⇒S S⇒S S S⇒a S S⇒a b S⇒a b a.
2) (a (b a))(a\ (b\ a))(a (b a)):
S⇒S S⇒a S⇒a S S⇒a b S⇒a b aS \Rightarrow S\ S \Rightarrow a\ S \Rightarrow a\ S\ S \Rightarrow a\ b\ S \Rightarrow a\ b\ aS⇒S S⇒a S⇒a S S⇒a b S⇒a b a.
Эти два дерева дают один и тот же выводный ряд символов abaabaaba, но имеют разную структуру — отсюда неоднозначность.
Следствия для парсинга:
- Поскольку грамматика неоднозначна, она не может быть распознаваема как детерминированная LR(1)-грамматика (всякая LR(k)-грамматика однозначна), следовательно исходная грамматика не является LR(1).
- Она также не является LL(1) (LL(1) требует единственного выбора продукции по первому символу при предсказании; неоднозначность и пересекающиеся FIRST-наборы препятствуют этому).
Как модификации влияют:
- Чтобы получить однозначную и LL(1)-совместимую грамматику для множества всех непустых строк над {a,b}\{a,b\}{a,b}, можно факторизовать по первому символу, например
S→a A∣b A,A→a A∣b A∣ε. S \to a\ A \mid b\ A,\qquad A \to a\ A \mid b\ A \mid \varepsilon.
S→a A∣b A,A→a A∣b A∣ε. Здесь FIRST-альтернатив для SSS раздельны ({a}\{a\}{a} и {b}\{b\}{b}), грамматика однозначна и является LL(1) (а значит и LR(1)).
- Если сделать левую рекурсию, например
S→S a∣S b∣a∣b, S \to S\,a \mid S\,b \mid a \mid b,
S→Sa∣Sb∣a∣b, то грамматика может быть однозначной, но из‑за левой рекурсии она не LL(1) без преобразований; LR(1)-парсер с такими правилами справится (LR(1) нормально обрабатывает левую рекурсию).
- В общем: устранение двоичного правила конкатенации S→S SS\to S\ SS→S S в пользу правых/левых линейных или факторизованных правил делает грамматику однозначной; факторизация даёт LL(1), а леворекурсивная форма — удобна для LR(1).