Книга: Системное программное обеспечение. Лабораторный практикум

Листинг П3.10. Описание структур данных триад

Листинг П3.10. Описание структур данных триад

unit Triads;

interface

{ Модуль, обеспечивающий работу с триадами и их списком }

uses Classes, TblElem, LexElem, TrdType;

type

TTriad = class; { Предварительное описание класса триад }

TOpType = (OP_CONST, OP_VAR, OP_LINK); { Типы операндов:

константа, переменная, ссылка на другую триаду }

TOperand = record { Структура описания операнда в триадах }

case OpType: TOpType of { Тип операнда }

OP_CONST: (ConstVal: integer);{для констант – значение}

OP_VAR: (VarLink: TVarInfo);{ для переменной – ссылка

на элемент таблицы идентификаторов }

OP_LINK: (TriadNum: integer);{ для триады – номер }

end;

TOpArray = array[1..2] of TOperand; {Массив из 2 операндов}

TTriad = class(TObject)

private { Структура данных для описания триады }

TriadType: TTriadType; { Тип триады }

Operands: TOpArray; { Массив операндов }

public

Info: longint; { Дополнительная информация

для оптимизирующих алгоритмов }

IsLinked: Boolean; { Флаг наличия ссылки на эту триаду }

{ Конструктор для создания триады }

constructor Create(Typ: TTriadType; const Ops: TOpArray);

{ Функции для чтения и записи операндов }

function GetOperand(iIdx: integer): TOperand;

procedure SetOperand(iIdx: integer; Op: TOperand);

{ Функции для чтения и записи ссылок на другие триады }

function GetLink(iIdx: integer): integer;

procedure SetLink(iIdx: integer; TrdN: integer);

{ Функции для чтения и записи типа операндов }

function GetOpType(iIdx: integer): TOpType;

procedure SetOpType(iIdx: integer; OpT: TOpType);

{ Функции для чтения и записи значений констант }

function GetConstVal(iIdx: integer): integer;

procedure SetConstVal(iIdx: integer; iVal: integer);

{ Свойства триады, основанные на описанных функциях }

property TrdType: TTriadType read TriadType;

property Opers[iIdx: integer]: TOperand read GetOperand

write SetOperand; default;

property Links[iIdx: integer]: integer read GetLink

write SetLink;

property OpTypes[iIdx: integer]: TOpType read GetOpType

write SetOpType;

property Values[iIdx: integer]: integer read GetConstVal

write SetConstVal;

{ Функция, проверяющая эквивалентность двух триад }

function IsEqual(Trd1: TTriad): Boolean;

{ Функция, формирующая строковое представление триады }

function MakeString(i: integer): string;

end;

TTriadList = class(TList)

public { Класс для описания списка триад и работы с ним }

procedure Clear; override; { Процедура очистки списка }

destructor Destroy; override;{Деструктор удаления списка}

{ Процедура вывода списка триад в список строк

для отображения списка триад }

procedure WriteToList(list: TStrings);

{ Процедура удаления триады из списка }

procedure DelTriad(iIdx: integer);

{ Функция получения триады из списка по ее номеру }

function GetTriad(iIdx: integer): TTriad;

{ Свойство списка триад для доступа по номеру триады }

property Triads[iIdx: integer]: TTriad read GetTriad;

default;

end;

{ Процедура удаления из списка триад заданного типа }

procedure DelTriadTypes(listTriad: TTriadList;

TrdType: TTriadType);

implementation

uses SysUtils, FncTree, LexType;

constructor TTriad.Create(Typ: TTriadType;

const Ops: TOpArray);

{ Конструктор создания триады }

var i: integer;

begin

inherited Create; {Вызываем конструктор базового класса}

TriadType:= Typ; { Запоминаем тип триады }

{ Запоминаем два операнда триады }

for i:=1 to 2 do Operands[i]:= Ops[i];

Info:= 0; { Очищаем поле дополнительной информации }

IsLinked:= False; { Очищаем поле внешней ссылки }

end;

function TTriad.GetOperand(iIdx: integer): TOperand;

{ Функция получения данных об операнде по его номеру }

begin Result:= Operands[iIdx]; end;

procedure TTriad.SetOperand(iIdx: integer; Op: TOperand);

{ Функция записи данных операнда триады по его номеру }

begin Operands[iIdx]:= Op; end;

function TTriad.GetLink(iIdx: integer): integer;

{ Функция получения ссылки на другую триаду из операнда }

begin Result:= Operands[iIdx].TriadNum; end;

procedure TTriad.SetLink(iIdx: integer; TrdN: integer);

{ Функция записи номера ссылки на другую триаду }

begin Operands[iIdx].TriadNum:= TrdN; end;

function TTriad.GetOpType(iIdx: integer): TOpType;

{ Функция получения типа операнда по его номеру }

begin Result:= Operands[iIdx].OpType; end;

function TTriad.GetConstVal(iIdx: integer): integer;

{ Функция записи типа операнда по его номеру }

begin Result:= Operands[iIdx].ConstVal; end;

