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

на главную - закладки

Жанры

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

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

Шрифт:

function IsDigit(Ch: Char): Boolean;

begin

 Result := Ch in ['0'..'9'];

end;

// Проверка символа на соответствие <Sign>

function IsSign(Ch: Char): Boolean;

begin

 Result := (Ch = '+') or (Ch = '-');

end;

// Проверка символа на соответствие <Separator>

function IsSeparator(Ch: Char): Boolean;

begin

 Result := Ch='.';

end;

//
Проверка символа на соответствие <Exponent>

function IsExponent(Ch: Char): Boolean;

begin

 Result := (Ch = 'E') or (Ch = 'e');

end;

function IsNumber(const S: string): Boolean;

var

 P: Integer; // Номер символа выражения, который сейчас проверяется

begin

 Result := False;

 // Проверка, что выражение содержит хотя бы один символ — пустая строка

 // не является числом

 if Length(S) = 0 then Exit;

 // Начинаем проверку с первого символа

 Р := 1;

 // Если первый символ — <Sign>, переходим к следующему

 if IsSign(S[Р]) then Inc(Р);

 // Проверяем, что в данной позиции стоит хотя бы одна цифра

 if (Р > Length(S)) or not IsDigit(S[Р]) then Exit;

 // Переходим к следующей позиции, пока не достигнем конца строки

 // или не встретим не цифру

 repeat

Inc(Р);

 until (Р > Length(S)) or not IsDigit(S[Р]);

 // Если достигли конца строки, выражение корректно — число.

 // не имеющее дробной части и экспоненты

 if Р > Length(S) then

 begin

Result := True;

Exit;

 end;

 // Если следующей символ — <Separator>, проверяем, что после него

 // стоит хотя бы одна цифра

 if IsSeparator(S[P]) then

 begin

Inc(P);

if (P > Length(S)) or not IsDigit(S[P]) then Exit;

repeat

Inc(P);

until (P > Length(S)) or not IsDigit(S[P]);

// Если достигли конца строки, выражение корректно — число

// без экспоненты

if Р > Length(S) then

begin

Result := True;

Exit;

end;

 end;

 //
Если следующий символ — <Exponent>, проверяем, что после него

 // стоит все то, что требуется правилами

 if IsExponent(S[Р]) then

 begin

Inc(P);

if P > Length(S) then Exit;

if IsSign(S[P]) then Inc(P);

if (P > Length(S)) or not IsDigit(S[P]) then Exit;

repeat

Inc(P);

until (P > Length(S)) or not IsDigit(S[P]);

if P > Length(S) then

begin

Result := True;

Exit;

end;

 end;

 // Если выполнение дошло до этого места, значит, в выражении остались

 // еще какие-то символы. Так как никакие дополнительные символы

 // синтаксисом не предусмотрены, такое выражение не считается

 // корректным числом.

end;

Для каждого нетерминального символа мы ввели отдельную функцию, разбор начинается с символа самого верхнего уровня —

<Number>
— и следует правилам, записанным для этого символа. Такой способ синтаксического анализа называется левосторонним рекурсивным нисходящим анализом. Левосторонним потому, что символы в выражении перебираются слева направо, нисходящим — потому, что сначала анализируются символы верхнего уровня, а потом — символы нижнего. Рекурсивность метода на данном примере не видна, т. к. наша грамматика не содержит рекурсивных определений, но мы с этим столкнемся в последующих примерах.

Пример использования функции

IsNumber
содержится на компакт-диске и называется IsNumberSample.

В заключение рассмотрим альтернативный способ записи грамматики вещественного числа — графический (такой способ называется синтаксическим графом, или рельсовой диаграммой). Это направленный граф, узлами которого являются терминальные (круги) и нетерминальные (прямоугольники) символы. Двигаться от одного узла к другому можно только по линиям в направлениях, указанных стрелками. В таком графе достаточно легко разобраться, а по возможностям описания синтаксиса он эквивалентен БНФ. На рис. 4.1 показана запись синтаксиса вещественного числа с помощью рельсовой диаграммы.

Рис. 4.1. Диаграмма синтаксиса вещественного числа

В качестве самостоятельного упражнения рекомендуем нарисовать с помощью рельсовой диаграммы грамматику символа "Цифра", используемого на рис. 4.1.

4.4. Простой калькулятор

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

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

Черный дембель. Часть 5

Федин Андрей Анатольевич
5. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Черный дембель. Часть 5

30 сребреников

Распопов Дмитрий Викторович
1. 30 сребреников
Фантастика:
попаданцы
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
30 сребреников

Жребий некроманта 2

Решетов Евгений Валерьевич
2. Жребий некроманта
Фантастика:
боевая фантастика
6.87
рейтинг книги
Жребий некроманта 2

Охота на разведенку

Зайцева Мария
Любовные романы:
современные любовные романы
эро литература
6.76
рейтинг книги
Охота на разведенку

Чужбина

Седой Василий
2. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чужбина

Возвышение Меркурия. Книга 4

Кронос Александр
4. Меркурий
Фантастика:
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Возвышение Меркурия. Книга 4

Надуй щеки! Том 3

Вишневский Сергей Викторович
3. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки! Том 3

Идеальный мир для Лекаря 16

Сапфир Олег
16. Лекарь
Фантастика:
боевая фантастика
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 16

По воле короля

Леви Кира
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
По воле короля

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9

Штуцер и тесак

Дроздов Анатолий Федорович
1. Штуцер и тесак
Фантастика:
боевая фантастика
альтернативная история
8.78
рейтинг книги
Штуцер и тесак

Камень Книга седьмая

Минин Станислав
7. Камень
Фантастика:
фэнтези
боевая фантастика
6.22
рейтинг книги
Камень Книга седьмая

Хозяйка дома в «Гиблых Пределах»

Нова Юлия
Любовные романы:
любовно-фантастические романы
5.75
рейтинг книги
Хозяйка дома в «Гиблых Пределах»