идентификаторов, синтаксический стек и список триад }
InitTreeVar;
listLex:= TLexList.Create;
symbStack:= TSymbStack.Create;
listTriad:= TTriadList.Create;
{ Если указан параметр – не надо открывать окно,
надо запускать компилятор и обрабатывать входной файл }
if ParamCount > 0 then
begin { Берем имя входного файла из первого параметра }
sInpFile:= ParamStr(1);
{ Обрабатываем все остальные параметры }
ProcessParams(flOptC,flOptSame,flOptAsm);
iErr:= CompRun({ Запускаем компилятор }
sInpFile,sOutFile,sErrFile{входные файлы},
symbRes{ссылка на дерево разбора},
False{запоминать списки триад не надо},
flOptC{флаг удаления триад "C"},
flOptSame{флаг удаления триад «SAME»},
flOptC{флаг свертки объектного кода },
flOptSame{флаг исключения лишних операций},
flOptAsm{оптимизация команд ассемблера});
{ Если нет файловых ошибок, то надо завершать работу }
if iErr <> ERR_FILE then Self.Close;
end;
end;
procedure TCursovForm.FormClose(Sender: TObject;
var Action: TCloseAction);
{ В конце выполнения очищаем список лексем, таблицу
идентификаторов, синтаксический стек и список триад }
begin
listTriad.Free; symbStack.Free;
listLex.Free; ClearTreeVar;
Application.Terminate;
end;
procedure TCursovForm.EditFileChange(Sender: TObject);
begin { Можно читать файл, только когда его имя не пустое }
BtnLoad.Enabled:= (EditFile.Text <> );
end;
procedure TCursovForm.BtnFileClick(Sender: TObject);
begin { Выбор имени файла с помощью стандартного диалога }
if FileOpenDlg.Execute then
begin
EditFile.Text:= FileOpenDlg.FileName;
BtnLoad.Enabled:= (EditFile.Text <> );
end;
end;
procedure TCursovForm.ErrInfo(const sErrF,sErr: string;
iPos,iLen: integer);
{ Процедура информации об ошибке }
var fileErr: TextFile; { Файл записи информации об ошибке }
begin { Если имя файла ошибок не пустое }
if sErrF <> then
try { Записываем информацию об ошибке в файл }
AssignFile(fileErr,sErrF);
if FileExists(sErrF) then Append(fileErr)
else Rewrite(fileErr);
writeln(fileErr,sErr);
CloseFile(fileErr); { и закрываем его }
except { Если ошибка записи в файл, сообщаем об этом }
MessageDlg(Format('Ошибка записи в файл «%s»! #13#10
+ 'Ошибка компиляции: %s![sErrF,sErr]),
mtError,[mbOk],0);
end { Если имя файла ошибок пустое, }
else { выводим информацию на экран }
begin { Позиционируем список строк на место ошибки }
ListIdents.SelStart:= iPos;
ListIdents.SelLength:= iLen;
MessageDlg(sErr,mtWarning,[mbOk],0);{Выводим сообщение}
ListIdents.SetFocus; { Выделяем ошибку в списке строк }
end;
end;
function TCursovForm.CompRun({Функция запуска компилятора}
const sInF,{имя входного файла}
sOutF,{имя результирующего файла}
sErrF{имя файла ошибок}:string;
var symbRes: TSymbol;{корень дерева разбора}
flTrd,{флаг записи триад в списки}
flDelC,{флаг удаления триад типа "C"}
flDelSame,{флаг удаления триад типа «SAME»}
flOptC,{флаг оптимизации методом свертки}
flOptSame,{флаг исключения лишних операций}
flOptAsm{флаг оптимизации ассемблерного кода}
: Boolean): TErrType;
var i,iCnt,iErr: integer; { переменные счетчиков }
lexTmp: TLexem; { временная лексема для инф. об ошибках }
sVars,sAdd: string; { временные строки }
asmList: TStringList; { список ассемблерных команд }
begin{ Очищаем список лексем, синтаксический стек и список триад }
listLex.Clear; symbStack.Clear; listTriad.Clear;
try { Чтение файла в список строк }
ListIdents.Lines.LoadFromFile(sInF);
except { Если файловая ошибка – сообщаем об этом }
Result:= ERR_FILE;
MessageDlg('Ошибка чтения файла!mtError,[mbOk],0);
Exit; { Дальнейшая работа компилятора невозможна }
end; { Анализ списка строк и заполнение списка лексем }
iErr:= MakeLexList(ListIdents.Lines,listLex);
if iErr<>0 then {Анализ неуспешный – сообщаем об ошибке}
begin { Берем позицию ошибки из лексемы в начале списка }
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);
Читать дальше
Конец ознакомительного отрывка
Купить книгу