sTmp:= ParamStr(i); { Берем строку параметра }
iLen:= Length(sTmp); { Длина строки параметра }
{ Если параметр слишком короткий или не начинается
со знака «-» – это неправильный параметр }
if (iLen < 3) or (sTmp[1] <> – ) then
{ Запоминаем ошибку в список }
listErr.Add(Format('Неверный параметр %d: «%s»!
[i,sTmp]))
else { Иначе обрабатываем параметр в соответствии
с его типом (второй символ) }
case sTmp[2] of
{ Флаг оптимизации ассемблера }
'a','A': flOptAsm:= (sTmp[3] = 1 );
{ Флаг оптимизации методом свертки }
'c','C': flOptC:= (sTmp[3] = 1 );
{ Флаг оптимизации исключением лишних операций }
's','S': flOptSame:= (sTmp[3] = 1 );
{ Имя выходного файла }
'o','O': sOutFile:= System.Copy(sTmp,3,iLen-2);
{ Имя файла ошибок }
'e','E': StartInfo(System.Copy(sTmp,3,iLen-2));
else { Параметр неизвестного типа }
{ Запоминаем ошибку в список }
listErr.Add(Format('Неверный параметр %d: «%s»!
[i,sTmp]));
end{case};
end{for};
{ Ставим имена файлов по умолчанию,
если они не были указаны в параметрах }
if sOutFile = then
sOutFile:= ChangeFileExt(sInpFile, asm');
if sErrFile = then
StartInfo(ChangeFileExt(sInpFile, err'));
iCnt:= listErr.Count-1; { Количество ошибок }
{ Запоминаем информацию обо всех ошибках }
for i:=0 to iCnt do ErrInfo(sErrFile,listErr[i],0,0)
finally listErr.Free; { Уничтожаем список ошибок }
end{try};
end;
procedure TCursovForm.FormCreate(Sender: TObject);
var flOptC,flOptSame,flOptAsm: Boolean;
symbRes: TSymbol;
iErr: TErrType;
begin
symbRes:= nil; sOutFile:= ; sErrFile:= ;
{ В начале выполнения инициализируем список лексем, таблицу
идентификаторов, синтаксический стек и список триад }
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; { Анализ списка строк и заполнение списка лексем }