|
Разработка программы-компилятора |
ermyes: =0; // флаг: найдена ли лексемаif (NumTerm<>0) and (str_lex<>'') thenbeginif (CompareStr (Term_tab [Curr_term]. lex,str_lex) >0) and (Term_tab [Curr_term]. Left<>0) thenSearch_Term (Term_tab [Curr_term]. Left,str_lex); // рекурсивный "спуск по дереву"if (CompareStr (Term_tab [Curr_term]. lex,str_lex) <0) and (Term_tab [Curr_term]. Right<>0) thenSearch_Term (Term_tab [Curr_term]. Right,str_lex);if Term_tab [Curr_term]. lex=str_lex then Termyes: =Term_tab [Curr_term]. nomer;end;end; // функция распознавания 16-рич. константfunction FConst (str: string): integer;varsost: byte;beginsost: =0;if str [1] ='$' then // распознаём символ '$'beginsost: =1;delete (str,1,1);endelse exit;if (str [1] ='+') or (str [1] ='-') then // распознаём знакbeginsost: =2;delete (str,1,1)endelse begin sost: =4; exit; end;if str='' then exit;while length (str) >0 do beginif (str [1] in cifra) or (str [1] in bukva)then sost: =2 // распознаём буквы или цифрыelse begin sost: =4; exit;end;delete (str,1,1);end;sost: =3;if sost=3 then FConst: =1 else FConst: =-1;end;function termin: integer; // распознаватель терминальных символовbegintermin: =-1;for k: =1 to 14 do if Words [k] =Lexem then termin: =3;for k: =1 to 8 do if Razdel [k] =Lexem then termin: =1;for k: =1 to 11 do if Operacii [k] =Lexem then termin: =2;end;function Rome (str: string): integer; // распознаватель римских константvar sost: byte;beginsost: =0;if (str [1] ='-') or (str [1] ='+')then begin sost: =12; delete (str,1,1); end;if str='' then exit;if str [1] ='X'then begin sost: =1; delete (str,1,1) endelse beginif str [1] ='V' then begin sost: =2; delete (str,1,1) endelse beginif str [1] ='I' then begin sost: =3; delete (str,1,1) endelse begin sost: =4; exit; end; end; end;while Length (str) <>0 do begincase sost of1: if str [1] ='X'then begin sost: =5; delete (str,1,1) endelse beginif str [1] ='V' then begin sost: =2; delete (str,1,1) endelse beginif str [1] ='I' then begin sost: =3; delete (str,1,1) endelse begin sost: =4; exit; end; end; end;2: if str [1] ='I'then begin sost: =7; delete (str,1,1) endelse begin sost: =4; exit; end;3: if str [1] ='X'then begin sost: =8; delete (str,1,1) endelse beginif str [1] ='V' then begin sost: =9; delete (str,1,1) endelse beginif str [1] ='I' then begin sost: =10; delete (str,1,1) endelse begin sost: =4; exit; end; end; end;4: exit;5: if str [1] ='X'then begin sost: =6; delete (str,1,1) endelse beginif str [1] ='V' then begin sost: =2; delete (str,1,1) endelse beginif str [1] ='I' then begin sost: =3; delete (str,1,1) endelse begin sost: =4; exit; end; end; end;6: if str [1] ='V'then begin sost: =2; delete (str,1,1) endelse beginif str [1] ='I' then begin sost: =3; delete (str,1,1) endelse begin sost: =4; exit; end; end;7: if str [1] ='I'then begin sost: =10; delete (str,1,1) endelse begin sost: =4; exit; end;8: begin sost: =4; exit; end;9: begin sost: =4; exit; end;10: if str [1] ='I'then begin sost: =11; delete (str,1,1) endelse begin sost: =4; exit; end;11: begin sost: =4; exit; end;end;end;if (sost=4) or (sost=12) then Rome: =-1 else Rome: =1;end; // функция распознавания идентификаторовfunction Ident (str: string): integer;varsost: byte;beginsost: =0; // реализация конечного автоматаif str [1] in ['a'. 'z'] thenbeginsost: =1;delete (str,1,1)endelse exit;while length (str) >0 do beginif str [1] in ['a'. 'z','0'. '9','_']then begin sost: =1; delete (str,1,1); endelse begin sost: =3; exit; end;end;sost: =2;if sost=2 then ident: =1 else ident: =-1;end;procedure WriteCode (nomer: integer; lex: string; typ: char; num: integer); // запись в таблицу кодов лексемbeginCode_Tab [NumLex]. nomer: =nomer;Code_Tab [NumLex]. Lex: =lex;Code_Tab [NumLex]. typ: =typ;Code_Tab [NumLex]. Num: =num;Code_Tab [NumLex]. numstr: =string_counter+1;end;procedure WriteLex (typelex: char); // запись лексем в таблицыbegincase typelex of'C': begin // если лексема-16-рич. константаNumLex: =NumLex+1;Search_Const (1,Lexem);if Constyes=0 then // если лексема не найденаbeginNumConst: =NumConst+1;Add_Const (1,Lexem);Const_tab [NumConst]. Typ: ='16-рич. ';Const_tab [Numconst]. Width: ='2 байта';WriteCode (NumLex,Lexem,'C',NumConst);end else // если лексема найденаbeginWriteCode (NumLex,Lexem,'C',Constyes);end;end;'M': begin // если лексема-римская константаNumLex: =NumLex+1;Search_Const (1,Lexem);if Constyes=0 then // если лексема не найденаbeginNumConst: =NumConst+1;Add_Const (1,Lexem);Const_tab [NumConst]. Typ: ='римск. ';Const_tab [Numconst]. Width: ='2 байта';WriteCode (NumLex,Lexem,'C',NumConst);end else // если лексема найденаbeginWriteCode (NumLex,Lexem,'C',Constyes);end;end;'I': begin // если лексема-идентификаторNumLex: =NumLex+1;y: =Search_Ident ({1,}Lexem);if y=0 then // если лексема не найденаbeginNumId: =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 // если лексема не найденаbeginNumTerm: =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 // если лексема не найденаbeginNumTerm: =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 // если лексема не найденаbeginNumTerm: =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;beginfor k: =1 to numid do // обнуление таблицы идентификаторовbeginid_tab [k]. lex: ='0';id_tab [k]. nomer: =0;id_tab [i]. ssylka: =0;end;for i: =1 to numlex do // обнуление выходной таблицыbeginCode_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 // обнуление таблицы константbeginConst_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 dobeginTerm_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 // цикл по строкам файлаbeginn: =1;m: =1;s: =Form1. Memo1. Lines. Strings [string_counter] ;for l: =1 to 2 dowhile m<=Length (s) do // цикл по строкеbeginn: =m;m: =Select_Lex (s,Lexem,n);if (Lexem<>'') and not (Lexem [1] in [#0. #32]) thenbeginif FConst (Lexem) =1 then WriteLex ('C') else // вызов процедуры записиif Termin=3 then WriteLex ('K') elseif Rome (Lexem) =1 then WriteLex ('M') elseif Ident (Lexem) =1 then WriteLex ('I') elseif Termin=1 then WriteLex ('R') elseif Termin=2 then WriteLex ('O')else Err_lex;end;end;string_counter: =string_counter+1;end;vyvod; // вызов процедуры выводаend;procedure TForm1. vyvod; // Вывод результатовvarf: textfile; // выходной файлbeginStringGrid1. 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 // вывод таблицы константbeginStringGrid1. 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 doWriteln (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 // вывод таблицы идентификаторовbeginif Id_tab [k1]. lex<>'' thenbeginStringGrid2. 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 // вывод таблицы терминальных символовbeginStringGrid3. 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 // вывод таблицы кодов лексемbeginStringGrid4. 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; // процедура вывода ошибки в лексемеbeginMemo2. 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;2.4.4 Тестирование лексического анализатораТекст программы не содержит ошибок:program var15;var n: integer;beginn: =$+00;repeatn: =n- (-XII);until n<$-0A;end.Результат - таблицы констант, идентификаторов, терминальных символов и кодов лексем (см. рис.5, б) и отсутствие сообщениий об ошибках (см. рис.5, а).рис.5, а.рис.5, брис.5. Результаты тестирования программы, не содержащей ошибок.Текст программы содержит ошибочные лексемы var% и $+MN.program var15;var% n: integer;beginn: =$+MN;repeatn: =n- (-XII);until n<$-0A;end.Результат - в таблицу кодов лексем эти лексемы занесены с типом Е, что означает, что они ошибочны (см. Рис.6, а, б), программа выдала также сообщения об ошибках (Рис.6, в).Рис.6, аРис.6, бРис.6, вРис.6. Результаты тестирования программы, содержащей ошибочные лексемы.
Страницы: 1, 2, 3, 4, 5, 6, 7, 8
|
|
|
© 2003-2013
Рефераты бесплатно, курсовые, рефераты биология, большая бибилиотека рефератов, дипломы, научные работы, рефераты право, рефераты, рефераты скачать, рефераты литература, курсовые работы, реферат, доклады, рефераты медицина, рефераты на тему, сочинения, реферат бесплатно, рефераты авиация, рефераты психология, рефераты математика, рефераты кулинария, рефераты логистика, рефераты анатомия, рефераты маркетинг, рефераты релиния, рефераты социология, рефераты менеджемент. |
|
|