Определение синтаксиса языка

Курсовая работа

По дисциплине

Системное программное обеспечение

Разработка компилятора с языка Паскаль

На язык Ассемблера

Выполнил:

ст. гр. ИВТ-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;