Схема вызовов процедур и функций

синтаксического анализатора

compiller-2—main -- Syntax_Analiz_1

|

NextLexema

|

p_prog—isWord—InsertGIT

|

p_var—NextLex—isWord—isOperator—GetTypeByWord—InsertGIT

|

p_func—isWord—Syntax_Analiz_1

|

p_beg—isOperator--insertBlock

|

p_end—error

4.4 Организация процедуры компиляции

 

Процедура компиляции состоит из следующих этапов:

1. Подготовка к компиляции

2. Проверка лексики входного файла

3. Проверка синтаксиса входного файла

4. Проверка блочной структуры входного файла

5. Генерация кода

6. Вывод кода ошибки при ее обнаружении

 

4.5 Спецификация основных процедур и функций

lpdgram *p_block(int b)

{Входные параметры: номер разбираемого блока

Выходные параметры: массив из бинарных деревьев (диаграмм Вирта)

Выполняемая функция: преобразование таблицы лексем к таблице идентификаторов и массивам диаграмм Вирта

}

lpdgram p_codeline(int b)

{Входные параметры: номер разбиваемого блока

Выходные параметры: бинарное дерево (диаграмма Вирта)

Выполняемая функция: преобразование одной строки на языке Pascal из таблицы лексем в диаграмму Вирта

}

int getnumArg(int f)

{Входные параметры: индекс функции в таблице идентификаторов

Выходные параметры: количество аргументов функции

Выполняемая функция: получение количества аргументов для функции, заданной индексом в таблице идентификаторов

}

operations operationType(char * op, int block)

{Входные параметры: символьное представление операции (лексема) и блок, в котором она находится

Выходные параметры: тип операции

Выполняемая функция: определение типа диаграммы Вирта

}

lpdgram initDgram(operations type, int ext, lpdgram left, lpdgram right)

{Входные параметры: тип операции, индекс в таблице идентификаторов (для переменных и функций) или значение константы (для константы), левая и правая связи

Выходные параметры: корень дерева кода

Выполняемая функция: инициализация элемента или корня дерева кода

}

void dropDgram(lpdgram Dgram)

{Входные параметры: корень или элемент дерева

Выходные параметры: нет

Выполняемая функция: освобождение памяти из-под диаграммы Вирта

}

void atLexima(int sl, int sw)

{Входные параметры: индексы в таблице лексем

Выходные параметры: нет

Выполняемая функция: переход к указанному слову в таблице лексем

}

void rewindLexima(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: переход на одну лексему назад

}

char * nextLexima(void)

{Входные параметры: нет

Выходные параметры: лексема

Выполняемая функция: получение новой лексемы из таблицы лексем

}

 

int Delimeter(char * line)

{Входные параметры: символьная строка

Выходные параметры: код разделителя

Выполняемая функция: определение типа и кода разделителя

}

 

int isOperator(char * line)

{Входные параметры: символьная строка

Выходные параметры: код оператора

Выполняемая функция: определение, является ли line оператором, если является, то определяется его код, если нет – возвращается -1

}

int isKeyWord(char * line)

{Входные параметры: символьная строка

Выходные параметры: код ключевого слова

Выполняемая функция: определяет, является ли line ключевым словом, возвращает его код, если является

}

BOOL Syntax_Analiz_1(void)

{Входные параметры:нет

Выходные параметры: true – анализ успешен, false – обнаружена ошибка

Выполняемая функция: преобразование программы к блокам кода, извлечение идентификаторов в таблицу идентификаторов и подготовка к разбиению блоков на строки диаграмм Вирта

}

void p_program(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: обработка ключевого слова program и помещение его в таблицу GIT (Global Ident Table)

}

void p_var(int _ext)

{Входные параметры: тип хранения переменной: переменная локальная для функции, глобальная для программы или параметр для вызова функции

Выходные параметры: нет

Выполняемая функция: обработка ключевого слова var и помещение его в таблицу GIT (Global Ident Table)

}

void p_function(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: обработка ключевого слова function и помещение его в таблицу GIT (Global Ident Table)

}

void p_begin(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: обработка ключевого слова begin, создание метки блока, добавление нового блока к таблице блоков, создание связи блока с таблицей идентификаторов

}

void p_end(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: обработка ошибки отсутствия соответствующего ключевого слова begin

}

BOOL p_other_sym(char * lex)

{Входные параметры: lex – лексема

Выходные параметры: true – продолжать анализ, false – анализ прекратить

Выполняемая функция: анализ дополнительных лексем (например ;)

}

BOOL insertGIT(char * lex, IdentTypes type, unsigned int ext, unsigned long val)

{Входные параметры: лексема, тип идентификатора, тип хранения переменной: переменная локальная для функции, глобальная для программы или параметр для вызова функции, значение

Выходные параметры: успешно добавлен элемент или нет

Выполняемая функция: добавляет элемент в таблицу идентификаторов

}

int searchGIT(char * name)

{Входные параметры: имя лексемы

Выходные параметры: номер строки в таблице идентификаторов, -1 в случае не обнаружения идентификатора

Выполняемая функция: осуществляет поиск идентификаторов в таблице и возвращает номер строки в случае, если она найдена.

}

