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;
{ Деструктор для удаления синтаксического стека }
begin
Clear; { Очищаем стек }
inherited Destroy; { Вызываем деструктор базового класа }
end;
procedure TSymbStack.Clear;
{ Функция очистки синтаксического стека }
var i: integer;
begin { Удаляем все символы из стека }
for i:=Count-1 downto 0 do TSymbol(Items[i]). Free;
inherited Clear; { Вызываем функцию базового класса }
end;
function TSymbStack.GetSymbol(iIdx: integer): TSymbol;
{ Функция выборки символа по номеру от вершины стека }
begin Result:= TSymbol(Items[iIdx]); end;
function TSymbStack.TopLexem: TLexem;
{ Функция, возвращающая самую верхнюю лексему в стеке }
var i: integer;
begin
Result:= nil; { Начальный результат функции пустой }
for i:=Count-1 downto 0 do{Для символов от вершины стека}
if Symbols[i].SymbType = SYMB_LEX then
begin { Если это терминальный символ }
Result:= Symbols[i].Lexem; {Берем ссылку на лексему}
Break; { Прекращаем поиск }
end;
end;
function TSymbStack.Push(lex: TLexem): TSymbol;
{ Функция помещения лексемы в синтаксический стек }
begin { Создаем новый терминальный символ }
Result:= TSymbol.CreateLex(lex);
Add(Result); { Добавляем его в стек }
end;
function TSymbStack.MakeTopSymb: TSymbol;
{ Функция, выполняющая свертку. Результат функции:
nil – если не удалось выполнить свертку, иначе – ссылка
на новый нетерминальный символ (если свертка выполнена).}
var
symCur: TSymbol; {Текущий символ стека}
SymbArr: TSymbArray;{Массив хранения символов правила}
i,iSymbN: integer;{Счетчики символов в стеке и в правиле}
sRuleStr: string; {Строковое представление правила}
{ Функция добавления символа в правило }
procedure AddToRule(const sStr: string;{Строка символа}
sym: TSymbol{Тек. символ});
begin
symCur:= sym; { Устанавливаем ссылку на текущий символ }
{ Добавляем очередной символ в массив символов правила }
SymbArr[iSymbN]:= Symbols[i];
{ Добавляем его в строку правила (слева!) }
sRuleStr:= sStr + sRuleStr;
Delete(i); { Удаляем символ из стека }
Inc(iSymbN); { Увеличиваем счетчик символов в правиле }
end;
begin
Result:= nil; { Сначала обнуляем результат функции }
iSymbN:= 0; { Сбрасываем счетчик символов }
symCur:= nil; { Обнуляем текущий символ }
sRuleStr:= ; { Сначала строка правила пустая }
for i:=Count-1 downto 0 do{ Выполняем алгоритм }
begin { Для всех символов начиная с вершины стека }
if Symbols[i].SymbType = SYMB_SYNT then
{ Если это нетерминальный символ, то добавляем его
в правило, текущий символ при этом не меняется }
AddToRule(Symbols[i].SymbolStr,symCur)
else { Если это терминальный символ }
if symCur = nil then {и текущий символ пустой }
{ Добавляем его в правило и делаем текущим }
AddToRule(LexTypeInfo(Symbols[i].Lexem.LexType),
Symbols[i])
else { Если это терминальный символ и он связан
отношением "=" с текущим символом }
if GramMatrix[Symbols[i].Lexem.LexType,
symCur.Lexem.LexType] = = then
{ Добавляем его в правило и делаем текущим }
AddToRule(LexTypeInfo(Symbols[i].Lexem.LexType),
Symbols[i])
else { Иначе – прерываем цикл, дальше искать не нужно }
Break;
if iSymbN > RULE_LENGTH then Break; { Если превышена
максимальная длина правила, цикл прекращаем }
end;
if iSymbN <> 0 then
begin { Если выбран хотя бы один символ из стека, то
ищем простым перебором правило, у которого строковое
представление совпадает с построенной строкой }
Читать дальше
Конец ознакомительного отрывка
Купить книгу