then Result:= >;
end;
end;
end.
Модуль описания структур данных синтаксического анализатора и реализации алгоритма «сдвиг-свертка»
unit SyntSymb;
interface
{ Модуль, обеспечивающий выполнение функций синтаксического
разбора с помощью алгоритма «сдвиг-свертка» }
uses Classes, LexElem, SyntRule;
{ Типы символов: терминальные (лексемы) и нетерминальные }
type TSymbKind = (SYMB_LEX, SYMB_SYNT);
TSymbInfo = record{Структура данных для символа грамматики}
case SymbType: TSymbKind of { Тип символа }
{ Для терминального символа – ссылка на лексему }
SYMB_LEX: (LexOne: TLexem);
{ Для нетерминального символа – ссылка на список
символов, из которых он был построен }
SYMB_SYNT: (LexList: TList);
end;
TSymbol = class; {Предварительное описание класса «Символ»}
{ Массив символов, составляющих правило грамматики }
TSymbArray = array[0..RULE_LENGTH] of TSymbol;
TSymbol = class(TObject)
protected { Структура, описывающая грамматический символ }
SymbInfo: TSymbInfo; { Информация о символе }
iRuleNum: integer; {Номер правила, которым создан символ}
public
{ Конструктор создания терминального символа по лексеме }
constructor CreateLex(Lex: TLexem);
{ Конструктор создания нетерминального символа }
constructor CreateSymb(iR,iSymbN: integer;
const SymbArr: TSymbArray);
{ Деструктор для удаления символа }
destructor Destroy; override;
{Функция получения символа из правила по номеру символа}
function GetItem(iIdx: integer): TSymbol;
{ Функция получения количества символов в правиле }
function Count: integer;
{ Функция, формирующая строковое представление символа }
function SymbolStr: string;
{ Свойство, возвращающее тип символа }
property SymbType: TSymbKind read SymbInfo.SymbType;
{Свойство «Ссылка на лексему» для терминального символа}
property Lexem: TLexem read SymbInfo.LexOne;
{ Свойство, возвращающее символ правила по номеру }
property Items[i: integer]: TSymbol read GetItem; default;
{ Свойство, возвращающее номер правила }
property Rule: integer read iRuleNum;
end;
TSymbStack = class(TList)
public { Структура, описывающая синтаксический стек }
destructor Destroy; override; { Деструктор для стека }
procedure Clear; override; { Функция очистки стека }
{ Функция выборки символа по номеру от вершины стека }
function GetSymbol(iIdx: integer): TSymbol;
{ Функция помещения в стек входящей лексемы }
function Push(lex: TLexem): TSymbol;
{ Свойство выборки символа по номеру от вершины стека }
property Symbols[iIdx: integer]: TSymbol read GetSymbol;
default;
{ Функция, возвращающая самую верхнюю лексему в стеке }
function TopLexem: TLexem;
{ Функция, выполняющая свертку и помещающая новый символ
на вершину стека }
function MakeTopSymb: TSymbol;
end;
{ Функция, выполняющая алгоритм «сдвиг-свертка» }
function BuildSyntList(const listLex: TLexList;
symbStack: TSymbStack): TSymbol;
implementation
uses LexType, LexAuto;
constructor TSymbol.CreateLex(Lex: TLexem);
{ Создание терминального символа на основе лексемы }
begin
inherited Create; { Вызываем конструктор базового класа }
SymbInfo.SymbType:= SYMB_LEX;{Ставим тип «терминальный»}
SymbInfo.LexOne:= Lex; { Запоминаем ссылку на лексему }
iRuleNum:= 0; { Правило не используется, поэтому «0» }
end;
constructor TSymbol.CreateSymb(iR{Номер правила},
iSymbN{количество исходных символов}: integer;
const SymbArr: TSymbArray{Массив исходных символов});
{ Конструктор создания нетерминального символа
на основе правила и массива символов }
var i: integer;
begin
inherited Create; { Вызываем конструктор базового класа }
{ Тип символа «нетерминальный» }
SymbInfo.SymbType:= SYMB_SYNT;
{ Создаем список для хранения исходных символов }
SymbInfo.LexList:= TList.Create;
{Переносим исходные символы в список в обратном порядке}
for i:=iSymbN-1 downto 0 do
SymbInfo.LexList.Add(SymbArr[i]);
iRuleNum:= iR; { Запоминаем номер правила }
end;
function TSymbol.GetItem(iIdx: integer): TSymbol;
{ Функция получения символа из правила по номеру символа }
begin Result:= TSymbol(SymbInfo.LexList[iIdx]) end;
function TSymbol.Count: integer;
{ Функция, возвращающая количество символов в правиле }
begin Result:= SymbInfo.LexList.Count; end;
function TSymbol.SymbolStr: string;
{ Функция, формирующая строковое представление символа }
begin { Если это нетерминальный символ, формируем его
представление в зависимости от номера правила }
if SymbType = SYMB_SYNT then
Result:= MakeSymbolStr(iRuleNum)
{ Если это терминальный символ, формируем его
представление в соответствии с типом лексемы }
else Result:= Lexem.LexInfoStr;
end;
destructor TSymbol.Destroy;
{ Деструктор для удаления символа }
var i: integer;
begin
if SymbInfo.SymbType = SYMB_SYNT then
with SymbInfo.LexList do
begin { Если это нетерминальный символ, }
{ удаляем все его исходные символы из списка }
for i:=Count-1 downto 0 do TSymbol(Items[i]). Free;
Free; { Удаляем сам список символов }
end;
inherited Destroy; { Вызываем деструктор базового класа }
end;
destructor TSymbStack.Destroy;