- •Пояснительная записка к курсовой работе (вар16)
- •2008 Оглавление
- •Задание
- •Описание синтаксиса языка в форме Бэкуса-Наура Teрминальные символы:
- •Программа
- •Оператор ввода
- •Оператор вывода
- •Оператор безусловного перехода
- •Оператор условного перехода
- •Оператор Цикла
- •Арифметические выражения
- •Переменная
- •Оператор присваивания
- •Объявления переменных, констант и типов
- •Операции входного языка и их приоритет
- •Перечисление лексем
- •Синтаксический анализ и перевод во внутреннюю форму
- •Кс-грамматика входного языка
- •Основная грамматика
- •Подграмматика составного оператора
- •Подграмматика оператора
- •Подграмматика оператора_вывода
- •Подграмматика для операторов
- •Подграмматика объявлений
- •Подграмматика объявления констант
- •Подграмматика арифметических выражений
- •Подграмматика переменной
- •Описание промежуточного языка.
- •Спецификация тетрад
- •Описание перевода (постфиксная s – атрибутная транслирующая грамматика) каждой конструкции входного языка
- •Основная грамматика
- •Подграмматика для операторов
- •Подграмматика объявления констант
- •Связь между дмп-процессорами и подграмматиками
- •Пример перехода от основной грамматики к подграмматике составного оператора Управляющая таблица основной грамматики
- •Управляющая таблица подграмматики составного оператора
- •S– атрибутный дмп процессор
- •Пример атрибутного перевода для арифметических выражений
- •Управляющая таблица подграмматики оператора
- •Управляющая таблица подграмматики оператора вывода
- •Реализация компилятора
- •Генерация ассемблерного кода
Описание перевода (постфиксная s – атрибутная транслирующая грамматика) каждой конструкции входного языка
Все нетерминалы содержат только синтезированныеатрибуты.
Операционные символы содержат как унаследованные, так и синтезированные атрибуты. Синтезтрованные атрибуты операционных символов – это те атрибуты, значения которых есть результат некоторой функции (НОВЭЛТ, НОВМЕТ, ..). Все остальные атрибуты операционных символов – унаследованные.
Основная грамматика
PRG -> voi mai ( ) SOP
PRG -> GD voi mai ( ) SOP
GD -> GD DES
GD -> DES
Подграмматика составного оператора
SOP -> { SET }
SOP -> { }
SET -> SET OP
SET -> OP
Подграмматика оператора
OP -> LOP OPS
OP -> OPS
LOP -> idp1 : {МЕТКА}p2
p2p1
OPS -> OPN
OPS -> GOT
OPS -> IN
OPS -> OUT
OPS -> SOP
OPS -> ;
GOT -> got idp ; {БП}q
qp
IN -> scn ( LIN ) ;
LIN -> VARp {ВВОД}q
qp
LIN -> LIN , VARP {ВВОД}q
qp
Подграмматика оператора вывода
OUT -> prn ( LO ) ;
LO -> AEXp {ВЫВОД}q
qp
LO -> LO , AEXp {ВЫВОД}q
qp
Операционные символы:
|
{МЕТКА}A |
Идентификатору A1задается класс метка и ссылка указывает на таблицу меток, в которую добавляется текущий номер тетрады. |
|
{БП}A |
Если A– идентификатор и его класс – метка, то генерируется тетрада:JMPA1, иначе ошибка. |
|
{ВВОД}A |
Если A– переменная целого или вещественного типов, то в зависимости от типа переменнойAгенерируется тетрада:SCAN(см. таблицу), иначе ошибка. |
|
{ВЫВОД}A |
Если A– переменная или константа целого или вещественного типов, то в зависимости от типа значенияAгенерируется тетрада:PRINT(см. таблицу), иначе ошибка. |
|
тип A |
SCAN |
|
|
float |
SCANF A |
PRINTF A |
|
int |
SCANI A |
PRINTF A |
Подграмматика для операторов
OPN -> FOR
OPN -> IF
OPN -> GIV
FOR -> for HDq1,q2 ) OP {БП}m1 {ИМ}m2
m1q2
m2q1
HDp1,p2 -> HD0q1,q2,q3,q4 OGV {БП}m {ИМ}m1
mq1
m1q3
p1q2
p2q4
HDp1,p2 -> HD0q1,q2,q3,q4 {БП}m {ИМ}m1
mq1
m1q3
p1q2
p2q4
HD0p1,p2,p3,p4 -> HD1q LEXr ; {ДВМ}m {УПЛ}r1,m1 {ДВМ}n {БП}n1 {ДМ}n2
p1q
mНОВМЕТ
p2,m1m
nНОВМЕТ
p3,n1n
n2НОВМЕТ
p4n2
HD0p1,p2,p3,p4 -> HD1q ; {ДВМ}n {ДВМ}m {БП}m1 {ДМ}m2
nНОВМЕТ
mНОВМЕТ
p3,m1m
m2НОВМЕТ
p4m2
p2n
p1q
HD1p -> ( ; {ДМ}m
mНОВМЕТ
pm
HD1p -> ( GIV {ДМ}m
mНОВМЕТ
pm
IF -> IF1p
IF -> IF1p els op {ИМ}q
qp
IF1p -> if CONp1 ) op {ДВМ}k {БП}k1 {ИМ}q {ИМ}k2
qp1
kНОВМЕТ
p, k2, k1k
CONp1 -> ( LEXq {ДВМ}m {УПЛ}r,m1
rq
m1,mНОВМЕТ
p1m
GIV -> OGV ;
OGV -> VARp = AEXq {=}q1,q2
p1p
q1q
LEXp -> LEXp1 != LE1q {!=}r1,r2,r3
p,r3НОВЭЛТ
r1p1
r2q
LEXp -> LEXp1 == LE1q {==}r1,r2,r3
p,r3НОВЭЛТ
r1p1
r2q
LEXp -> LE1q
pq
LE1p -> AEXq
pq
LE1p -> LE1p1 > AEXq {<}r1,r2,r3
r1q
r2p1
p,r3НОВЭЛТ
LE1p -> LE1p1 < AEXq {<}r1,r2,r3
r1p1
r2q
p,r3НОВЭЛТ
LE1p -> LE1p1 >= AEXq {<=}r1,r2,r3
r1q
r2p1
p,r3НОВЭЛТ
LE1p -> LE1p1 <= AEXq {<=}r1,r2,r3
r1p1
r2q
p,r3НОВЭЛТ
Операционные символы:
|
{ДВМ}A1 |
Добавляет виртуальную метку в таблицу меток, и возвращает ее номер в A1 |
|
{ИМ}A1 |
Инициализируется метка с номером A1– записывается в таблицу меток номер текущей тетрады. |
|
{ДМ}A1 |
Метке с номером A1присваивается номер следующей тетрады. |
|
{УПЛ}A1,A2 |
Если A1– переменная или константа типаint, то генерируется тетрада:JMPFА1,A2, гдеA1 – номер переменной или константы,A2– номер в таблице меток, иначе ошибка. |
|
{<}A1,A2,R |
Если A1иA2– переменные или константы целого и вещественного типов, то в зависимости от типаintилиfloat, генерируется тетрада:LIA1A2RилиLFA1A2R, иначе ошибка |
|
{<=}A1,A2,R |
Если A1иA2– переменные или константы целого и вещественного типов, то в зависимости от типаintилиfloat, генерируется тетрада:LEIA1A2RилиLEFA1A2R, иначе ошибка. |
|
{==}A1,A2,R |
Если A1иA2– переменные или константы целого и вещественного типов, то в зависимости от типаintилиfloat, генерируется тетрада:EEIA1A2RилиEEFA1A2R, иначе ошибка. |
|
{!=}A1,A2,R |
Если A1иA2– переменные или константы целого и вещественного типов, то в зависимости от типаintилиfloat, генерируется тетрада:NEIA1A2RилиNEFA1A2R, иначе ошибка. |
|
{=}A1,A2 |
Если A1– не переменная, то ошибка. ЕслиA2– не переменная и не константа, то ошибка. Если типыA1иA2совпадают, то в зависимости от типа генерируется тетрада:SETxA1A2R. Если типA1 –float, а типA2–int, то генерируются тетрады:FTYPEA2 -A3;SETA1A3R |
Операционные символы операций отношений вызывают функцию проверки совпадения типов операндов. Если типы не совпадают, и A1–float, аA2–int, то генерируется тетрада преобразования типаintкfloat:FTYPE A - R, гдеA– элемент типаint.
НОВМЕТ - процедура, которая выдает значение указателя на свободную позицию таблицы меток.
НОВЭЛТ - процедура, которая выдает значение указателя на свободную позицию таблицы, используемой для запоминания результата.
Подграмматика объявлений
DES -> DVA
DES -> DMT
DES -> DC
DVA -> TYPp LIq ; {ПЕРЕМЕННЫЕ}p1,q1
p1p
q1q
DVA -> TYPp LAq ; {МАССИВ}p1,q1
p1p
q1q
DMT -> fmt LMT ;
TYPp -> intq
pq
TYPp -> fltq
pq
LIp -> LIq , idr {СПИСОК}r1,q1
p,q1q
r1r
LIp -> idq {СПИСОК}q1,r
q1q
rНОВ_СПИСОК
pr
LAp -> LAr1 , idq IAr2 {СПИСОК_МАСС}q1,r3,r4
q1q
r3r2
p,r4r1
LAp -> idq IAr {СПИСОК_МАСС}q1,r1,r2
q1q
r1r
r2НОВ_СПИСОК_МАСС
pr2
IAp -> [ numq1 ] {СПИСОК}q2,r
q2q1
rНОВ_СПИСОК
pr
IAp -> IAp1 [ numq1 ] {СПИСОК}q2,r
q2q1
r,pp1
LMT -> LMT , idp [ numq1 , numq2 ] {МАТРИЦА}r1,r2,r3
r1p
r2q1
r3q2
LMT -> idp [ numq1 , numq2 ] {МАТРИЦА}r1,r2,r2
r1p
r2q1
r3q2
Операционные символы:
|
{МАТРИЦА}A1,A2,A3 |
Объявление матрицы: размер которой [A2,A3]. Если идентификатор уже объявлен, то ошибка. ИдентификаторуA1задается класс – переменная, и ссылка указывает на таблицу переменных. В поле “атрибуты” таблицы переменных записывается размер матрицы. В поле “тип” записывается 3 –fmatr. В поле “адрес” записывается адрес свободной ячейки памяти.“размер” = A2 * A3 * 4 |
|
{СПИСОК}A1,A2 |
Добавляется элемент A1в списокA2, |
|
{СПИСОК_МАСС}A1,A2,A3 |
В список массивов по адресу A3добавляется элемент {A1,A2}, гдеA1– идентификатор,A2– указатель на список индексов. |
|
{МАССИВ}A1,A2 |
Объявление массивов: В цикле обрабатывается список массивов. Если идентификатор уже объявлен, то ошибка. Если размерность массива больше 10, то ошибка. Идентификатору задается класс – переменная, и ссылка указывает на таблицу переменных. В поле “атрибуты” таблицы переменных записывается указатель на список размеров массива. В поле “тип” записывается тип массива. В поле “адрес” записывается адрес свободной ячейки памяти. В поле “размер” записывается количество байт, требуемых массиву. |
|
{ПЕРЕМЕННЫЕ}A1,A2 |
Объявляются переменные типа A1.A2– список идентификаторов. Если идентификатор уже объявлен, то ошибка. Идентификатору задается класс – переменная, и ссылка указывает на таблицу переменных |
НОВ_СПИСОК – создается список из элементов типа (unsigned char) и возвращается указатель на него.
НОВ_СПИСОК_МАСС – создается список из элементов типа ARR и возвращается указатель на него.
ARR = struct {
List<unsigned char>* ptr; - указатель на список индексов
unsigned char ID – номер идентификатора
}
