Алексей Молчанов - Системное программное обеспечение. Лабораторный практикум
- Название:Системное программное обеспечение. Лабораторный практикум
- Автор:
- Жанр:
- Издательство:Array Издательство «Питер»
- Год:2005
- Город:Санкт-Петербург
- ISBN:978-5-469-00391-4
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Алексей Молчанов - Системное программное обеспечение. Лабораторный практикум краткое содержание
Книга ориентирована на студентов, обучающихся в технических вузах по специальностям, связанным с вычислительной техникой. Но она будет также полезна всем, чья деятельность так или иначе касается разработки программного обеспечения.
Системное программное обеспечение. Лабораторный практикум - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
ErrInfo(sErrF,
Format('Неверная лексема «%s» в строке %d!
[listLex[0].LexInfoStr,iErr]),
listLex[0].PosAll,listLex[0].PosNum);
Result:= ERR_LEX; { Результат – лексическая ошибка }
end
else { Добавляем в конец списка лексем }
begin { информационную лексему «конец строки» }
with ListIdents do
listLex.Add(TLexem.CreateInfo('Конец строки',
Length(Text), Lines.Count-1,0));
{ Выполняем синтаксический разбор
и получаем ссылку на корень дерева разбора }
symbRes:= BuildSyntList(listLex,symbStack);
{ Если эта ссылка содержит лексические данные,
значит, была ошибка в месте, указанном лексемой }
if symbRes.SymbType = SYMB_LEX then
begin { Берем позицию ошибки из лексемы по ссылке }
ErrInfo(sErrF,
Format('Синтаксическая ошибка в строке %d поз. %d!
[symbRes.Lexem.StrNum+1,symbRes.Lexem.PosNum]),
symbRes.Lexem.PosAll,0);
symbRes.Free; { Освобождаем ссылку на лексему }
symbRes:= nil;
Result:= ERR_SYNT; { Это синтаксическая ошибка }
end
else { Иначе – ссылка указывает на корень
синтаксического дерева }
begin { Строим список триад по синтаксическому дереву }
lexTmp:= MakeTriadList(symbRes,listTriad);
{ Если есть ссылка на лексему, значит, была
семантическая ошибка }
if lexTmp <> nil then
begin { Берем позицию ошибочной лексемы по ссылке }
ErrInfo(sErrF,
Format('Семантическая ошибка в строке %d поз. %d!
[lexTmp.StrNum+1,lexTmp.PosNum]),
lexTmp.PosAll,0);
Result:= ERR_TRIAD; { Это семантическая ошибка }
end
else { Если ссылка пуста, значит, триады построены }
begin
Result:= ERR_NO; { Результат – «ошибок нет» }
{ Если указан флаг, сохраняем общий список триад }
if flTrd then
listTriad.WriteToList(ListTriadAll.Lines);
if flOptC then { Если указан флаг, выполняем }
begin { оптимизацию путем свертки объектного кода }
OptimizeConst(listTriad);
{ Если указан флаг, удаляем триады типа «C» }
if flDelC then
DelTriadTypes(listTriad,TRD_CONST);
end; { Если указан флаг,}
if flTrd then {сохраняем триады после оптимизации}
listTriad.WriteToList(ListTriadConst.Lines);
if flOptSame then { Если указан флаг, выполняем
begin{оптимизацию путем исключения лишних операций}
OptimizeSame(listTriad);
{ Если указан флаг, удаляем триады типа «SAME» }
if flDelSame then
DelTriadTypes(listTriad,TRD_SAME);
end; { Если указан флаг,}
if flTrd then {сохраняем триады после оптимизации}
listTriad.WriteToList(ListTriadSame.Lines);
{ Распределяем регистры по списку триад }
iCnt:= MakeRegisters(listTriad);
{ Создаем и записываем список ассемблерных команд }
asmList:= TStringList.Create;
try
with asmList do
begin
Clear; { Очищаем список ассемблерных команд }
{ Пишем заголовок программы }
Add(Format('program %s;,[NAME_PROG]));
{ Запоминаем перечень всех идентификаторов }
sVars:= IdentList(, ,NAME_INPVAR,NAME_FUNCT);
if sVars <> then
begin{Если перечень идентификаторов не пустой,}
Add( ); { записываем его с указанием }
Add('var'); { типа данных }
Add(Format(%s: %s;,[sVars,NAME_TYPE]));
end;
Add( );
{ Пишем заголовок функции }
Add(Format('function %0:s(%1:s: %2:s): %2:s;
+ stdcall;,
[NAME_FUNCT,NAME_INPVAR,NAME_TYPE]));
if iCnt > 0 then {Если регистров для хранения}
begin {промежуточных результатов не хватило}
Add('var'); {и нужны временные переменные,}
sVars:= ; {то заполняем их список.}
for i:=0 to iCnt do
begin
sAdd:= Format(%s%d',[TEMP_VARNAME,i]);
if sVars = then sVars:= sAdd
else sVars:= sVars +, + sAdd;
end;
Add(Format(%s: %s;,[sVars,NAME_TYPE]));
end;
Add('begin'); { В тело функции записываем }
Add(asm'); { список команд ассемблера, }
Add(#9'pushad'#9#9 {запоминаем регистры,});
MakeAsmCode(listTriad,asmList,flOptAsm);
Add(#9'popad'#9#9 {восстанавливаем регистры,});
Add(end;);
Add('end;);
Add( ); { Описываем одну входную переменную }
Add(Format('var %s: %s;,
[NAME_INPVAR,NAME_TYPE]));
Add( );
Add('begin'); { Заполняем главную программу }
Add(Format(readln(%s);,[NAME_INPVAR]));
Add(Format(writeln(%s(%s));,
[NAME_FUNCT,NAME_INPVAR]));
Add(readln;);
Add('end.);
end{with}; {Если установлен флаг, записываем}
if flTrd then {команды для отображения на экране}
ListAsm.Lines.AddStrings(asmList);
if sOutF <> then { Если есть имя рез. файла,}
try { записываем туда список всех команд }
asmList.SaveToFile(sOutF);
except Result:= ERR_FILE;
end;
finally asmList.Free; {Уничтожаем список команд}
end{try}; {после его отображения и записи в файл}
end;
end;
end;
end;
procedure TCursovForm.BtnLoadClick(Sender: TObject);
{ Процедура чтения и анализа файла }
var i,iCnt: integer; { переменные счетчиков }
iRes: TErrType; { переменная для хранения результата }
symbRes: TSymbol; { временная переменная корня дерева}
nodeTree: TTreeNode; { переменная для узлов дерева }
begin
symbRes:= nil; { Корень дерева разбора вначале пустой }
InitLexGrid; {Очищаем таблицу отображения списка лексем}
TreeSynt.Items.Clear; { Очищаем синтаксическое дерево }
iRes:= CompRun({ Вызываем функцию компиляции }
EditFile.Text, , ,{задан только входной файл}
symbRes{указатель на дерево разбора},
True{Списки триад нужно запоминать},
CheckDel_C.Checked {флаг удаления триад "C"},
CheckDelSame.Checked {флаг удаления триад «SAME»},
True {флаг оптимизации «свертка объектного кода»},
True {флаг оптимизации исключения лишних операций},
CheckAsm.Checked {оптимизация команд ассемблера});
if iRes > ERR_LEX then {Если не было лексической ошибки,}
begin { заполняем список лексем }
GridLex.RowCount:= listLex.Count+1; { Количество строк }
iCnt:= listLex.Count-1;
for i:=0 to iCnt do
begin { Цикл по всем прочитанным лексемам }
{ Первая колонка – номер }
GridLex.Cells[0,i+1]:= IntToStr(i+1);
{ Вторая колонка – тип лексемы }
GridLex.Cells[1,i+1]:=
LexTypeName(listLex[i].LexType);
{ Третья колонка – значение лексемы }
GridLex.Cells[2,i+1]:= listLex[i].LexInfoStr;
end;
end;
if (iRes > ERR_SYNT) and (symbRes <> nil) then
{ Если не было синтаксической ошибки,}
begin { заполняем дерево синтаксического разбора }
{ Записываем данные в корень дерева }
nodeTree:= TreeSynt.Items.Add(nil,symbRes.SymbolStr);
MakeTree(nodeTree,symbRes); { Строим дерево от корня }
nodeTree.Expand(True); { Раскрываем все дерево }
{ Позиционируем указатель на корневой элемент }
TreeSynt.Selected:= nodeTree;
end;
if iRes > ERR_TRIAD then { Если не было семантической }
begin { ошибки, то компиляция успешно завершена }
MessageDlg('Компиляция успешно выполнена!
mtInformation,[mbOk],0);
PageControl1.ActivePageIndex:= 4;
end;
end;
procedure TCursovForm.MakeTree(
{ Процедура отображения синтаксического дерева }
nodeTree: TTreeNode; {ссылка на корневой элемент
отображаемой части дерева на экране}
symbSynt: TSymbol {ссылка на синтаксический символ,
связанный с корневым элементом этой части дерева});
var i,iCnt: integer; { переменные счетчиков }
nodeTmp: TTreeNode; { текущий узел дерева }
begin { Берем количество дочерних вершин для текущей }
iCnt:= symbSynt.Count-1;
Читать дальшеИнтервал:
Закладка: