Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2215 / 889 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 6:

Синтаксические анализаторы. Нисходящие анализаторы

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >

Условия использования метода рекурсивного спуска

Метод рекурсивного спуска без возвратов можно использовать только для грамматик, правила которых удовлетворяют следующему условию: первого символа каждого правила должно быть достаточно для того, чтобы определить, какое правило применимо в данном случае. Более точно это условие можно формализовать путем определения множества FIRST.

Определение.Для КС-грамматики G и цепочки w, состоящей из терминальных и нетерминальных символов, определим множество FIRST k (w) следующим образом:

FIRST k (w) = {x | w =>* xv, |x| = k или w =>* x, |x| < k}, где k - натуральное число.

Иными словами, множество FIRST k (w) состоит из всех терминальных префиксов длины k терминальных цепочек, выводимых из w.

Пример.Рассмотрим грамматику, порождающую подмножество типов языка Pascal.

type \to imple
\\
type \to \widehat{\ }\,\textbf{id}
\\
type \to \textbf{array}\ [simple]\ \textbf{of}\ type
\\
simple \to \textbf{integer}
\\
simple \to \textbf{char}
\\
simple \to \textbf{num .. num}

Для этой грамматики мы имеем:

FIRST1 (simple) = {integer, char, num}
FIRST1 (^id) = {^}
FIRST1 (array [simple] of type) = { array }

Понятно, что если цепочка w состоит только из терминалов, то FIRST k (w) - это первые k символов цепочки w , если |w| >=, или это сама цепочка w, если |w| < k <

Алгоритм построения множества FIRST

Прежде всего, определим множество FIRST для всех символов грамматики:

  1. если X - терминал, то FIRST (X) = X
  2. для правила X \to \varepsilon добавим \varepsilon к множеству FIRST (X)
  3. если X - нетерминал и X \to Y_{1}Y_{2}{\ldots} Y_{k} - правило грамматики, то добавим терминал а в FIRST(X), если для некоторого i этот терминал a принадлежит FIRST (Y_{i}) и \varepsilon принадлежит всем множествам FIRST (Y_{1}), {\ldots} , FIRST (Y_{i-1}) , то есть Y_{1} , {\ldots}, Y_{i-1}=>*\varepsilon . Если \varepsilon принадлежит FIRST (Y_{j}) для всех j =1, 2, {\ldots}, k , то добавим \varepsilon в FIRST(Y).

Теперь сформулируем сам алгоритм построения множества FIRST(w).

Вход.КС-грамматика G=(N, T, P, S) и цепочка w терминальных и нетерминальных символов.

Выход. FIRST (w).

Метод.Добавим в FIRST (X 1 X 2 …X k) все непустые символы из FIRST (X1). Затем, если \varepsilon принадлежит FIRST (X1), то добавим все непустые символы из FIRST (X2), и так далее. Наконец, если для всех j FIRST (Xj) содержит пустой символ, то мы добавим \varepsilon в множество FIRST (X1 X2…Xk) .

Пример.Рассмотрим грамматику с правилами:

{S \to B A}
\\
{A \to +B A }
\\
{A \to  \varepsilon }
\\
{B \to D C}
\\
{C \to * D C }
\\
{C \to  \varepsilon }
\\
{D \to (S) }
\\
{D \to a}

Для этой грамматики множества FIRST определяются следующим образом:

\begin{align*}
&{FIRST (D) = {\{}(, a{\}}, 
\ \
FIRST (C) = {\{}*, }\varepsilon { {\}}, 
\ \
FIRST (B) = FIRST (D), 
\\
&FIRST (A)={\{}+, }\varepsilon { {\}}, } 
\ \
{FIRST (S) = {\{}(, a{\}}} 
\end{align*}

< Лекция 5 || Лекция 6: 123456 || Лекция 7 >