Автор работы: Пользователь скрыл имя, 12 Декабря 2012 в 01:25, курсовая работа
Наименование программного продукта – «Компилятор».
Область применения программного продукта – разработка программного обеспечения, трансляция с языка высокого уровня на язык ассемблера.
Разработка предназначена для компиляции программы из исходного кода в код на языке ассемблера.
1 ТЕХНИЧЕСКОЕ ЗАДАНИЕ. 4
2 ОПИСАНИЕ ПРОГРАММЫ. 7
3 ТЕКСТ ПРОГРАММЫ. 17
4 КОНТРОЛЬНЫЙ ПРИМЕР ИСПОЛЬЗОВАНИЯ 47
ЗАКЛЮЧЕНИЕ 64
// процедуры описания заголовка программы и символа конца программы
procedure error(kod:integer);
//процедура вывода ошибок
procedure declar();
//процедура описания блока декларации
procedure block();
// процедуры описания раздела блока операторов
procedure E();
procedure T();
procedure F();
// арифметические выражения
procedure L();
procedure TL();
procedure FL();
// логические выражения
procedure block();
// процедура описания блока операторов
procedure operator();
// процедура выбора оператора
procedure op_if();
// оператор условия
procedure op_while();
// оператор цикла while
procedure op_read();
// оператор ввода
procedure op_write();
// оператор вывода
procedure op_do();
// оператор цикла do
Procedure op_pr();
// оператор присваивания
Синтаксический разбор начинается с вызова процедуры procedure sintax(). Из данной процедуры вызывается процедура разбора целевого символа грамматики pr.
В процедуре pr() выполняются следующие действия:
- проверяется
наличие ключевого слова ‘
- вызывается
процедура разбора блока
- вызывается процедура разбора блока кода block();
- проверяется наличие ключевого слова ‘end’ и разделителя ‘.’.
Процедура разбора блока переменных declar() выполняет следующие действия:
- проверяет наличие ключевого слова ‘var’;
- выполняет разбор и заполнение таблицы переменных.
Процедура разбора блока кода block() выполняет следующие функции:
- выполняется цикл с предусловием, в котором идентификация оператора и передается управление его процедуре разбора operator:
- если текущим
символом является имя
- если текущим
символом является ключевое
- если текущим
символом является ключевое
- если текущим
символом является ключевое
- если текущим
символом является ключевое
- если текущим
символом является ключевое
Следует
также отметить, что в классе синтаксического
анализа предусмотрена
2.4 Генерация кода.
Параллельно
с синтаксическим анализом производится
генерация кода программы на языке
ассемблера. Данный метод называется
синтаксически управляемой
Генерация кода - последняя фаза трансляции. Результатом ее является ассемблерный файл (*.asm). В процессе генерации кода могут выполняться некоторые локальные оптимизации, такие как распределение регистров, выбор длинных или коротких переходов, учет стоимости команд при выборе конкретной последовательности команд.
Задача генератора кода - построение эквивалентной программы на ассемблере по программе на входном языке. Обычно в качестве входного для генератора кода служит некоторое промежуточное представление программы.
Генерация осуществляется на этапе рекурсивного спуска, когда разобранному правилу ставится в соответствие определенная команда или набор команд ассемблера.
Program kompil;
type
lek=record
table:string;
nomer:integer;
type_i:string;
znachenie:string;
mas:integer;
end;
var
f1,f2,f3,f4,f5,f6,f7:text;
analiz:array [1..1000] of lek;
x1,x2:string;
S,i,dlina,n,dl,met,k,nom_
alfavit: set of char;
cifri: set of char;
razdel: set of char;
zn_ot:set of char;
tab_I:array [1..1000] of string;
bol_tab_i,firstrun:boolean;
t:string;
tab_ident:array [1..1000] of string;
count_ident:integer;
tab_cifri:array [1..1000] of string;
count_cifri:integer;
tab_liter:array [1..1000] of string;
count_liter:integer;
tab_hardrazdel:array[1..1000] of string;
tab_razdel:array[1..1000] of string;
count_razdel:integer;
er:real;
ch1_mas,ch2_mas:integer;
cur_met:integer;
g_met:string;
procedure leksich;
Procedure CMP_tab_liter(var str:string);
var id:boolean;i:integer;
begin
id:=false;
for i:=1 to count_liter do
begin
If tab_liter[i]=x2 then
begin
t:='l';
n:=i;
id:=true;
end;
end;
If id=false then
begin
tab_liter[count_liter]:=x2;
t:='l';
n:=count_liter;
end;
count_liter:=count_liter+1;
end;
Procedure CMP_tab_razdel(var str:string);
var id:boolean;i:integer;
begin
id:=false;
for i:=1 to count_razdel do
begin
If tab_razdel[i]=x2 then
begin
t:='s';
n:=i;
id:=true;
end;
end;
If id=false then
begin
tab_razdel[count_razdel]:=x2;
t:='s';
n:=count_razdel;
count_razdel:=count_razdel+1;
end;
end;
Procedure CMP_tab_cifri(var str:string);
var id:boolean;i:integer;
begin
id:=false;
for i:=1 to count_cifri do
begin
If tab_cifri[i]=x2 then
begin
t:='c';
n:=i;
id:=true;
end;
end;
If id=false then
begin
tab_cifri[count_cifri]:=x2;
t:='c';
n:=count_cifri;
count_cifri:=count_cifri+1;
end;
end;
Procedure CMP_tab_I(var str:string);
begin
t:='';
n:=0;
k:=1;
While tab_i[k]<>'' do
begin
If tab_i[k]=x2 then begin t:='k';n:=k; end;
K:=k+1;
end;
end;
Procedure CMP_tab_hardrazdel(var str:string);
begin
t:='';
n:=0;
k:=1;
While tab_hardrazdel[k]<>'' do
begin
If tab_hardrazdel[k]=str then begin t:='h';n:=k; end;
K:=k+1;
end;
end;
Procedure CMP_tad_ident(var str:string);
var id:boolean;i:integer;
begin
id:=false;
for i:=1 to count_ident do
begin
If tab_ident[i]=x2 then
begin
t:='i';
n:=i;
id:=true;
end;
end;
If id=false then
begin
tab_ident[count_ident]:=x2;
t:='i';
n:=count_ident;
count_ident:=count_ident+1;
end;
end;
begin
Repeat
readln(f2,x1);
tab_I[k]:=x1;
k:=k+1;
until eof(f2);
K:=1;
Repeat
readln(f3,x1);
tab_hardrazdel[k]:=x1;
k:=k+1;
until eof(f3);
s:=0;
nom_analiz:=1;
Repeat
readln(f1,x1);
dlina:=Length(x1);
For i:=1 to dlina+2 do
begin
case s of
0: Begin If (x1[i] in alfavit) then Begin S:=11; x2:=x2+x1[i] end else begin If (x1[i] in cifri) then Begin S:=13; x2:=x2+x1[i] end else S:=0;end;
If x1[i]='''' then begin S:=21;dl:=1;end else if (x1[i] in razdel ) and (x1[i+1]<>'/') and (x1[i+1]<>'*') then begin S:=41; x2:=x2+x1[i];i:=i-1; end;
If x1[i]='{' then begin S:=31;x2:=x2+x1[i];met:=
begin
if x1[i]='/' then begin S:=33;x2:=x2+x1[i] end;// else x2:=x2+x1[i];
If dlina=i then begin S:=32;i:=i-1; end;
end;
end;
11: Begin If (x1[i] in alfavit) or (x1[i] in cifri) then x2:=x2+x1[i] else begin S:=12;i:=i-1; end; If i=dlina then begin S:=12;end; end;
12: Begin CMP_tab_I(x2); If (n=0) and (x2[1] in alfavit) then CMP_tad_ident(x2)
else if x2[1] in cifri then cmp_tab_cifri(x2);writeln(f4,' ',t,' ',n);analiz[nom_analiz].table:
13: Begin If (x1[i] in cifri) then x2:=x2+x1[i] else begin S:=12;i:=i-1; end;; If i=dlina then begin i:=i-1;S:=12;end;end;
21:begin If x1[i]='''' then begin S:=23; end else begin x2:=x2+x1[i];dl:=dl+1;end; end;
22:begin cmp_tab_liter(x2); writeln(f4,' ',t,' ',n);analiz[nom_analiz].table:
23:begin If x1[i]='''' then begin x2:=x2+x1[i];dl:=dl+1;S:=21;
31:begin If x1[i]='}' then begin S:=32;delete(x2,met,dl)end else begin x2:=x2+x1[i];dl:=dl+1; end; If (eof(f1)=true) and (dlina=i) then begin S:=32;i:=i-1;end; end;
32:begin If dlina<>i then i:=i-1;if x2<>'' then begin
writeln(f4);delete(x2,1,dlina)
33:begin If x1[i]='*' then begin S:=34; met:=Length(x2);dl:=dl+2;x2:=
34:begin If x1[i]='*' then begin S:=35; x2:=x2+x1[i];dl:=dl+1; end else begin x2:=x2+x1[i];dl:=dl+1;end;If (eof(f1)=true) and (dlina=i) then begin S:=32;i:=i-1;end;end;
35:begin If x1[i]='/' then begin S:=32;delete(x2,met,dl) end else
begin x2:=x2+x1[i];S:=34;dl:=dl+1;
36:begin If dlina=i then begin S:=32;i:=i-1;delete(x2,met,2)
41:begin n:=0;t:=''; If (x1[i+1] in razdel) then begin x2:=x2+x1[i+1];
cmp_tab_hardrazdel(x2);end; If n<>0 then begin S:=42;i:=i+1;
end else begin S:=42;delete(x2,1,dlina);x2:=
42:begin writeln(f4,' ',t,' ',n);analiz[nom_analiz].table:
end;
end;
Until eof(f1);
end;
procedure sintax;
var current_analiz:integer;
type_virag: array[1..10] of string;
cur_vir:integer;
cur_stroka:integer;
procedure block;forward;
procedure declar;forward;
procedure mass;forward;
procedure AddProcedures;
begin
writeln(F6,'R_B proc near');
writeln(F6,'CMP BUFS,''t''');
writeln(F6,'JNZ FN');
writeln(F6,'PUSH 1 ; TRUE');
writeln(F6,'JMP PBEnd');
writeln(F6,'FN: CMP BUFS, ''f''');
writeln(F6,'JNZ EndKode1');
writeln(F6,'EndKode1:');
writeln(F6,'JMP EndKode');
writeln(F6,'PUSH 0');
writeln(F6,'PBEnd:');
writeln(F6,'RET');
writeln(F6,'ENDP');
writeln(F6,'');
writeln(F6,'R_Ch proc near');
writeln(F6,'mov bx,0');
writeln(F6,'M:');
writeln(F6,'mov ah,08h');
writeln(F6,'int 21h');
writeln(F6,'mov dl,al');
writeln(F6,'mov ah,02h');
writeln(F6,'int 21h');
writeln(F6,'cmp al,'' ''');
writeln(F6,'jz M');
writeln(F6,'cmp al,13');
writeln(F6,'jz M');
writeln(F6,'mov BUFS[bx],al');
writeln(F6,'M1:');
writeln(F6,'mov ah,08h');
writeln(F6,'int 21h');
writeln(F6,'mov dl,al');
writeln(F6,'mov ah,02h');
writeln(F6,'int 21h');
writeln(F6,'cmp al,'' ''');
writeln(F6,'jz M2');
writeln(F6,'cmp al,13');
writeln(F6,'jz M2');
writeln(F6,'inc bx');
writeln(F6,'mov BUFS[bx],al');
writeln(F6,'jmp M1');
writeln(F6,'M2:');
writeln(F6,'mov cx,bx');
writeln(F6,'mov al,13');
writeln(F6,'mov ah,02h');
writeln(F6,'int 21h');
writeln(F6,'ret');
writeln(F6,'ENDP');
writeln(F6,'');
writeln(F6,'PR_Int proc near');
writeln(F6,'push bx');
writeln(F6,'push cx');
writeln(F6,'push dx');
writeln(F6,'test ax,ax');
writeln(F6,'push -1');
writeln(F6,'mov cx,10');
writeln(F6,'wrem:');
writeln(F6,'xor dx,dx');
writeln(F6,'div cx');
writeln(F6,'push dx');
writeln(F6,'test ax,ax');
writeln(F6,'jnz wrem');
writeln(F6,'mov ah,02h');
writeln(F6,'orem:');
writeln(F6,'pop dx');
writeln(F6,'test dx,dx');
writeln(F6,'js output_int_exit');
writeln(F6,'add dl,''0''');
writeln(F6,'int 21h');
writeln(F6,'jmp orem');
writeln(F6,'output_int_exit:')
writeln(F6,'pop dx');
writeln(F6,'pop cx');
writeln(F6,'pop bx');
writeln(F6,'ret');
writeln(F6,'ENDP');
writeln(F6,'');
writeln(F6,'R_Int proc near');
writeln(F6,'push bx');
writeln(F6,'push cx');
writeln(F6,'push dx');
writeln(F6,'mov bx,0');
writeln(F6,'mov ax,0');
writeln(F6,'inc cx');
writeln(F6,'mov bufs3,cx');
writeln(F6,'m_start:');
writeln(F6,'mov cx,10');
writeln(F6,'mul cx');
writeln(F6,'mov dx,0');
writeln(F6,'push ax');
writeln(F6,'mov dl,BUFS[bx]');
writeln(F6,'mov cx,dx');
writeln(F6,'sub dx,30h');
writeln(F6,'pop ax');
writeln(F6,'add ax,dx');
writeln(F6,'inc bx');
writeln(F6,'mov cx,bufs3');
writeln(F6,'cmp cx,bx');
writeln(F6,'jnz m_start');
writeln(F6,'m_exit:');
writeln(F6,'pop bx');
writeln(F6,'pop cx');
writeln(F6,'pop dx');
writeln(F6,'ret');
writeln(F6,'ENDP');
writeln(F6,'');
writeln(F6,'outline proc');
writeln(F6,'push dx');
writeln(F6,'mov ah,02h');
writeln(F6,'mov dl,0dh');
writeln(F6,'int 21h');
writeln(F6,'mov dl,0Ah');
writeln(F6,'int 21h');
writeln(F6,'pop dx');
writeln(F6,'ret');
writeln(F6,'outline endp');
writeln(F6,'');
writeln(F6,'output_logic proc');
writeln(F6,'push dx');
writeln(F6,'test ax,ax');
writeln(F6,'jz output_logic_false');
writeln(F6,'mov dx, offset $logic_true');
writeln(F6,'jmp output_logic_end');
writeln(F6,'output_logic_
writeln(F6,'mov dx, offset $logic_false');
writeln(F6,'output_logic_end:'
writeln(F6,'mov ah,9h');
writeln(F6,'int 21h');
writeln(F6,'pop dx');
writeln(F6,'ret');
writeln(F6,'output_logic endp');
writeln(F6,'');
end;
procedure error(kod:integer);
begin
//cur_stroka:=cur_stroka+1;
case kod of
1:Writeln('Ожидалось слово Program',' строка-',cur_stroka);
2:writeln('Ожидался идентификатор',' строка-',cur_stroka);
3:writeln('ожидалась ";"',' строка-',cur_stroka);
4:writeln('Ожидалось end',' строка-',cur_stroka);
5:writeln('Ожидалось "."',' строка-',cur_stroka);
6:writeln('Ожидалось var',' строка-',cur_stroka);
7:writeln('Ожидалось ","',' строка-',cur_stroka);
8:writeln('Ожидалось ":"',' строка-',cur_stroka);
9:writeln('Ожидалось begin',' строка-',cur_stroka);
10:writeln('Не известный тип данных',' строка-',cur_stroka);
11:writeln('Неверное
12:writeln('Ожидалось "]"',' строка-',cur_stroka);
13:writeln('Ожидалось ")"',' строка-',cur_stroka);
14:writeln('неверный знак сравнения',' строка-',cur_stroka);
15:writeln('Ожидалось "!"',' строка-',cur_stroka);
16:writeln('Неверное
17:writeln('Переменная не оъявлена',' строка-',cur_stroka);
18:writeln('Ожидалось :=',' строка-',cur_stroka);
19:writeln('Ожидалось then',' строка-',cur_stroka);
20:writeln('Ожидалось do',' строка-',cur_stroka);
21:writeln('Ожидалось "("',' строка-',cur_stroka);
22:writeln('Ожидалось "["',' строка-',cur_stroka);
23:writeln('Ожидалось число',' строка-',cur_stroka);
24:writeln('Ожидалось ".."',' строка-',cur_stroka);
25:writeln('Ожидалось of',' строка-',cur_stroka);