Смекни!
smekni.com

Разработка программы-компилятора (стр. 8 из 9)

Const_tab [Numconst]. Width: ='2 байта';

WriteCode (NumLex,Lexem,'C',NumConst);

end else // если лексема найдена

begin

WriteCode (NumLex,Lexem,'C',Constyes);

end;

end;

'M': begin // если лексема-римская константа

NumLex: =NumLex+1;

Search_Const (1,Lexem);

if Constyes=0 then // если лексема не найдена

begin

NumConst: =NumConst+1;

Add_Const (1,Lexem);

Const_tab [NumConst]. Typ: ='римск. ';

Const_tab [Numconst]. Width: ='2 байта';

WriteCode (NumLex,Lexem,'C',NumConst);

end else // если лексема найдена

begin

WriteCode (NumLex,Lexem,'C',Constyes);

end;

end;

'I': begin // если лексема-идентификатор

NumLex: =NumLex+1;

y: =Search_Ident ({1,}Lexem);

if y=0 then // если лексема не найдена

begin

NumId: =NumId+1;

WriteCode (NumLex,Lexem,'I',NumId);

Add_Ident (Lexem);

end else WriteCode (NumLex,Lexem,'I',y); // если лексема найдена

end;

'K': begin // если лексема-служебное слово

NumLex: =NumLex+1;

Search_Term (1,Lexem);

if Termyes=0 then // если лексема не найдена

begin

NumTerm: =NumTerm+1;

Add_Term (1,Lexem);

Term_tab [Numterm]. razd: =0;

Term_tab [Numterm]. oper: =0;

Term_tab [Numterm]. slug: =1;

WriteCode (NumLex,Lexem,'T',NumTerm);

end else WriteCode (NumLex,Lexem,'T',Termyes); // если лексема найдена

end;

'R': begin // если лексема-разделитель

NumLex: =NumLex+1;

Search_Term (1,Lexem);

if Termyes=0 then // если лексема не найдена

begin

NumTerm: =NumTerm+1;

Add_Term (1,Lexem);

Term_tab [NumTerm]. razd: =1;

Term_tab [NumTerm]. oper: =0;

Term_tab [NumTerm]. slug: =0;

WriteCode (NumLex,Lexem,'T',NumTerm)

end else WriteCode (NumLex,Lexem,'T',Termyes) // если лексема найдена

end;

'O': begin // если лексема-знак операция

NumLex: =NumLex+1;

Search_Term (1,Lexem);

if Termyes=0 then // если лексема не найдена

begin

NumTerm: =NumTerm+1;

Add_Term (1,Lexem);

Term_tab [Numterm]. razd: =0;

Term_tab [Numterm]. oper: =1;

Term_tab [Numterm]. slug: =0;

WriteCode (NumLex,Lexem,'T',NumTerm)

end else WriteCode (NumLex,Lexem,'T',Termyes) // есди лексема найдена

end;

end;

end;

procedure TForm1. N5Click (Sender: TObject);

var i,pip: integer;

begin

for k: =1 to numid do // обнуление таблицы идентификаторов

begin

id_tab [k]. lex: ='0';

id_tab [k]. nomer: =0;

id_tab [i]. ssylka: =0;

end;

for i: =1 to numlex do // обнуление выходной таблицы

begin

Code_Tab [i]. Lex: ='';

Code_Tab [i]. typ: =#0;

Code_Tab [i]. Num: =0;

Code_Tab [i]. nomer: =0;

end;

for i: =0 to numconst do // обнуление таблицы констант

begin

Const_tab [i]. nomer: =0;

Const_tab [i]. value: ='';

Const_tab [i]. Typ: ='';

Const_tab [i]. Width: ='';

Const_tab [i]. Val10: ='';

Const_tab [k]. Left: =0;

Const_tab [k]. Right: =0;

Const_tab [k]. Way: ='';

end;

for i: =1 to numterm do

begin

Term_tab [i]. nomer: =0;

Term_tab [i]. Lex: ='';

Term_tab [i]. razd: =0;

Term_tab [i]. oper: =0;

Term_tab [i]. slug: =0;

Term_tab [k]. Left: =0;

Term_tab [k]. Right: =0;

Term_tab [k]. Way: ='';

end;

// инициализация

NumLex: =0; NumId: =0; NumConst: =0; NumErr: =0; NumTerm: =0;

