var
P: Integer; // Номер символа выражения, который сейчас проверяется
begin
Result:= False;
// Проверка, что выражение содержит хотя бы один символ — пустая строка
// не является числом
if Length(S) = 0 then Exit;
// Начинаем проверку с первого символа
Р:= 1;
// Если первый символ —
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;
// Если следующей символ —
// стоит хотя бы одна цифра
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;
// Если следующий символ —
// стоит все то, что требуется правилами
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;
Для каждого нетерминального символа мы ввели отдельную функцию, разбор начинается с символа самого верхнего уровня —
— и следует правилам, записанным для этого символа. Такой способ синтаксического анализа называется
Пример использования функции IsNumber
содержится на компакт-диске и называется IsNumberSample.
В заключение рассмотрим альтернативный способ записи грамматики вещественного числа — графический (такой способ называется синтаксическим графом, или рельсовой диаграммой). Это направленный граф, узлами которого являются терминальные (круги) и нетерминальные (прямоугольники) символы. Двигаться от одного узла к другому можно только по линиям в направлениях, указанных стрелками. В таком графе достаточно легко разобраться, а по возможностям описания синтаксиса он эквивалентен БНФ. На рис. 4.1 показана запись синтаксиса вещественного числа с помощью рельсовой диаграммы.
Рис. 4.1. Диаграмма синтаксиса вещественного числа
В качестве самостоятельного упражнения рекомендуем нарисовать с помощью рельсовой диаграммы грамматику символа "Цифра", используемого на рис. 4.1.
4.4. Простой калькулятор