Определение синтаксиса языка
Курсовая работа
По дисциплине
Системное программное обеспечение
Разработка компилятора с языка Паскаль
На язык Ассемблера
Выполнил:
ст. гр. ИВТ-102
Парневич И.В.
Принял:
Маскеев С.В.
Владимир, 2004
Введение.
С самого начала развития вычислительной техники человека, пытающегося практически использовать вычислительную машину, раздражала необходимость общаться с ней на ее собственном языке. Для вычислительной машины команды и данные — это хранящиеся в ее памяти наборы двоичных битов. Для человека такое представление информации является трудным для восприятия и понимания. Происходящая непрерывная эволюция в области взаимодействия человека с компьютером привела к появлению сложных и изощренных языковых средств современного математического обеспечения.
Можно указать три главных фактора, обусловливающие и стимулирующие развитие языков программирования. Эти факторы — мнемоника, парадигма (стереотип) и управление данными. Большинство наиболее употребительных общецелевых языков обладает свойствами, отражающими влияние всех этих факторов, но во многих специализированных языках основное внимание было уделено одному из них.
Мнемоника — это возможность подстановки осмысленных для человека символов и фраз в конструкциях машинного языка.
Сущность парадигмы заключается в объединении нескольких внешне не связанных команд в одну группу, для программиста логически более завершенную и содержательно более осмысленную. Подпрограммы, функции и разного рода макро возможности позволяют программисту строить сложные стереотипы. Возможность парадигмы в языках высокого уровня позволяет увеличивать сложность конструируемых систем.
Последний фактор, сильно влияющий на языки программирования,—это структура данных. Основной структурой данных большинства вычислительных машин является линейный массив единиц памяти, состоящих из байтов.
Рассматриваемые единицы памяти характеризуются еще так называемыми абсолютными адресами; это означает, что каждая единица памяти обладает одним приписанным только ей именем. К сожалению, этот тип структуры данных весьма ограничен и ни в коей мере не отражает всего разнообразия типов данных, которым, пользуются программисты. Таким образом, имеется логическая структура данных, т.е. структура, используемая программистом при разработке своего алгоритма, и физическая структура данных, т.е. представление данных непосредственно в памяти машины.
Теперь, когда программист стал обладателем языка высокого уровня, нужно сделать так, чтобы машина смогла прочесть написанную на этом языке программу и понять, какую последовательность машинных команд эта программа обозначает. Как принято говорить, программа должна пройти этап компиляции. Компилятором называется системная программа, выполняющая преобразование программы, написанной на одном алгоритмическом языке, в программу на языке, близком к машинному, и в определенном смысле эквивалентную первой.
1 Задание на проектирование
Разработать транслятор языка высокого уровня Pascal на язык ассемблера. Реализовать следующие конструкции входного языка:
· арифметические операции +, –, *, div, mod;
· скобочные выражения;
· оператор присваивания;
· составной оператор;
· пустой оператор;
Дополнительно были реализованы следующиее конструкции:
· целый тип данных;
· функции, работа с функциями, выход из них, передача данных по указателям;
2 Цели и требования
Необходимо разработать программу, удовлетворяющую заданию. Критичным является размер программы. Дать спецификацию к основным процедурам верхнего уровня, обозначить порядок вызова процедур. Произвести тестирование процедуры нижнего уровня и 2 внешних теста.
3 Внешний проект
Входные и выходные данные
Пользователь запускает программу с одним параметром – имя исполняемого файла на языке Паскаль. Ход компиляции (генерация кода) выводится на экран. Если встречается ошибка, на экран выводится ее номер, текстовое описание, и работа компилятора прерывается. Код программы на языке Ассемблера выводится в файл, носящий то же имя, что и заданное в параметре программы и с расширением “.asm”
Определение синтаксиса языка
Подмножество языка Паскаль, транслируемое программой, описывают нижеследующие диаграммы Вирта:
Идентификатор:
Буква
Буква
Цифра
_
Программа:
Заголовок Описание Описание тело
переменных функций программы
Заголовок:
program идентификатор ;
Описание переменных:
var идентификатор : integer ;
;
Описание функций:
function идентификатор формальные : integer ;
параметры
описание составной
переменных оператор
Формальные параметры:
( var идентификатор : integer )
,
;
Тело программы:
begin оператор end .
Оператор:
оператор
присваивания
составной
оператор
пустой
оператор
функция ;
exit ;
Вызов функции:
идентификатор фактические
параметры
Фактические параметры:
( идентификатор )
константа
,
Оператор присваивания:
идентификатор : = значение ;
Значение:
идентификатор
константа
выражение
функция
Выражение:
( значение математический значение )
оператор
значение математический значение
оператор
Математический оператор:
+
-
*
mod
div
Составной оператор:
begin оператор end ;
Пустой оператор:
;
Общая структура проекта
В общем виде процесс компиляции представлен на схеме:
Структура выходного файла
Определим следующую структуру выходного файла на языке ассемблера:
; ---- primitive asm code generator (.pas to .asm)
;include procedure call and expression enterpriter
.386
.model flat, stdcall
option casemap :none
include masm32.inc
includelib lib1.lib
includelib masm32.lib
ExitProcess PROTO :DWORD
outdec PROTO :DWORD
__codeblock000 PROTO
…
__codeblockXXX PROTO
.data
out_ db 200 dup (0)
real_ db 200 dup (0)
nl_ db 0Dh, 0Ah, 00h
nul_ db 30h, 00h
mm_ db '-', 00h
.code
outdec proc NUM:DWORD
pusha
push es
push ds
pop es
lea edi, out_
mov eax, NUM
cmp eax, 0
jl _otr
jne _ok
invoke StdOut, offset nul_
ret
_otr:
invoke StdOut, offset mm_
ret
_ok:
xor ebx, ebx
mov bl, 10
xor ecx, ecx
;===
cld
ll:
cmp eax, 0
jle ex
xor edx, edx
div ebx
xchg eax, edx
add al, 30h
stosb
mov al, 00h
stosb
xchg eax, edx
jmp ll
ex:
invoke StdOut, edi
sub edi, 2
cmp edi, offset out_
jge ex
;===
pop es
popa
ret
outdec endp
EntryPoint:
mov ebp, esp
sub esp, 20 ; vars to block 0
call __codeblock000
invoke ExitProcess,0
__codeblock000 proc
…
ret
__codeblock000 endp
END EntryPoint
Организация листинга
Листинг не организуется в ходе трансляции и не выводится в выходной файл в виде комментариев. Листинг заменен выводом технической информации о ходе компилирования на экран.
4 Проект архитектуры
Структуры данных
typedef enum {
typenspace,
typevar,
typeconst,
typefunc
} IdentTypes;
typedef struct __typeGIT
{ char * name;
IdentTypes type;
unsigned int ext;
unsigned long value;
unsigned int level;
} typeGIT, * lpGIT;
typedef struct __typeBlock
{ int slPos, swPos; // Начало блока
int elPos, ewPos; // Конец блока
int GITidx; //индекс старта переменных блока в IDT
int GITend; //индекс конца переменных блока в IDT
lpdgram * code;
} typeBlock, *lpBlock;
typedef enum
{ opset,
opcall,
opadd,
opsub,
opdiv,
opmul,
opmod,
opvar,
opconst,
op_count, //endline & count of ops
op_error,
opignore,
opret,
opneg
} operations;
typedef struct __dgram
{ operations type;
int ext;
struct __dgram * left, * right;
} typedgram, *lpdgram;
char *** GCode;
int lPos;
int wPos;
typeGIT * GIT;
int GIT_size;
typeBlock * Block;
int Block_size;
int Block_cur;
BOOL _stop;