Error: =false; Found: =false;

i: =0; j: =0; k: =0; y: =0;

String_counter: =0;

Memo2. Lines. Clear;

N6. Enabled: =true;

while string_counter<=Memo1. Lines. Count do // цикл по строкам файла

begin

n: =1;

m: =1;

s: =Form1. Memo1. Lines. Strings [string_counter] ;

for l: =1 to 2 do

while m<=Length (s) do // цикл по строке

begin

n: =m;

m: =Select_Lex (s,Lexem,n);

if (Lexem<>'') and not (Lexem [1] in [#0. #32]) then

begin

if FConst (Lexem) =1 then WriteLex ('C') else // вызов процедуры записи

if Termin=3 then WriteLex ('K') else

if Rome (Lexem) =1 then WriteLex ('M') else

if Ident (Lexem) =1 then WriteLex ('I') else

if Termin=1 then WriteLex ('R') else

if Termin=2 then WriteLex ('O')

else Err_lex;

end;

end;

string_counter: =string_counter+1;

end;

vyvod; // вызов процедуры вывода

end;

procedure TForm1. vyvod; // Вывод результатов

var

f: textfile; // выходной файл

begin

StringGrid1. RowCount: =NumConst+1; // определение числа строк в таблицах

StringGrid2. RowCount: =NumId+1;

StringGrid3. RowCount: =NumTerm+1;

StringGrid4. RowCount: =NumLex+1;

StringGrid1. Cells [0,0]: ='№'; StringGrid1. Cells [1,0]: ='Константа'; StringGrid1. Cells [2,0]: ='Тип';

StringGrid1. Cells [3,0]: ='Ширина'; StringGrid1. Cells [4,0]: ='10-тичный формат';

StringGrid1. Cells [5,0]: ='L'; StringGrid1. Cells [6,0]: ='R';

StringGrid1. Cells [7,0]: ='Путь'; // определение заголовков

for k: =1 to NumConst do // вывод таблицы констант

begin

StringGrid1. cells [0,k]: = Inttostr (Const_Tab [k]. nomer);

StringGrid1. cells [1,k]: = Const_Tab [k]. value;

StringGrid1. cells [2,k]: = Const_Tab [k]. Typ;

StringGrid1. cells [3,k]: = Const_Tab [k]. Width;

StringGrid1. cells [4,k]: = Const_Tab [k]. Val10;

StringGrid1. cells [5,k]: = Inttostr (Const_Tab [k]. Left);

StringGrid1. cells [6,k]: = Inttostr (Const_Tab [k]. Right);

StringGrid1. cells [7,k]: = Const_Tab [k]. Way;

end;

AssignFile (F,'Const. txt'); // запись в файл таблицы констант

Rewrite (F);

for k: =1 to NumConst do

Writeln (F, StringGrid1. cells [0,k] +' '+StringGrid1. cells [1,k] +' '+StringGrid1. cells [2,k] +' '+StringGrid1. cells [3,k]);

CloseFile (F);

StringGrid2. Cells [0,0]: ='№'; StringGrid2. Cells [1,0]: ='Имя'; // определение заголовков

k: =0;

k1: =0;

while k<numid do // вывод таблицы идентификаторов

begin

if Id_tab [k1]. lex<>'' then

begin

StringGrid2. cells [0,k+1]: =IntToStr (Id_tab [k1]. nomer);

StringGrid2. cells [1,k+1]: =Id_Tab [k1]. lex;

k: =k+1;

end;

k1: =k1+1;

end;

AssignFile (F,'Ident. txt'); // запись в файл таблицы констант

Rewrite (F);

for k: =1 to NumId do Writeln (F, StringGrid2. cells [0,k] +' '+StringGrid2. cells [1,k]);

CloseFile (F);

StringGrid3. Cells [0,0]: ='№'; StringGrid3. Cells [1,0]: ='Символ'; StringGrid3. Cells [2,0]: ='Раздел. ';

StringGrid3. Cells [3,0]: ='Зн. операции'; StringGrid3. Cells [4,0]: ='Ключ. слово';

StringGrid3. Cells [5,0]: ='L'; StringGrid3. Cells [6,0]: ='R';

StringGrid3. Cells [7,0]: ='Путь'; // определение заголовков

for k: =1 to NumTerm do // вывод таблицы терминальных символов

begin

StringGrid3. cells [0,k]: = Inttostr (Term_Tab [k]. nomer);

StringGrid3. cells [1,k]: = Term_Tab [k]. lex;

StringGrid3. cells [2,k]: = Inttostr (Term_Tab [k]. razd);

StringGrid3. cells [3,k]: = Inttostr (Term_Tab [k]. oper);

StringGrid3. cells [4,k]: = Inttostr (Term_Tab [k]. slug);

StringGrid3. cells [5,k]: = Inttostr (Term_Tab [k]. Left);

StringGrid3. cells [6,k]: = Inttostr (Term_Tab [k]. Right);

StringGrid3. cells [7,k]: = Term_Tab [k]. Way;

end;

AssignFile (F,'Term. txt'); // запись в файл таблицы терминальных символов

Rewrite (F);

for k: =1 to NumTerm do Writeln (F, StringGrid3. cells [0,k] +' '+StringGrid3. cells [1,k] +' '+StringGrid3. cells [2,k] +' '+StringGrid3. cells [3,k] +' '+StringGrid3. cells [4,k]);

CloseFile (F);

StringGrid4. Cells [0,0]: ='№'; StringGrid4. Cells [1,0]: ='Тип'; StringGrid4. Cells [2,0]: ='№ в таблице'; StringGrid4. Cells [3,0]: ='Лексема'; // определение заголовков

for k: =1 to NumLex do // вывод таблицы кодов лексем

begin

StringGrid4. cells [0,k]: = Inttostr (Code_Tab [k]. nomer);

StringGrid4. cells [1,k]: = Code_Tab [k]. typ;

StringGrid4. cells [2,k]: = Inttostr (Code_Tab [k]. num);

StringGrid4. cells [3,k]: = Code_Tab [k]. lex;

end;

AssignFile (F,'Cod. txt'); // запись в файл выходной таблицы

Rewrite (F);

for k: =1 to NumLex do Writeln (F, StringGrid4. cells [0,k] +' '+StringGrid4. cells [1,k] +' '+StringGrid4. cells [2,k] +' '+StringGrid4. cells [3,k]);

CloseFile (F);

end;

procedure TForm1. Err_Lex; // процедура вывода ошибки в лексеме

begin

Memo2. Lines. Add ('В строке №'+Inttostr (String_counter+1) +' ошибочная лексема '+Lexem);

NumErr: =NumErr+1;

NumLex: =NumLex+1;

Code_Tab [NumLex]. nomer: =NumLex;

Code_Tab [NumLex]. Lex: =Lexem;

Code_Tab [NumLex]. typ: ='E';

Code_Tab [NumLex]. Num: =NumErr;

Exit;

end;

procedure TForm1. N6Click (Sender: TObject);

begin

Syntax;

end;

procedure TForm1. Syntax;

begin

i: =1; // инициализация

Error: =false;

Scobka: =false;

Memo2. Clear;

if (Lex_Progr=true) and (Error<>true) then Memo2. Lines [0]: ='Ошибок нет' else if Memo2. Lines [0] ='' then Memo2. Lines [0]: ='Неизвестная ошибка'

end;

function TForm1. Lex_Progr: boolean; // 1. программа

begin

Lex_Progr: =False;

if Code_Tab [i]. Lex='program' then i: =i+1 else // конец блока для PROGRAM

begin

Err_Synt ('Отсутствует служебное слово program, либо в нем ошибка ', i);

Exit;

end;

if Lex_Prog_Name=false then Exit; // начало блока для имени программы

if Code_Tab [i]. Lex='; ' then i: =i+1 else // начало блока для точки с запятой

begin

Err_Synt ('Отсутствует точка с запятой после имени программы', i-1);

Exit;

end;

if Code_Tab [i]. Lex='var' then i: =i+1 else // начало блока для VAR

begin

Err_Synt ('Отсутствует служебное слово var после заголовка программы', i);

Exit;

end;

if Lex_descr_list=false then Exit;

if Code_Tab [i]. Lex='begin' then // начало блока для BEGIN

begin

i: =i+1;

if Code_Tab [i]. Lex='; ' then

begin

Err_Synt ('После begin недопустим символ "; "', i);

Exit;

end;

end else

begin

Err_Synt ('Отсутствует служебное слово begin после описаний переменных', i);

Exit;

end;

if Lex_oper_list=false then Exit;

if Code_Tab [i]. Lex='end' then i: =i+1 else // начало блока для END

begin

Err_Synt ('Отсутствует служебное слово end в конце программы', i);

Exit;

end; // начало блока для точки

if Code_Tab [i]. Lex='. ' then Lex_Progr: =true else if Code_Tab [i]. Lex<>'' then Err_Synt ('После служебного слова END вместо точки находится "'+Code_Tab [i]. Lex+'"', i) else Err_Synt ('Ожидается точка после служебного слова END в конце программы', i-1);

end;

procedure TForm1. Err_Synt (text: string; l: integer);

begin

if Error<>true then

begin

Memo1. Lines [Code_tab [l]. numstr-1]: =Memo1. Lines [Code_tab [l]. numstr-1] +'!!! '+'Error!!! ';

Memo2. Lines [0]: =Memo2. Lines [0] +text;

end;

Error: =true;

Exit;

end;

function TForm1. Lex_Prog_Name: boolean; // имя программы

begin

Lex_Prog_Name: =False;

if (Code_Tab [i]. typ<>'I') and (Code_Tab [i]. Lex<>'; ') then

begin

Err_Synt ('Неправильное имя программы. Ошибочное выражение: "'+Code_Tab [i]. Lex+'"', i);

Exit;

end;

if Code_Tab [i]. Lex='; ' then

begin

Err_Synt ('Отсутствует имя программы после program', i);

Exit;

end;

Lex_Prog_Name: =true;

i: =i+1;

end;

function TForm1. Lex_Descr_List: boolean; // список описаний

begin

Lex_descr_list: =false;

Found: =false;

while Code_Tab [i]. typ='I' do

begin

Found: =true;

if Lex_descr=false then Exit;

if Code_Tab [i]. Lex='; ' then i: =i+1 else

begin

Err_Synt ('Отсутствует точка с запятой после описания переменных ', i-1);

Exit;

end;

end;;

if Found=false then

begin

Err_Synt ('Отсутствует идентификатор в описании ', i);

Exit;

end;

Lex_descr_list: =true;

end;

function TForm1. Lex_descr: boolean; // описание

begin

Lex_descr: =false;

if Lex_name_list=true then

begin

if Code_Tab [i]. Lex=': ' then i: =i+1 else

begin

Err_Synt ('Отсутствует двоеточие перед типом '+Code_Tab [i]. Lex, i);

Exit;

end;

if Lex_type=true then Lex_descr: =true else Exit;

end else Exit;

end;

function TForm1. Lex_name_list: boolean; // список имен

begin

Lex_name_list: =false;

if Code_Tab [i]. typ='I' then i: =i+1 else

begin

Err_Synt ('Ожидается идентификатор ', i);

Exit;

end;

while Code_Tab [i]. Lex=',' do

begin

i: =i+1;

if Code_Tab [i]. Typ='I' then i: =i+1 else

begin

Err_Synt ('Ожидается идентификатор ', i);

Exit;

end;

end;

Lex_name_list: =true;

end;

function TForm1. Lex_type: boolean; // тип

begin

Lex_type: =false;

if (Code_Tab [i]. Lex='integer') then

begin

Lex_type: =true;

i: =i+1

end else

begin

Err_Synt ('Отсутствует тип: integer ', i-1);

Exit;

end;

end;

function TForm1. Lex_oper_list: boolean; // список операторов

begin

Lex_oper_list: =false;

found: =false;

while Lex_oper=true do

begin

Found: =true;

if (Code_Tab [i]. Lex='; ') then i: =i+1 else // Если след. лексема после проверенного оператора ни "; ", ни END, а любая другая лексема.

if Code_Tab [i]. Lex<>'end' then

begin

Err_Synt ('Ожидается точка с запятой после оператора (после лексемы '+Code_Tab [i-1]. Lex+') ', i-1);

Exit;

end;

end;

Lex_oper_list: =true;

if found=false then

begin

Err_Synt ('Не найдены операторы между begin и end', i-1);

Lex_oper_list: =false;

end;

end;

function TForm1. Lex_oper: boolean;

begin

Lex_oper: =false;

if (Lex_assign) or (Lex_repeat_until) then Lex_oper: =true else