\(\mathrm{FIRST}(α) = \{ t | t \in T, α \overset{*}\Rightarrow t β \} \cup \{ ε | α \overset{*}\Rightarrow ε \}\)
Множество \(t \in T\), таких, что существует порождение \(S \overset{*}\Rightarrow α A t β\), и \(\$\), если существует порождение \(S \overset{*}\Rightarrow α A\).
\(\mathrm{FOLLOW}(A) = \{ t | t \in T, S \overset{*}\Rightarrow α A t β \} \cup \{ \$ | S \overset{*}\Rightarrow α A \}\)
Вычисление \(\mathrm{FIRST}(α)\) возможно по следующему принципу: \[\mathrm{FIRST}(X α) =\] \[\begin{cases} \mathrm{FIRST}(X), & ε \notin \mathrm{FIRST}(X) \\ (\mathrm{FIRST}(X) \setminus \{ε\}) \cup \mathrm{FIRST}(α), & \text{otherwise} \end{cases}\] \[\mathrm{FIRST}(X) =\] \[\begin{cases} X, & X \in T \cup \{ε\}\\ \bigcup \mathrm{FIRST}(β), & X \in N,\, \forall β \in \{β | (X \to β) \in P \} \end{cases}\]
Для вычисления \(\mathrm{FOLLOW}(A)\), используем следующий принцип: \[\mathrm{FOLLOW}(S) = \{\$\}\] \[\mathrm{FOLLOW}(B) =\] \[\{\mathrm{FIRST}(β) \setminus \{ε\} | A \to α B β\} \\ \cup \{\mathrm{FOLLOW}(A) | A \to α B β, ε \in \mathrm{FIRST}(β)\}\]
Алгоритм выбора продукции на основе функций \(\mathrm{FIRST}\) и \(\mathrm{FOLLOW}\):
При разборе \(A\in N\), выбирается \(A \to α\), если текущий входной символ \(c \in \mathrm{FRIST}(α)\) или, если \(ε \in \mathrm{FIRST}(α)\), то в \(c\in\mathrm{FOLLOW}(A)\).
Из этого формальные требования для \(LL(1)\) грамматики:
\(\forall A \to α_i\), \(α_i \neq α_j, i\neq j\) выполняются:
\(LL(k)\) включает только нелеворекурсивные однозначные грамматики.
Формальный алгоритм: для каждого нетерминала, для всех продукций этого нетерминала, ищется наиболее длинный префикс, общий для 2 или более альтернатив. Затем применяется один шаг замены. Для оставшихся продукций, процесс повторяется.
stack.push($);
stack.push(S);
X = stack.top(); // == S
a = getNextToken();
while(X != $) {
if (X == a) {
a = getNextToken();
stack.pop();
}
else if(X -- терминал)
reportError();
// далее X -- нетерминал
else if(M[X, a] == Y₁ Y₂ … Yₖ) {
print("X -> Y₁ Y₂ … Yₖ");
stack.pop();
if(M[X, a] != ε) {
for(l in k…1)
stack.push(Yₗ);
}
}
// нет записи M[X, a]
else reportError();
X = stack.top();
}
$
– конец входной строки.
Вызовы getNextToken()
после конца входной строки возвращают $
Управляющая таблица. \(\forall A \to α\):
Отметим, \(\$ \in \mathrm{FOLLOW}(A)\).
Автомат, разбирающий \(LL(1)\)-грамматику, называется \(LL(1)\)-автоматом.
\[\begin{align} E & \to E + T | T \\ T & \to T * F | F \\ F & \to ( E ) | val \\ \end{align}\]
\[\begin{align} E & \to E + T | T \\ T & \to T * F | F \\ F & \to ( E ) | val \\ \end{align}\]
Удалим левую рекурсию.
\[\begin{align} E & \to T E' \\ E' & \to + T E' | ε \\ T & \to F T' \\ T' & \to * F T' | ε \\ F & \to ( E ) | val \\ \end{align}\]
\[\begin{align} E & \to T E' \\ E' & \to + T E' | ε \\ T & \to F T' \\ T' & \to * F T' | ε \\ F & \to ( E ) | val \\ \end{align}\]
\[\begin{align} E & \to T E' \\ E' & \to + T E' | ε \\ T & \to F T' \\ T' & \to * F T' | ε \\ F & \to ( E ) | val \\ \end{align}\]
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | ||||||
\(E'\) | ||||||
\(T\) | ||||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | |||||
\(E'\) | ||||||
\(T\) | ||||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | ||||||
\(T\) | ||||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | |||||
\(T\) | ||||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | ||||
\(T\) | ||||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | ||||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | |||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | \(FT'\) | ||||
\(T'\) | ||||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | \(FT'\) | ||||
\(T'\) | \(*FT'\) | |||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | \(FT'\) | ||||
\(T'\) | \(ε\) | \(*FT'\) | ||||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | \(FT'\) | ||||
\(T'\) | \(ε\) | \(*FT'\) | \(ε\) | |||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | \(FT'\) | ||||
\(T'\) | \(ε\) | \(*FT'\) | \(ε\) | \(ε\) | ||
\(F\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | \(FT'\) | ||||
\(T'\) | \(ε\) | \(*FT'\) | \(ε\) | \(ε\) | ||
\(F\) | \((E)\) |
\(val\) | \(+\) | \(*\) | \((\) | \()\) | \(\$\) | |
---|---|---|---|---|---|---|
\(E\) | \(TE'\) | \(TE'\) | ||||
\(E'\) | \(+TE'\) | \(ε\) | \(ε\) | |||
\(T\) | \(FT'\) | \(FT'\) | ||||
\(T'\) | \(ε\) | \(*FT'\) | \(ε\) | \(ε\) | ||
\(F\) | \(val\) | \((E)\) |