Читаем О чём не пишут в книгах по Delphi полностью

В предыдущем примере выражение сначала от начала до конца просматривается лексическим анализатором и переводится в иную форму (список лексем). Затем этот список обрабатывается синтаксическим анализатором. Таким образом, калькулятор получается двухпроходным, хотя из синтаксиса и семантики выражения необходимость нескольких проходов не вытекает. Попробуем переделать его так, чтобы он стал однопроходным.

Примечание

В некоторых языках многопроходность — обязательное требование к реализации компилятора. Например, в языке C++ реализацию функций класса можно вставлять в само описание класса. При этом внутри этих функций можно обращаться к тем полям и функциям класса, которые объявлены ниже. Таким образом, откомпилировать подобный код может только компилятор как минимум с двумя проходами, чтобы на первом проходе можно было найти все поля класса, а на втором — откомпилировать функции класса.

В предыдущей реализации калькулятора синтаксический анализатор работал с лексическим через процедуру Next и свойство Lexeme: процедура Next передвигала текущую позицию в списке лексем, а свойство Lexeme давало доступ к текущей лексеме. Легко видеть, что при таком алгоритме лексическому анализатору нет необходимости хранить полный список лексем, достаточно помнить текущую, а при вызове Next анализировать очередную часть строки, выделяя из нее следующую лексему и делая ее текущей. Таким образом, синтаксический и лексический анализаторы будут работать по очереди, обрабатывая каждый по одной лексеме.

В реализации лексического анализатора требуются следующие изменения. Во-первых, теперь конструктор не запускает полный цикл лексического анализа, а только сохраняет переданную строку и выделяет из нее первую лексему. Во-вторых, выражение и позиция в выражении теперь должны сохраняться между вызовами методов лексического анализатора и поэтому становятся полями этого класса. В-третьих, метод Next теперь выполняет выделение очередной лексемы, которую помещает в специально созданное для этого поле, а свойство Lexeme возвращает указатель на это поле, а не на элемент списка. Остальные функции лексического анализатора изменились только в том отношении, что теперь выражение и указатель на позицию в строке получают не через параметры, а напрямую обращаются к соответствующим полям.

Пример однопроходного калькулятора с лексическим анализатором находится на компакт-диске в папке SinglePassSample. В листинге 4.14 показан код той части нового варианта класса TLexicalAnalyzer, которую понадобилось изменить, чтобы обеспечить однопроходность.

Листинг 4.14. Однопроходный вариант класса TLexicalAnalyzer

type

 TLexicalAnalyzer = class

 private

 // Выражение для вычисления

 FExpr: string;

 // Текущая позиция

 FP: Integer;

 // Текущая лексема

 FCurrLexeme: TLexeme;

 function GetLexeme: PLexeme;

procedure SkipWhiteSpace;

 procedure ExtractLexeme;

 procedure PutLexeme(LexemeType: TLexemeType; Pos: Integer; const Lexeme: string);

procedure Number;

 procedure Word;

 public

constructor Create(const Expr: string);

 procedure Next;

property Lexeme: PLexeme read GetLexeme;

 end;

constructor TLexicalAnalyzer.Create(const Expr: string);

begin

 inherited Create;

 FP:= 1;

 FExpr:= Expr;

 Next;

end;

// Получение указателя на текущую лексему

function TLexicalAnalyzer.GetLexeme: PLexeme;

begin

 Result:= @FCurrLexeme;

end;

// Получение следующей лексемы

procedure TLexicalAnalyzer.Next;

begin

 if FP <= Length(FExpr) then

 begin

SkipWhiteSpace;

 ExtractLexeme;

 end

 else PutLexeme(ltEnd, FP, '');

end;

// Замещение текущей лексемы новой лексемой

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных