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; { Количество строк }
Читать дальше
Конец ознакомительного отрывка
Купить книгу