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

на главную

Жанры

О чём не пишут в книгах по 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
, которые придется в этом случае модифицировать, видно, что переделка будет достаточно сложной.

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

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

Черный Маг Императора 13

Герда Александр
13. Черный маг императора
Фантастика:
попаданцы
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Черный Маг Императора 13

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Маяк надежды

Кас Маркус
5. Артефактор
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Маяк надежды

Великий перелом

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

Сопротивляйся мне

Вечная Ольга
3. Порочная власть
Любовные романы:
современные любовные романы
эро литература
6.00
рейтинг книги
Сопротивляйся мне

Инквизитор Тьмы 2

Шмаков Алексей Семенович
2. Инквизитор Тьмы
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Инквизитор Тьмы 2

Мастер Разума V

Кронос Александр
5. Мастер Разума
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Мастер Разума V

Бандит 2

Щепетнов Евгений Владимирович
2. Петр Синельников
Фантастика:
боевая фантастика
5.73
рейтинг книги
Бандит 2

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Падение Твердыни

Распопов Дмитрий Викторович
6. Венецианский купец
Фантастика:
попаданцы
альтернативная история
5.33
рейтинг книги
Падение Твердыни

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Ох уж этот Мин Джин Хо 2

Кронос Александр
2. Мин Джин Хо
Фантастика:
попаданцы
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 2

Энфис 6

Кронос Александр
6. Эрра
Фантастика:
героическая фантастика
рпг
аниме
5.00
рейтинг книги
Энфис 6