Конечные преобразователи. (Простейший транслятор)
Алгоритм работы синтаксически управляемого перевода
Вход: СУ – схема с входной грамматикой Gi {N, S, Pi, S}и дерево вывода D.
Выход: Дерево D’ в грамматике G0 {N, D, P0, S}.
Шаг 1: Применять шаг 2 начиная с корня D.
Шаг 2: Пусть этот шаг (2) применяется к вершине n, внутренней в дереве D, и пусть n1, nk – прямые потомки. Пусть А:=a - правило из Pi, соответствующее вершине n.
Цепочка a образуется конкатенацией меток n1…nk.
Выбрать из R правило А:=a, b и переставить вершины согласно соответствию, установленному этими правилами.
Применять шаг 2 к вершинам, не являющимся листьями.
Рассмотрим следующий пример, поясняющий алгоритм синтаксически управляемого перевода:
T= {(S,A), (0,1), (a,b), R, S};
СУ – схема, у которой в правилах соответствия нетерминалов, однозначное называется простой.
S |
S A a |
A S a |
S A a |
b |
b |
b |
b |
S |
0 A S1 |
0 S A1 |
0 A S1 |
000111 bbbbaaa
S=> 0AS, SAa =>00SAS, SASaa =>000ASAS, SASAaaa => 0001111, bbbbaaa.
Необходима индексация.
|
|
Простые СУ – переводы образуют важный класс трансляторов, так как легко реализуются преобразованиями с магазинной памятью.
В его основе лежит конечный автомат.
Конечный преобразователь:
M= {Q, S, D, d0, q0, F},
где Q – множество состояний;
СУ |
Только читать |
Только писать |
D - выходной алфавит;
d0 – функция отображения;
q0 – начальное состояние;
F – множество заключительных состояний.
Q * Sие -> Q*D*.
Конфигурация определяется: (q, x, y).
Если d(q0, a)= d(q1, b), то (q0, ax, y)|- (q1, x, yb).
Цепочка y называется выходом цепочки x, если имеет место следующее:
+ |
(q0, x, y)|--- (q1, x, y), где x Î S*, y Î A*, q1 Î F
+ |
|--- вывод за какое-то количество шагов.
Перевод, определяемый конечными преобразованиями, называется регулярным («правильным»): S:= a + S |a-S| -a | +a | a.
Любое арифметическое выражение может содержать любое количество операторов - + - - + + - - а - + - - а, то есть ошибки при трансляции не будет. Транслятор сделает так, чтобы выдавался один оператор. Это происходит следующим образом.
Количество состояний:
S {+, -, а}.
D {+, -, а}.
Функцию отношения зададим диаграммой:
q1 |
q4 |
q2 |
q3 |
q0 |
+ / e |
+ / e |
a / a |
+ / e |
a / +a |
- / e |
- / e |
a / - a |
- / e |
- / e |
- / e |
+ / e |
a / - a |
- / e |
+ / e |
+ / e |
Для первого идентификатора, Для оставшихся идентификаторов
так как не ставим знак «+»;
(a + a - a) = итог.
(q0,- + - - + - a + - - a + + - - - +a,e)|→ (q1, + - - + - a + - - a + + - - - +a,e)| |→
(q1, - - + - a + - - a + + - - - +a,e) |→ (q0, - + - a + - - a + + - - - +a,e) |→
(q1, + - a + - - a + + - - - +a,e) |→ (q1,- a + - - a + + - - - +a,e) |→
(q0,a + - - a + + - - - +a,e) |→ (q2,+ - - a + + - - - +a,a) |→
(q3,- - a + + - - - +a, a) |→ (q4,- a + + - - - + a, a) |→
(q3,a + + - - - +a, a+a) |→ (q2,+ + - - - +a, a+a) |→
|
|
(q3,+ - - - +a, a+a) |→ (q3,- - - +a, a+a) |→
(q4,- - +a, a+a) |→ (q3, - +a, a+a) |→
(q4,+a, a+a) |→ (q4,a, a+a) |→ (q2,e, a+a-a)
Конечный преобразователь назовем детерминированным, если:
"q Î Q, |d(q,a)| £ 1, где |d(q,a)|- мощность;
d (q,e)=0.
q1 |
a / b |
e / b |
q0 |
a |
d(q0, a) = (q0, b);
d(q0, e) = (q0, b);
(q0, a, e) |→ (q1, e, b) |→ (q1, e, b)
Нужно в заключительном состоянии запретить е – такты.
Они могут быть получены путем добавления автомату с магазинной памятью выходной цепочки.
МП – преобразователь содержит 8 символов:
{Q, S, Г, D, d, q0, Z, F}, где все элементы означают то же, что и раньше, кроме функции отображения:
d: Q*S*Г -> Q1*Г**D*, где S - входной символ, Г – магазинный символ.
Конфигурация содержит 4 символа:
(q, aw, z, y),
где q – состояние;
aw – входная цепочка;
z – магазин;
y - входная цепочка.
d (q, a, gz) = (q1, az, b) – функция отображения;
(q, aw, gz, y)|¾ (q1, w, az, yb) Записывают только верх магазина (gz, az), дно не пишут.
+ |
+ |
Преобразователь переводит цепочку х в цепочку у опустошением магазина только тогда, когда имеет место следующее: (q, x, a, e)|¾ (q1, e, e, y).
Расширенный МП – преобразователь определяется аналогично расширенному МП – автомату.
Пример: Переведем польскую запись в некоторую цепочку. Используем все ту
же грамматику.
Запишем автомат:
{(q0,q1), (*,+,(,),i), (N T $), (*,+,(,),i), (d, q0, $, q1)}
(*,+,(,),i) – терминальные символы. (N – нетерминальные, T – терминальные).
Q*E*Г -> Q*Г**D*.
1. (q0, e, E) = (q0, e+T, ET+);
2. (q0, e, E) = (q0, T, T);
3. (q0, e, T) = (q0, T*F, TF*);
4. (q0, e, T) = (q0, F, F);
5. (q0, e, F) = (q0, (E), E);
6. (q0, e, F) = (q0, i, i);
7. (q0, a, a) = (q0, e, e);
8. (q0, e, e) = (q0, e, y).
i*(i+i) в этом случае мы должны получить iii+*.
(q0, i*(i+i), E, e) |¾ (q0, i*(i+i), T, T) |¾
(q0, i*(i+i), T*F, TF*) |¾ (q0, i*(i+i), T*(E), TE*) |¾
(q0, i*(i+i), T*(E+i), TEi+*) |¾ (q0, i*(i+i), T*(T+i), TTi+*) |¾
(q0, i*(i+i), i*(i+i), iii+*) |¾ (q0, e, e$, iii+*) |¾ (q0, e, e, iii+*)
7 – сравнение выходной цепочки со входной.