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

Обратите внимание, как в лексическом анализаторе реализован метод Number. Рассмотрим выражение "1е*5". В калькуляторе без лексического анализатора функция Number, дойдя до символа "*" выдавала исключение, т. к. ожидала увидеть здесь знак "+", или число. Но лексический анализатор не должен брать на себя такую ответственность — поиск синтаксических ошибок. Поэтому в данном случае он должен, дойдя до непонятного символа в конструкции, которую он счел за экспоненту, откатиться назад, выделить из строки лексему "1" и продолжить выделение лексем с символа "е". В результате список лексем будет выглядеть так: "1, "е", "*", "5". И уже синтаксический анализатор должен потом разобраться, допустима ли такая последовательность лексем или нет.

Отметим, что для нашей грамматики непринципиально, зафиксирует ли в таком выражении ошибку лексический или синтаксический анализатор. Но в общем случае может существовать грамматика, в которой такое выражение допустимо, поэтому лексический анализатор должен действовать именно так, т. е. выполнять откат, если попытка выделить число зашла на каком-то этапе в тупик (самый простой пример — наличие в языке бинарного оператора, начинающегося с символа "е" — тогда пользователь сможет написать этот оператор после числа без пробела, и чтобы справиться с такой ситуацией, понадобится откат). Функция Number вызывается из ExtractLexeme только в том случае, когда в начале лексемы встречается цифра, а с цифры может начинаться только лексема ltNumber. Таким образом, сам факт вызова функции Number говорит о том, что в строке гарантированно обнаружена подстрока (состоящая, по крайней мере, из одного символа), которая является числом. Функции синтаксического анализатора очень похожи на аналогичные функции из предыдущих примеров, за исключением того, что работают не со строкой, а со списком лексем. Поэтому мы приведем здесь только одну из них — функцию Term (листинг 4.13).

Листинг 4.13. Пример функции, использующей лексический анализатор

const

 Operator2 = (ltAsterisk, ltSlash, ltDiv, ltMod, ltAnd);

function Term(LexicalAnalyzer: TLexicalAnalyzer): Extended;

var

 Operator: TLexemeType;

begin

 Result:= Factor(LexicalAnalyzer);

 while LexicalAnalyzer.Lexeme.LexemeType in Operator2 do

 begin

Operator:= LexicalAnalyzer.Lexeme.LexemeType;

 LexicalAnalyzer.Next;

case Operator of

ltAsterisk: Result:= Result * Factor(LexicalAnalyzer);

 ltSlash: Result:= Result / Factor(LexicalAnalyzer);

 ltDiv: Result:= Trunc(Result) div Trunc(Factor(LexicalAnalyzer));

 ltMod: Result:= Trunc(Result) mod Trunc(Factor(LexicalAnalyzer));

 ltAnd: Result:= Trunc(Result) and Trunc(Factor(LexicalAnalyzer));

end;

 end;

end;

Если сравнить этот вариант Term с аналогичной функцией из листинга 42, легко заметить их сходство.

Использование лексического анализатора может повысить скорость многократного вычисления одного выражения при разных значениях входящих в него переменных (например, при построении графика функции, ввезенной пользователем). Действительно, лексический анализ в этом случае достаточно выполнить один раз, а потом пользоваться готовым списком. Можно сделать такие операции еще более эффективными, переложив вычисление числовых констант на лексический анализатор. Для этого в структуру TLexeme нужно добавить поле Number типа Extended и модифицировать метод Number таким образом, чтобы он сразу преобразовывал выделенную подстроку в число. Тогда дорогостоящий вызов функции StrToFloat будет перенесен из многократно повторяющейся функции Base в однократно выполняемый метод TLexicalAnalyzer.Number. Но самое радикальное средство повышения производительности — переделка синтаксического анализатора таким образом, чтобы он не вычислял выражение самостоятельно, а формировал машинный код для его вычисления. Однако написание компилятора математических выражений выходит за рамки данной книги.

<p>4.9. Однопроходный калькулятор и функции с несколькими переменными</p>
Перейти на страницу:

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

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

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

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

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

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

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

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