Чтение онлайн

на главную

Жанры

О чём не пишут в книгах по Delphi

Григорьев Антон Борисович

Шрифт:

if (Р > Length(S)) or (S[P] <> ')') then

raise ESyntaxError.Create(

'Ожидается ")" в позиции ' + IntToStr(P));

Inc(P);

 end

 // если скобки нет - переменная

 else

 begin

VarValue := Form1.ListBoxVars.Items.Values[IDStr];

if VarValue = '' then

raise ESyntaxError.Create(

'Необъявленная переменная ' + IDStr +

'
в позиции ' + IntToStr(P))

elsе Result := StrToFloat(VarValue);

 end;

end;

// Выделение подстроки, соответствующей <Base>,

// и ее вычисление

function Base(const S: string; var P: Integer): Extended;

begin

 if P > Length(S) then

raise ESyntaxError.Create('Неожиданный конец строки');

 // По первому символу подстроки определяем,

 // какое это основание

 case S[P] of

 '(': // выражение в скобках

 begin

Inc(Р);

Result := Expr(S, Р);

// Проверяем, что скобка закрыта

if (Р > Length(S)) or (S[P) <> ')') then

raise ESyntaxError.Create(

'Ожидается ")" в позиции ' + IntToStr(Р));

Inc(Р);

 end;

'0'..'9': // Числовая константа

Result := Number(S, P);

 'A'..'Z', 'a'..'z', '_': // Идентификатор (переменная или функция)

Result := Identifier(S, P);

 else

raise ESyntaxError.Create(

'Некорректный символ в позиции ' + IntToStr(Р));

 end;

end;

// Выделение подстроки, соответствующей <Factor>,

// и ее вычисление

function Factor(const S: string; var P: Integer): Extended;

begin

 if P > Length(S) then

raise ESyntaxError.Create('Неожиданный конец строки');

 // По первому символу подстроки определяем,

 // какой это множитель

 case S[P] of

 '+'; // унарный "+"

 begin

Inc(Р);

Result := Factor(S, P);

 end;

 '-': // унарный "-"

 begin

Inc(P);

Result := -Factor(S, P);

 end;

 else

 begin

Result := Base(S, P); 

if (P <= Length(S)) and (S[P] = '^') then

begin

Inc(P);

Result := Power(Result, Factor(S, P));

end;

 end;

 end;

end;

Пример

калькулятора называется FullCalcSample. Его интерфейс (рис. 4.2) содержит новые элементы, с помощью которых пользователь может задавать значения переменных. В левой нижней части окна находится список переменных с их значениями (при запуске программы этот список пустой). Правее расположены поля ввода Имя переменной и Значение переменной, а также кнопка Установить. В первое поле следует ввести имя переменной, во второе — ее значение. При нажатии на кнопку Установить переменная будет внесена в список, а если переменная с таким именем уже есть в списке, то ее значение будет обновлено. Все переменные, которые есть в списке, могут использоваться в выражении. Если требуемая переменная в списке не найдена, попытка вычислить выражение приводит к ошибке.

Рис. 4.2. Главное окно программы FullCalcSample

Заметим, что символ

<Factor>
можно было бы определить несколько иначе:

<Factor> ::= [<UnaryOp>] <Base> ['^' <Factor>]

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

4.8. Калькулятор с лексическим анализатором

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

Number
, но в функции
Base
также содержится проверка первого символа числа. Функция
Identifier
тоже частично дублируется функцией
Base
.

Второй недостаток — нельзя вставлять разделители, облегчающие чтение выражения. Например, строка "2 + 2" не является допустимым выражением — следует писать "2+2" (без пробелов). Если же попытаться учесть возможность вставки пробелов, придется в разные функции добавлять много однотипного рутинного кода, который существенно усложнит восприятие программы.

Третий недостаток — сложность введения новых операторов, которые обозначаются не одним символом, а несколькими, например,

>=
,
and
,
div
. Если посмотреть функции
Expr
и
Term
, которые придется в этом случае модифицировать, видно, что переделка будет достаточно сложной.

Решить все эти проблемы позволяет лексический анализатор, который выделяет из строки все лексемы, пропуская пробелы и иные разделители, и определяет тип каждой лексемы, не заботясь о том, насколько уместно ее появление в данной позиции выражения. А после лексического анализа начинает работать анализатор синтаксический, который будет иметь дело не с отдельными символами строки, а с целыми лексемами

Поделиться:
Популярные книги

На границе тучи ходят хмуро...

Кулаков Алексей Иванович
1. Александр Агренев
Фантастика:
альтернативная история
9.28
рейтинг книги
На границе тучи ходят хмуро...

Кодекс Охотника. Книга III

Винокуров Юрий
3. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
7.00
рейтинг книги
Кодекс Охотника. Книга III

Последний попаданец 11. Финал. Часть 1

Зубов Константин
11. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 11. Финал. Часть 1

Книга пяти колец

Зайцев Константин
1. Книга пяти колец
Фантастика:
фэнтези
6.00
рейтинг книги
Книга пяти колец

Поступь Империи

Ланцов Михаил Алексеевич
7. Сын Петра
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Поступь Империи

Купидон с топором

Юнина Наталья
Любовные романы:
современные любовные романы
7.67
рейтинг книги
Купидон с топором

Наследник в Зеркальной Маске

Тарс Элиан
8. Десять Принцев Российской Империи
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наследник в Зеркальной Маске

Совок 5

Агарев Вадим
5. Совок
Фантастика:
детективная фантастика
попаданцы
альтернативная история
6.20
рейтинг книги
Совок 5

Аномальный наследник. Том 1 и Том 2

Тарс Элиан
1. Аномальный наследник
Фантастика:
боевая фантастика
альтернативная история
8.50
рейтинг книги
Аномальный наследник. Том 1 и Том 2

Теневой путь. Шаг в тень

Мазуров Дмитрий
1. Теневой путь
Фантастика:
фэнтези
6.71
рейтинг книги
Теневой путь. Шаг в тень

Попаданка в академии драконов 2

Свадьбина Любовь
2. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
6.95
рейтинг книги
Попаданка в академии драконов 2

Гром над Империей. Часть 2

Машуков Тимур
6. Гром над миром
Фантастика:
фэнтези
попаданцы
5.25
рейтинг книги
Гром над Империей. Часть 2

Ритуал для призыва профессора

Лунёва Мария
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Ритуал для призыва профессора

Измена. Осколки чувств

Верди Алиса
2. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Осколки чувств