
- •3. Описание этапа синтаксического анализа
- •3.1. Посторенние кс-грамматики входного языка и разбиение ее на подграмматики
- •3.2. Описание промежуточного языка
- •3.3. Неформальное описание перевода
- •3.4. Построение атрибутной транслирующей грамматики
- •3.5. Построение атрибутного дмп-процессора
- •3.6. Тестирование атрибутного дмп-процессора
3.4. Построение атрибутной транслирующей грамматики
Атрибуты бывают двух типов – синтезированные и унаследованные.
Атрибуты, значения которых вычисляются при движении по дереву вывода снизу вверх, традиционно называются синтезируемыми (значение атрибута синтезируется из значений атрибутов потомков). Термин унаследованный означает, что значение атрибута зависит от значений атрибутов предка символа или атрибутов его соседей в дереве вывода.
Будем обозначать с помощью p унаследованные атрибуты, а q, t и r – синтезируемые.
Правила вывода АТ-граматики G1 (головная подграмматика)
PROG → _PROG _ID; DEFH SOP
PROG → _PROG _ID; SOP
PROG → DEFH SOP
PROG → SOP
DEFH → DEFH DEF
DEFH → DEF
SOP → _BEGIN {BLBEG} LOP _END {BLEND}
DEF → _TYPE TSEC
DEF → _CONST CSEC
DEF → _VAR VSEC
DEF → _LABEL LSEC
TSEC → TSEC TDEF
TSEC → TDEF
TDEF → _IDp1 = VLTp2; {ТИП}q1,q2,r
r ← NewType
q2 ← p2 // значение типа
q1 ← p1 // имя типа
LSEC → LDEF;
LDEF → LDEF, NLp {МЕТКА}q,r
r ← NewLabel
q ← p // имя метки
LDEF → NLp {МЕТКА}q,r
r ← NewLabel
q ← p // имя метки
NLq → _IDp
q ← p
NLq _NUMp
q ← p
NewType – функция, которая выдает указатель на свободную позицию в таблице типов;
NewLabel – функция, которая выдает указатель на свободную позицию в таблице меток.
Операционные символы:
{ТИП}q1,q2,r – записывает имя q1 и значение q2 в таблицу типов по адресу r;
{МЕТКА}q,r – записывает имя q в таблицу меток по адресу r.
Правила вывода АТ-граматики G1(описание типов)
VLTq → _ARRAY STRTp
q ← p // адрес в вспомогательной таблице
VLTq → SBTp
q ← p
VLTq → _INT
q ← integer
VLTq → _BOOL
q ← boolean
Правила вывода АТ-граматики G2(“хвост” описания матричного типа)
STRTq → [ NMp1, NMp2] {МАТРИЦА} q1,q2,r
r ← NewElem
q2 ← p2
q1 ← p1
q ← r // адрес в вспомогательной таблице
NMq → _IDp
q ← p
NMq _NUMp
q ← p
NewElem – функция, которая выдает указатель на свободную позицию в вспомогательной таблице.
Операционный символ:
{МАТРИЦА}q1,q2,r – записывает параметры матрицы q1 и q2 в вспомогательную таблицу по адресу r.
Правила вывода АТ-граматики G3(описания диапазонного типа)
SBTq → _IDp1 _DDOT _IDp2 {ДИАПАЗОН} q1,q2,r
r ← NewElem
q2 ← p2
q1 ← p1
q ← r // адрес в вспомогательной таблице
SBTq → _IDp1 _DDOT NMp2
SBTq → NMp1 _DDOT _IDp2
SBTq → NMp1 _DDOT NMp2
SBTq → _IDp
q ← p
NMq → _NUMp
q ← p
NMq → - _NUMp
q ← -p
Операционный символ:
{ДИАПАЗОН}q1,q2,r – записывает параметры диапазона q1 и q2 в вспомогательную таблицу по адресу r.
Правила вывода АТ-граматики G6(список объявлений переменных)
VSEC → VSEC VDEF
VSEC → VDEF
VDEF → LV: VLTp; {ПЕРЕМЕННАЯ}q,r
r ← NewVar
q ← p
LV → LV, _IDp {СПИСОК}q,r
r ← NewElem
q ← p
LV → _IDp {СПИСОК}q,r
r ← NewElem
q ← p
NewVar – функция, которая выдает указатель на свободную позицию в таблице переменных.
Операционные символы:
{СПИСОК}q,r – записывает имя q в вспомогательную таблицу по адресу r;
{ПЕРЕМЕННАЯ}q,r – читает элемент (имя переменной) из вспомогательной таблицы и записывает его со значением типа q в таблицу переменных по адресу r (он вызывается столько раз, сколько элементов во вспомогательной таблице).
Правила вывода АТ-граматики G4(список объявлений констант)
CSEC → CSEC CDEF
CSEC → CDEF
CDEF → _IDp1 = VLCp2; {КОНСТАНТА}q1,q2,t,r
r ← NewConst
t ← ConstType(r)
q2 ← p2 // значение константы
q1 ← p1 // имя константы
CDEF → _IDp1: _ARRAY STRTp2 = MCp3; {М_КОНСТАНТА}q1,q2,q3,r
r ← NewMatrConst
q3 ← p3 // значение константы
q2 ← p2 // тип константы
q1 ← p1 // имя константы
CDEF → _IDp1: _IDp2 = MCp3; { М_КОНСТАНТА}q1,q2,q3,r
r ← NewMatrConst
q3 ← p3 // значение константы
q2 ← p2 // тип константы
q1 ← p1 // имя константы
VLCq → _IDp
q ← p
VLCq → - _NUMp
q ← -p
VLCq → _NUMp
q ← p
VLCq → _TRUE
q ← true
VLCq → _FALSE
q ← true
NewConst – функция, которая выдает указатель на свободную позицию в таблице констант;
NewMatrConst – функция, которая выдает указатель на свободную позицию в таблице матриц.
Операционные символы:
{КОНСТАНТА}q1,q2,t,r - записывает имя q1, значение q2 и тип t в таблицу констант по адресу r;
{М_КОНСТАНТА}q1,q2,q3,r - записывает имя q1, тип q2 и адрес q3 (хранения матрицы в таблице матриц) в таблицу матриц-констант по адресу r.
Правила вывода АТ-граматики G8(выражение)
EXPq,t → EMp1,p2 _RELp3 EVp4,p5 {REL}m,q1,q2, q3,q4,r
m ← p3 //операнд
q1 ← p1
q2 ← p2
q3 ← p4
t, q4 ← p5 // тип
q ← r // местонахождение значения
EXPq,t → EARp1,p2
t ← p2 //тип
q ← p1 // местонахождение значения
EARq,t → EMp1,p2 LOWp3 EVp4,p5 {LOW}m,q1,q2, q3,q4,r
LOW [+, -, _OR]
m ← p3 //операнд
q1 ← p1
q2 ← p2
q3 ← p4
t, q4 ← p5 // тип
q ← r // местонахождение значения
EARq,t → EMp1,p2
t ← p2 //тип
q ← p1 // местонахождение значения
EMq,t → EMp1,p2 _MIDp3 EVp4,p5 {MID}m,q1,q2, q3,q4,r
m ← p3 //операнд
q1 ← p1
q2 ← p2
q3 ← p4
t, q4 ← p5 // тип
q ← r // местонахождение значения
EMq,t → EVp1,p2
t ← p2 //тип
q ← p1 // местонахождение значения
EVq,t → HIGHp1 EVp2,p3 {HIGH}m,q1,q2,r
HIGH [-, _NOT]
m ← p1 //операнд
q1 ← p2 //значение
t, q2 ← p3 //тип
q ← r // местонахождение значения
EVq,t → Vp1,p2
t ← p2 //тип
q ← p1 // местонахождение значения
EVq,t → _NUMp
t ← integer //тип
q ← p //значение
EVq,t → _TRUE
t ← boolean //тип
q ← true //значение
EVq,t → _FALSE
t ← boolean //тип
q ← false //значение
EVq,t → (EXPp1,p2)
t ← p2 //тип
q ← p1 // местонахождение значения
Vq,t → _IDp1,p2
t ← p2 //тип переменной
q ← p1 //адрес переменной
Vq,t → _IDp1,p2 [_NUMp3, _NUMp3] {SUBS}q1, q2,q3,q4,r
q4 ← p4 //индес
q3 ← p3 //индес
q2 ← p2 //тип переменной
q1 ← p1 //адрес переменной
t ← boolean //тип переменной
q ← r // местонахождение значения переменной
V → _ID [_ID, _NUM]
V → _ID [_NUM, _ID]
V → _ID [_ID, _ID]
Операционный символ {REL}m,q1,q2, q3,q4,r
if (q2==INTEGER && q4==INTEGER)
{ Записать на выход триаду вида
-
m
q1
q3
где m - <, <=, =, <>, >= , >
}
else { Ошибка: несответствие типов }
Операционный символ {LOW}m,q1,q2, q3,q4,r [{MID} m,q1,q2, q3,q4,r]
if (q2==q4)
{ Записать на выход триаду вида
-
M
q1
q3
где m – add, sub (для INTEGER) или or (для BOOLEAN)
[mul, div, mod (для INTEGER) или and (для BOOLEAN)]
}
else { Ошибка: несответствие типов
}
Операционный символ {HIGH}m,q1,q2,r
Записать на выход триаду вида
-
m
q1
где m – neg (для INTEGER) или not (для BOOLEAN)
Операционный символ {SUBS}q1, q2,n1,n2,r
if (q2==’матрица’)
{ Записать на выход последовательность триад вида
-
1
row
q1
n1
2
col
q1
n2
3
add
(1)
(2)
4
subs
q1
(4)
}
else { Ошибка: несответствие типа }
Правила вывода АТ-граматики G7(оператор)
OP → _IDp: {DEFL}q UOP
q ← p
OP → _NUMp: {DEFL}q UOP
q ← p
OP → UOP
UOP → Vp1,p2 _EQ EXPp3,p4 {EQ}q1,q2,q3,q4
q1 ← p1
q2 ← p2
q3 ← p3
q4 ← p4
UOP → _IF EXPp1,p2 _THEN {BF}q1,q2,r IFOPq3
r ← NewLabel
q1 ← p1 // местонахождение значения выражения
q2 ← p2 // тип выражения
q3 ← r
UOP → _REPEAT {DEFL}r LOP _UNTIL EXPp3,p4 {BF}q1,q2,q3
r ← NewLabel
q1 ← p3 // местонахождение значения выражения
q2 ← p4 // тип выражения
q3 ← r
UOP → _GOTO _IDp {BRL}q
q ← p
UOP → _GOTO _NUMp {BRL}q
q ← p
UOP → _READ(LV)
UOP → _WRITE(LE)
UOP → _WRITES(_STRp1) {WRITES}q1
q1 ← p1
UOP → _WRITEM(_IDp1,p2) {WRITEM}q1,q2
q1 ← p1
q2 ← p2
UOP → _MOPp1(_IDp2,p3, _IDp4,p5, _IDp6,p7) {_MOP}q1,q2,q3,q4,q5,q6,q7
q1 ← p1
q2 ← p2
q3 ← p3
q4 ← p4
q5 ← p5
q6 ← p6
q7 ← p7
UOP → _BEGIN {BLBEG} LOP _END {BLEND}
Vq,t → _IDp1,p2 [_NUMp3, _NUMp3] {ADDR}q1,q2,q3,q4,r
q4 ← p4 //индес
q3 ← p3 //индес
q2 ← p2 //тип переменной
q1 ← p1 //адрес переменной
t ← boolean //тип переменной
q ← r // местонахождение значения переменной
V → _ID [_ID, _NUM]
V → _ID [_NUM, _ID]
V → _ID [_ID, _ID]
V → _ID
LE → LE, EXPp1,p2 {WRITE}q1,q2
q1 ← p1
q2 ← p2
LE → EXPp1,p2 {WRITE}q1,q2
q1 ← p1
q2 ← p2
Операционный символ {DEFL}q
Записать на выход триаду вида
-
DEFL
q
Операционный символ {EQ}q1,q2,q3,q4
if (q2==q4)
{ Записать на выход триаду вида
-
EQ
q3
q1
}
else { Ошибка: несответствие типов }
Операционный символ {BF}q1,q2,r
if (q2==’BOOLEAN’)
{ Записать на выход триаду вида
-
BF
r
q1
}
else { Ошибка: Неверный тип выражения в операторе IF }
Операционный символ {WRITE}q1, q2
if (q2==’BOOLEAN’) or(q2==’INTEGER’)
{ Записать на выход триаду вида
-
WRITE
q1
}
else { Ошибка: Неверный тип выражения в операторе WRITE}
Операционный символ {WRITES}q
Записать на выход триаду вида
-
WRITES
q
Операционный символ {WRITEM}q1, q2
if (q2==’матрица’)
{ Записать на выход триаду вида
-
WRITEM
q1
}
else { Ошибка: Неверный тип выражения в операторе WRITES}
Операционный символ {BLBEG}
Записать на выход триаду вида
-
BLBEG
Операционный символ {BLENDG}
Записать на выход триаду вида
-
BLEND
Операционный символ {BRL}q
Записать на выход триаду вида
-
BRL
q
Операционный символ {ADDR}q1, q2,n1,n2,r
if (q2==’матрица’)
{ Записать на выход последовательность триад вида
-
1
row
q1
n1
2
col
q1
n2
3
add
(1)
(2)
4
addr
q1
(4)
}
else { Ошибка: несответствие типа }
Операционный символ {_MOP}q1,q2,q3,q4,q5,q6,q7
if (q3 ==’матрица’) and (q5 ==’матрица’) and (q7 ==’матрица’)
and (РАЗМ(q3) = РАЗМ(q5) = РАЗМ(q7))
{ Записать на выход последовательность триад вида
-
1
m
q2
q4
2
ldm
q6
n2
где m – con, diz
}
else { Ошибка: несответствие типа }
Правила вывода АТ-граматики G9(список идентификаторов)
LV → LV, _IDp1,p2 {READ}q1,q2
q1 ← p1
q2 ← p2
LV → _IDp1,p2 {READ}q1,q2
q1 ← p1
q2 ← p2
Операционный символ {READ}q1,q2
if (q2==’INTEGER’)
{ Записать на выход триаду вида
-
READ
q1
}
else { Ошибка: ожидается целочисленная переменная }
Правила вывода АТ-граматики G10(“хвост” оператораif)
IFOPp → OP {DEFL}q
q ← p
IFOPp → OP _ELSE {BRL}r {DEFL}q1 OP {DEFL}q2
r ← NewLabel
q1 ← p
q2 ← r