int searchGITfrom(char * name, int _from)

{Входные параметры: имя лексемы; номер блока, с которого осуществляется поиск

Выходные параметры: номер строки в таблице идентификаторов, -1 в случае не обнаружения идентификатора в таблице

Выполняемая функция: осуществляет поиск идентификатора в таблице для определенного блока, с учетом его “видимости”

}

int searchGITblock(char * name, int block)

{ Входные параметры: имя лексемы; номер блока, с которого осуществляется поиск

Выходные параметры: номер строки в таблице идентификаторов, -1 в случае не обнаружения идентификатора в таблице

Выполняемая функция: осуществляет поиск идентификатора в таблице для определенного блока, внутри его

}

int searchGITto(char * name, int block)

{Входные параметры: имя лексемы; номер блока, с которого осуществляется поиск

Выходные параметры: номер строки в таблице идентификаторов, -1 в случае не обнаружения идентификатора в таблице

Выполняемая функция: осуществляет поиск идентификатора в таблице для определенного блока, внутри его, в глобальном пространстве и передаваемых функции параметров

}

int insertBlock(int varIdx)

{Входные параметры: индекс начала блока в таблице идентификаторов

Выходные параметры: индекс добавленного блока

Выполняемая функция: добавление блока к таблице блоков

}

void addBlockStart(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: изменение метки начала блока в таблице блоков

}

void addBlockEnd(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: изменение метки конца блока в таблице блоков

}

void freeGIT(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: освобождение памяти от таблицы идентификаторов

}

void freeBlock(void)

{Входные параметры: нет

Выходные параметры: нет

Выполняемая функция: освобождение памяти от блоков кода

}

BOOL isWord(char * tmp)

{Входные параметры: слово

Выходные параметры: true в случае, если слово, false – если нет.

Выполняемая функция: определение, принадлежит ли tmp к словам или нет

}

int GetIdentTypeByWord(char * type)

{Входные параметры: символьная строка

Выходные параметры: -1 – ошибка, иначе код для типа

Выполняемая функция: получение типа идентификатора по его символьному названию (integer)

}

 

4.6 Обработка ошибок

Разработанный синтаксический анализатор обнаруживает следующие виды ошибок:

Ошибка Причина
  Error in program structure detected, may be an `;' expected  
Unexpected end-of-file detected  
  Error detected during compilation... Stopped...  
  Error unexpected end-of-file at line  
  program name must be a word  
  Wrong type definition, may be expected `:'  
  Invalid identificator name  
  expected type declaration  
  Function must have some name  
  Here must be variable or const definition  
  `;' Expected  
  `:' Expected  
  Function type specific-word must be a WORD!  
  Unknown type definition  
  Begin expected  
  Syntax error: Dublicate identificator  
  unknow identificator  
  Boolean operation dont supported  

Реализация

Тестирование

5.1.1 Внешние тесты

Входной файл на языке Паскаль test.pas:

program test;

var x:integer;

cy,h,c:integer;

function f(x:integer; var i,j:integer):integer;

var

d:integer;

begin

f:=x+i*j;

end;

var a:integer;

begin

cy:= 6;

c:= 9;

x:=c/cy + f(4,c ,cy);

end.

 

Выходной файл на языке Ассемблера test.asm:

; ---- 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

__codeblock001 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

 

mov eax, 6

mov DWORD PTR [ebp-4], eax

mov eax, 9

mov DWORD PTR [ebp-12], eax

sub esp, 16 ; vars to block 1

mov eax, 4

push eax

mov eax, 12

push eax

mov eax, 4

push eax

call __codeblock001

add esp, 28

push eax

mov eax, DWORD PTR [ebp-4]

mov ebx, DWORD PTR [ebp-12]

xchg eax, ebx

xor edx, edx

idiv ebx

pop ebx

add eax, ebx

mov DWORD PTR [ebp-0], eax

 

ret

__codeblock000 endp

__codeblock001 proc

 

mov eax, DWORD PTR [ebp-0]

mov ebx, DWORD PTR [ebp-16]

xor edx, edx

imul ebx

 

add eax, DWORD PTR [ebp-16]

 

ret

__codeblock001 endp

 

 

END EntryPoint

 

Входной файл на языке Паскаль test1.pas

program test1;

var i,j:integer;

x:integer;

function sum(i,j:integer):integer;

var

s:integer;

begin

s:=i+j;

sum:=s;

end;

begin

x:=sum (5,6);

end.

 

Выходной файл на языке Ассемблера test1.asm

; ---- 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

__codeblock001 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, 12 ; vars to block 0

call __codeblock000

 

invoke ExitProcess,0

 

 

__codeblock000 proc

 

sub esp, 12 ; vars to block 1

mov eax, 6

push eax

mov eax, 5

push eax

call __codeblock001

add esp, 20

mov DWORD PTR [ebp-8], eax

 

ret

__codeblock000 endp

__codeblock001 proc

 

mov eax, DWORD PTR [ebp-0]

add eax, DWORD PTR [ebp-16]

mov DWORD PTR [ebp-8], eax

mov eax, DWORD PTR [ebp-0]

 

ret

__codeblock001 endp

 

 

END EntryPoint

 

2 невъебенных теста…