Книга: Системное программное обеспечение. Лабораторный практикум
Листинг П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.
- Резервное копирование базы данных InterBase
- Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Резервное копирование многофайловых баз данных
- Листинг 10.1. (simpleid.c) Отображение идентификаторов пользователя и группы
- Восстановление из резервных копий многофайловых баз данных
- Владелец базы данных
- ЧАСТЬ IV. База данных и ее объекты.
- Перевод базы данных InterBase 6.x на 3-й диалект
- Типы данных для работы с датой и временем
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Обзор основных причин повреждения базы данных
- Ошибки проектирования базы данных