- •6. Генерация команд в компиляторе 44
- •1. Языки и грамматики
- •1.1. Язык как множество
- •1.2. Порождающая грамматика
- •1.3. Процесс порождения
- •1.4. Классификация грамматик по Хомскому
- •1.5. Классификация языков по Хомскому
- •1.6. Задача распознавания цепочек языка
- •2. Принципы трансляции языков программирования
- •3. Лексический анализ
- •3.1. Конечный автомат
- •3.2. Построение детерминированного конечного автомата
- •3.3. Недетерминированный конечный автомат
- •3.4. Преобразование неоднозначной а-грамматики к однозначной
- •3.5. Удаление из грамматики бесполезных нетерминалов
- •3.6. Лексический анализатор
- •4. Синтаксический анализ
- •4.1. Дерево порождения для кс-грамматики
- •4.2. Автомат с магазинной памятью
- •4.4. Левая рекурсия и ее устранение
- •4.5. Преобразование кс-грамматики к обобщенной нормальной форме Грейбах
- •4.6. Детерминированный ll-разбор
- •5. Обратная польская строка, как промежуточная форма программы
- •5.1. Обратная польская строка для арифметических выражений
- •5.2. Генерация опс для арифметических выражений
- •5.3. Вычисление опс для присваиваний и арифметических выражений с индексами
- •5.4. Генерация опс для присваиваний и арифметических выражений с индексами
- •5.5. Опс для условных, циклических и составных операторов
- •5.6. Опс для стандартных операторов
- •5.7. Распределение памяти и описание переменных
- •5.8. Обработка ошибок
- •6. Генерация команд в компиляторе
- •6.1. Распределение памяти при генерации команд
- •6.2. Генерация команд для присваиваний и арифметических выражений
- •6.3. Генерация команд с индексными выражениями
- •6.4. Генерация команд сравнения и перехода
5.4. Генерация опс для присваиваний и арифметических выражений с индексами
Вначале надо расширить грамматику арифметических выражений так, чтобы из начального нетерминала порождалось присваивание, и чтобы операндами могли быть индексируемые элементы массивов.
Пример 14. Грамматика присваиваний и арифметических выражений с индексами для одно- и двумерных массивов (A – начальный нетерминал) будет такой:
A → aH := S
S → S + T | T
T → T * F | F
F → (S) | aH
H → [S] | [S, S] | λ
Последняя группа порождающих правил (для нетерминала H) вносит неопределенность: две различные правые части начинаются с одного и того же терминального символа. Поэтому заменим эту группу правил на следующие правила, добавив в грамматику новый нетерминал:
H → [SK | λ
K → ] | , S]
После этого в грамматике устраним левую рекурсию и преобразуем ее к обобщенной нормальной форме Грейбах, в результате получим правила:
A → aH := S
S → (S)VU | aHVU
U → + TU | λ
T → (S)V | aHV
V → * FV | λ
F → (S) | aH
H → [SK | λ
K → ] | , S]
В табл. 17 представлен построенный по этим правилам LL(1)-анализатор, дополненный семантическими действиями для генерации ОПС. При этом правая часть правила A → aH := S в конце дополнена пустым символом □ для того, чтобы знак операции := генерировался после ОПС для выражения в правой части присваивания.
Табл. 17
|
+ |
* |
( |
) |
a |
[ |
] |
, |
:= |
┴ |
A |
|
|
|
|
aH:=S□ a□□□:= |
|
|
|
|
|
S |
|
|
(S)VU □□□□□ |
|
aHVU a□□□ |
|
|
|
|
|
U |
+TU □□+ |
λ |
λ |
λ |
λ |
λ |
λ |
λ |
λ |
λ |
T |
|
|
(S)V □□□□ |
|
aHV a□□ |
|
|
|
|
|
V |
λ |
*FV □□* |
λ |
λ |
λ |
λ |
λ |
λ |
λ |
λ |
F |
|
|
(S) □□□ |
|
aH a□ |
|
|
|
|
|
H |
λ |
λ |
λ |
λ |
λ |
[SK □□□ |
λ |
λ |
λ |
λ |
K |
|
|
|
|
|
|
] <i> |
, S] □□<i2> |
|
|
Пусть на вход анализатора поступает цепочка M[i] := a*L[i, j + d]. Шаги ее анализа и генерации ОПС представлены в табл. 18. Для сокращения таблицы из нее удалены некоторые шаги, при выполнении которых подряд удаляются из магазина несколько нетерминалов.
Табл. 18
№ шага |
Входные символы |
Содержимое магазина |
Дополнит. магазин |
ОПС |
1 |
M[i] := a*L[i, j + d]┴ |
A ┴ |
□□ |
|
2 |
M[i] := a*L[i, j + d]┴ |
aH:=S□┴ |
a□□□:=□ |
M |
3 |
[i] := a*L[i, j + d]┴ |
H:=S□┴ |
□□□:=□ |
M |
4 |
[i] := a*L[i, j + d]┴ |
[SK:=S□┴ |
□□□□□:=□ |
M |
5 |
i] := a*L[i, j + d]┴ |
SK:=S□┴ |
□□□□:=□ |
M |
6 |
i] := a*L[i, j + d]┴ |
aHVUK:=S□┴ |
a□□□□□□:=□ |
M i |
7 |
] := a*L[i, j + d]┴ |
HVUK:=S□┴ |
□□□□□□:=□ |
M i |
10 |
] := a*L[i, j + d]┴ |
K:=S□┴ |
□□□:=□ |
M i |
11 |
] := a*L[i, j + d]┴ |
]:=S□┴ |
<i>□□:=□ |
M i <i> |
12 |
:= a*L[i, j + d]┴ |
:=S□┴ |
□□:=□ |
M i <i> |
13 |
a*L[i, j + d]┴ |
S□┴ |
□:=□ |
M i <i> |
12 |
a*L[i, j + d]┴ |
aHVU□┴ |
a□□□:=□ |
M i <i> a |
13 |
*L[i, j + d]┴ |
HVU□┴ |
□□□:=□ |
M i <i> a |
14 |
*L[i, j + d]┴ |
VU□┴ |
□□:=□ |
M i <i> a |
15 |
*L[i, j + d]┴ |
*FVU□┴ |
□□*□:=□ |
M i <i> a |
16 |
L[i, j + d]┴ |
FVU□┴ |
□*□:=□ |
M i <i> a |
17 |
L[i, j + d]┴ |
aHVU□┴ |
a□*□:=□ |
M i <i> a L |
18 |
[i, j + d]┴ |
HVU□┴ |
□*□:=□ |
M i <i> a L |
19 |
[i, j + d]┴ |
[SKVU□┴ |
□□□*□:=□ |
M i <i> a L |
20 |
i, j + d]┴ |
SKVU□┴ |
□□*□:=□ |
M i <i> a L |
21 |
i, j + d]┴ |
aHVUKVU□┴ |
a□□□□*□:=□ |
M i <i> a L i |
22 |
, j + d]┴ |
HVUKVU□┴ |
□□□□*□:=□ |
M i <i> a L i |
25 |
, j + d]┴ |
KVU□┴ |
□*□:=□ |
M i <i> a L i |
26 |
, j + d]┴ |
KVU□┴ |
□*□:=□ |
M i <i> a L i |
27 |
, j + d]┴ |
, S]VU□┴ |
□□<i2>*□:=□ |
M i <i> a L i |
28 |
j + d]┴ |
S]VU□┴ |
□<i2>*□:=□ |
M i <i> a L i |
29 |
j + d]┴ |
aHVU]VU□┴ |
a□□□<i2> … |
M i <i> a L i j |
30 |
+ d]┴ |
HVU]VU□┴ |
□□□<i2> … |
M i <i> a L i j |
32 |
+ d]┴ |
U]VU□┴ |
□<i2>*□:=□ |
M i <i> a L i j |
33 |
+ d]┴ |
+TU]VU□┴ |
□□+<i2>… |
M i <i> a L i j |
34 |
d]┴ |
TU]VU□┴ |
□+<i2>*□:=□ |
M i <i> a L i j |
35 |
d]┴ |
aHVU]VU□┴ |
a□□+<i2>… |
M i <i> a L i j d |
36 |
]┴ |
HVU]VU□┴ |
□□+<i2>… |
M i <i> a L i j d |
38 |
]┴ |
U]VU□┴ |
+<i2>*□:=□ |
M i <i> a L i j d + |
39 |
]┴ |
]VU□┴ |
<i2>*□:=□ |
M i<i>a L i j d+<i2> |
40 |
┴ |
VU□┴ |
*□:=□ |
M i<i>a L i j d+<i2>* |
42 |
┴ |
□┴ |
:=□ |
M i<i>a Li j d+<i2>*:= |
43 |
┴ |
┴ |
□ |
M i<i>a Li j d+<i2>*:= |
Конец примера.