{ Код для бинарных арифметических операций }
TRD_ADD: MakeOper2('add', );
TRD_SUB: MakeOper2('sub','neg');
{ Код для унарного минуса }
TRD_UMIN: MakeOper1('neg', ,2);
TRD_ASSIGN: { Код для операции присвоения }
begin {Берем предыдущую команду и значение из eax}
TakePrevAsm;
sR:= GetOpName(i,listTriad,2); {Имя второго операнда}
{ Если имя второго операнда пустое, значит он уже есть
в регистре eax от выполнения предыдущей триады}
if sR <> then
begin {иначе генерируем код загрузки второго операнда}
sVal:= MakeMove(sR,sPrev,sVal,flagOpt);
if sVal <> then listCode.Add(sVal);
end; { Из eax записываем результат в переменную
с именем первого операнда }
sVal:= listTriad[i][1].VarLink.VarName;
if sVal = NAME_FUNCT then sVal:= NAME_RESULT;
sVal:= Format(#9'mov'#9 %s,eax'#9 { %s },
[sVal,listTriad[i].MakeString(i)]);
{ При этом запоминаем, что было в eax }
listCode.AddObject(sVal,TObject(PChar(sR)));
end;
{ Код для операции безусловного перехода }
TRD_JMP: listCode.Add(
Format(#9'jmp'#9 @M%d'#9 { %s },
[listTriad[i][2].TriadNum+1,
listTriad[i].MakeString(i)]));
{ Код для операции NOP }
TRD_NOP: listCode.Add(Format(#9'nop'#9#9 { %s },
[listTriad[i].MakeString(i)]));
end{case};
end{for};
Result:= listCode.Count;
end;
end.
Модуль интерфейса с пользователем
unit FormLab4;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, ComCtrls, Grids, ExtCtrls,
LexElem, SyntSymb, Triads;
type { Типы возможных ошибок компилятора: файловая,
лексическая, синтаксическая, семантическая или ошибок нет}
TErrType = (ERR_FILE,ERR_LEX,ERR_SYNT,ERR_TRIAD,ERR_NO);
TCursovForm = class(TForm) { главная форма программы }
PageControl1: TPageControl;
SheetFile: TTabSheet;
SheetLexems: TTabSheet;
BtnExit: TButton;
GroupText: TGroupBox;
ListIdents: TMemo;
EditFile: TEdit;
BtnFile: TButton;
BtnLoad: TButton;
FileOpenDlg: TOpenDialog;
GridLex: TStringGrid;
SheetSynt: TTabSheet;
TreeSynt: TTreeView;
SheetTriad: TTabSheet;
GroupTriadAll: TGroupBox;
Splitter1: TSplitter;
GroupTriadSame: TGroupBox;
Splitter2: TSplitter;
GroupTriadConst: TGroupBox;
ListTriadAll: TMemo;
ListTriadConst: TMemo;
ListTriadSame: TMemo;
CheckDel_C: TCheckBox;
CheckDelSame: TCheckBox;
SheetAsm: TTabSheet;
ListAsm: TMemo;
CheckAsm: TCheckBox;
procedure BtnLoadClick(Sender: TObject);
procedure BtnFileClick(Sender: TObject);
procedure EditFileChange(Sender: TObject);
procedure BtnExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject;
var Action: TCloseAction);
private
listLex: TLexList; { Список лексем }
symbStack: TSymbStack; { Синтаксический стек }
listTriad: TTriadList; { Список триад }
{ Имена файлов: входного, результата и ошибок }
sInpFile,sOutFile,sErrFile: string;
{ Функция записи стартовых данных в файл ошибок }
procedure StartInfo(const sErrF: string);
{ Функция обработки командной строки }
procedure ProcessParams(
var flOptC,flOptSame,flOptAsm: Boolean);
{ Инициализация таблицы отображения списка лексем }
procedure InitLexGrid;
{ Процедура отображения синтаксического дерева }
procedure MakeTree(nodeTree: TTreeNode;
symbSynt: TSymbol);
{ Процедура информации об ошибке }
procedure ErrInfo(const sErrF,sErr: string;
iPos,iLen: integer);
{ Функция запуска компилятора }
function CompRun(const sInF,sOutF,sErrF: string;
var symbRes: TSymbol; flTrd,flDelC,flDelSame,flOptC,
flOptSame,flOptAsm: Boolean): TErrType;
end;
var CursovForm: TCursovForm;
implementation
{$R *.DFM}
uses FncTree,LexType,LexAuto,TrdType,TrdMake,TrdAsm,TrdOpt;
procedure TCursovForm.InitLexGrid;
{Процедура инициализации таблицы отображения списка лексем}
begin
with GridLex do
begin
RowCount:= 2; Cells[0,0]:= № п/п';
Cells[1,0]:= 'Лексема'; Cells[2,0]:= 'Значение';
Cells[0,1]:= ; Cells[1,1]:= ; Cells[2,1]:= ;
end;
end;
procedure TCursovForm.StartInfo(
const sErrF: string{имя файла ошибок});
{ Функция записи стартовых данных в файл ошибок }
var i,iCnt: integer;{счетчик параметров и переменная цикла}
sT: string;{суммарная командная строка}
begin
sErrFile:= sErrF; { Запоминаем имя файла ошибок }
{ Записываем в файл ошибок дату запуска компилятора }
ErrInfo(sErrFile,
Format(– %s —,[DateTimeToStr(Now)]),0,0);
iCnt:= ParamCount; { Количество входных параметров }
sT:= ParamStr(0); { Обнуляем командную строку }
{Записываем в командную строку параметры последовательно}
for i:=1 to iCnt do sT:= sT + + ParamStr(i);
{ Записываем в файл ошибок суммарную командную строку }
ErrInfo(sErrFile,sT,0,0);
end;
procedure TCursovForm.ProcessParams(
var flOptC,flOptSame,flOptAsm: Boolean{флаги});
{ Функция обработки командной строки }
var i,iCnt,iLen: integer; { переменная счетчиков }
sTmp: string; { временная переменная }
{ Список для записи ошибок параметров }
listErr: TStringList;
begin { Устанавливаем все флаги по умолчанию }
flOptC:= True; flOptSame:= True;
flOptAsm:= True;
{ Создаем список для записи ошибок параметров }
listErr:= TStringList.Create;
try { Берем количество входных параметров }
iCnt:= ParamCount;
for i:=2 to iCnt do
begin { Обрабатываем параметры начиная со второго }