procedure TTriad.SetConstVal(iIdx: integer; iVal: integer);

{ Функция получения значения константы из операнда }

begin Operands[iIdx].ConstVal:= iVal; end;

procedure TTriad.SetOpType(iIdx: integer; OpT: TOpType);

{ Функция записи значения константы в операнд }

begin Operands[iIdx].OpType:= OpT; end;

function IsEqualOp(const Op1,Op2: TOperand): Boolean;

{ Функция проверки совпадения двух операндов }

begin { Операнды равны, если совпадают их типы }

Result:= (Op1.OpType = Op2.OpType);

if Result then { и значения в зависимости от типа }

case Op1.OpType of

OP_CONST: Result:= (Op1.ConstVal = Op2.ConstVal);

OP_VAR: Result:= (Op1.VarLink = Op2.VarLink);

OP_LINK: Result:= (Op1.TriadNum = Op2.TriadNum);

end;

end;

function TTriad.IsEqual(Trd1: TTriad): Boolean;

{ Функция, проверяющая совпадение двух триад }

begin { Триады эквивалентны, если совпадают их типы }

Result:= (TriadType = Trd1.TriadType) { и оба операнда }

and IsEqualOp(Operands[1],Trd1[1])

and IsEqualOp(Operands[2],Trd1[2]);

end;

function GetOperStr(Op: TOperand): string;

{ Функция формирования строки для отображения операнда }

begin

case Op.OpType of

OP_CONST: Result:= IntToStr(Op.ConstVal);

OP_VAR: Result:= Op.VarLink.VarName;

OP_LINK: Result:= ^ + IntToStr(Op.TriadNum+1);

end{case};

end;

function TTriad.MakeString(i: integer): string;

begin

Result:= Format(%d: #9 %s (%s, %s),

[i+1,TriadStr[TriadType],

GetOperStr(Opers[1]), GetOperStr(Opers[2])]);

end;

destructor TTriadList.Destroy;

{ Деструктор для удаления списка триад }

begin

Clear; { Очищаем список триад }

inherited Destroy; {Вызываем деструктор базового класса}

end;

procedure TTriadList.Clear;

{ Процедура очистки списка триад }

var i: integer;

begin { Освобождаем память для всех триад из списка }

for i:=Count-1 downto 0 do TTriad(Items[i]). Free;

inherited Clear; { Вызываем функцию базового класса }

end;

procedure TTriadList.DelTriad(iIdx: integer);

{ Функция удаления триады из списка триад }

begin

if iIdx < Count-1 then { Если это не последняя триада,

переставляем флаг ссылки на предыдущую (если флаг есть)}

TTriad(Items[iIdx+1]). IsLinked:=

TTriad(Items[iIdx+1]). IsLinked

or TTriad(Items[iIdx]). IsLinked;

TTriad(Items[iIdx]). Free; { Освобождаем память триады }

Delete(iIdx); { Удаляем ссылку на триаду из списка }

end;

function TTriadList.GetTriad(iIdx: integer): TTriad;

{ Функция выборки триады из списка по ее номеру }

begin Result:= TTriad(Items[iIdx]); end;

procedure TTriadList.WriteToList(list: TStrings);

{ Процедура вывода списка триад в список строк

для отображения списка триад }

var i,iCnt: integer;

begin

list.Clear; { Очищаем список строк }

iCnt:= Count-1;

for i:=0 to iCnt do { Для всех триад из списка триад }

{ Формируем строковое представление триады

и добавляем его в список строк }

list.Add(TTriad(Items[i]). MakeString(i));

end;

procedure DelTriadTypes(listTriad: TTriadList;

TrdType: TTriadType);

{ Процедура удаления из списка триад заданного типа }

var

i,j,iCnt,iDel: integer;

listNum: TList;

Trd: TTriad; { Список запоминания изменений индексов }

begin

iDel:= 0; { В начале изменение индекса нулевое }

iCnt:= listTriad.Count-1;

{ Создаем список запоминания изменений индексов триад }

listNum:= TList.Create;

try

for i:=0 to iCnt do { Для всех триад списка выполняем }

begin { запоминание изменений индекса }

{ Запоминаем изменение индекса данной триады }

listNum.Add(TObject(iDel));

{Если триада удаляется, увеличиваем изменение индекса}

if listTriad[i].TriadType = TrdType then Inc(iDel);

end;

for i:=iCnt downto 0 do { Для всех триад списка }

begin { изменяем индексы ссылок }

Trd:= listTriad[i];

{ Если эта триада удаляемого типа, то удаляем ее }

if Trd.TriadType = TrdType then listTriad.DelTriad(i)

else { Иначе для каждого операнда триады смотрим,

не является ли он ссылкой }

for j:=1 to 2 do

if Trd[j].OpType = OP_LINK then { Если операнд

является ссылкой на триаду, уменьшаем ее индекс }

Trd.Links[j]:=

Trd.Links[j] – integer(listNum[Trd.Links[j]]);

end;

finally listNum.Free; { Уничтожаем временный список }

end;

end;

end.

Оглавление книги


Генерация: 1.187. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз