Разработка компилятора

Автор работы: Пользователь скрыл имя, 12 Декабря 2012 в 01:25, курсовая работа

Краткое описание

Наименование программного продукта – «Компилятор».
Область применения программного продукта – разработка программного обеспечения, трансляция с языка высокого уровня на язык ассемблера.
Разработка предназначена для компиляции программы из исходного кода в код на языке ассемблера.

Содержание работы

1 ТЕХНИЧЕСКОЕ ЗАДАНИЕ. 4
2 ОПИСАНИЕ ПРОГРАММЫ. 7
3 ТЕКСТ ПРОГРАММЫ. 17
4 КОНТРОЛЬНЫЙ ПРИМЕР ИСПОЛЬЗОВАНИЯ 47
ЗАКЛЮЧЕНИЕ 64

Содержимое работы - 1 файл

Курсовая СПО.docx

— 223.50 Кб (Скачать файл)

    // процедуры описания заголовка программы и символа конца программы

   

    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() выполняются следующие действия:

- проверяется  наличие ключевого слова ‘program’ и имени программы,

- вызывается  процедура разбора блока переменных declar();

- вызывается  процедура разбора блока кода  block();

- проверяется  наличие ключевого слова ‘end’ и разделителя ‘.’.

Процедура разбора блока переменных declar() выполняет следующие действия:

- проверяет  наличие ключевого слова ‘var’;

- выполняет разбор и заполнение таблицы переменных.

Процедура разбора блока кода block() выполняет следующие функции:

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

- если текущим  символом является имя переменной, то вызывается процедура разбора оператора присваивания op_pr(), в противном же случае выполняется оператор множественного выбора:

- если текущим  символом является ключевое слово  ‘if’, то вызывается процедура разбора условного оператора op_if();

- если текущим  символом является ключевое слово  ‘do’, то вызывается процедура разбора оператора цикла op_do ();

- если текущим  символом является ключевое слово  ‘while’, то вызывается процедура разбора цикла с предусловием op_while();

- если текущим  символом является ключевое слово  ‘write’, то вызывается процедура вывода op_write().

- если текущим  символом является ключевое слово  ‘read’, то вызывается процедура ввода op_read().

 

Следует также отметить, что в классе синтаксического  анализа предусмотрена процедура  Error, предназначенная для добавления в выходной поток сообщений об ошибках и представляет собой оператор множественного выбора, где в соответствии с переданным кодом ошибки в выходной поток добавляется сообщение с номером строки и родом ошибки.

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

Параллельно с синтаксическим анализом производится генерация кода программы на языке  ассемблера. Данный метод называется синтаксически управляемой трансляцией.

Генерация   кода  -   последняя  фаза  трансляции. Результатом  ее   является  ассемблерный  файл (*.asm). В процессе генерации кода могут выполняться некоторые локальные оптимизации, такие как распределение регистров, выбор длинных или коротких переходов, учет стоимости команд при выборе конкретной последовательности команд.

Задача генератора  кода -  построение  эквивалентной  программы на ассемблере по  программе  на  входном языке.  Обычно в  качестве входного для  генератора кода  служит некоторое  промежуточное  представление  программы.

Генерация осуществляется на этапе рекурсивного спуска, когда  разобранному правилу ставится в  соответствие определенная команда        или набор команд ассемблера.

 

 

3 ТЕКСТ ПРОГРАММЫ.

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_analiz:integer;

    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:=Length(x2);dl:=dl+1; end else

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:=t;analiz[nom_analiz].nomer:=n;nom_analiz:=nom_analiz+1;S:=0;delete(x2,1,dlina);i:=i-1; end;

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:=t;analiz[nom_analiz].nomer:=n;nom_analiz:=nom_analiz+1;i:=i-1;delete(x2,1,dl);S:=0;dl:=1;end;

23:begin If x1[i]='''' then begin x2:=x2+x1[i];dl:=dl+1;S:=21;end else begin S:=22;i:=i-1;end;  end;

 

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);S:=0;dl:=0;met:=0;end else S:=0;end;

33:begin If x1[i]='*' then begin S:=34; met:=Length(x2);dl:=dl+2;x2:=x2+x1[i]; end else begin x2:=x2+x1[i]; S:=0; end; if x1[i]='/' then begin S:=36;met:=length(x2)-1;end; If (eof(f1)=true) and (dlina=i) then begin S:=32;i:=i-1;end;end;

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;end;If (eof(f1)=true) and (dlina=i) then begin S:=32;i:=i-1;end;end;

36:begin If dlina=i then begin S:=32;i:=i-1;delete(x2,met,2)end; end;

 

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:=x2+x1[i]; cmp_tab_razdel(x2);end;  If i=dlina then begin S:=42;end; end;

42:begin writeln(f4,' ',t,' ',n);analiz[nom_analiz].table:=t;analiz[nom_analiz].nomer:=n;nom_analiz:=nom_analiz+1;S:=0;delete(x2,1,dlina);i:=i-1;end;

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_false:');

  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('Неверное логическое  выражение','  строка-',cur_stroka);

      12:writeln('Ожидалось  "]"','  строка-',cur_stroka);

      13:writeln('Ожидалось  ")"','  строка-',cur_stroka);

      14:writeln('неверный знак  сравнения','  строка-',cur_stroka);

      15:writeln('Ожидалось  "!"','  строка-',cur_stroka);

      16:writeln('Неверное арифметическое  выражение','  строка-',cur_stroka);

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

Информация о работе Разработка компилятора