Как мне указать DCG для действительного номера?
Я пытаюсь указать DCG для действительного числа, которое будет использоваться следующим образом:
value(Number) --> valid_number(Number).
В основном, проверка, является ли указанное значение числовым (это также может быть переменная, поэтому необходимо проверить).
Я не знаю как это построить valid_number
DCG/ предикат, хотя.
Прямо сейчас у меня просто есть:
valid_number('1') --> ['1'].
valid_number('2') --> ['2'].
...
Который работает, но это, очевидно, ужасно. Попытка что-то вроде:
valid_number(Number) --> { integer(Number), Number = Number }.
И то, и другое не работает и, по общему признанию, выглядит довольно грубо (извините, я новичок в Прологе и пытаюсь изучить лучшие практики)
Как бы я начал создавать этот DCG/ предикат, который проверяет, является ли он числом?
2 ответа
Я даю вам пример кода, который описывает натуральные числа:
: - set_prolog_flag (двойные кавычки, символы). натуральный номер (N) -> число_(Cs), {число_кодов (N, Cs) }. число _([D|Ds]) -> цифра (D), число_ (Ds). номер _([D]) -> цифра (D). цифра (D) -> [D], {тип_значения (D, цифра)}.
Пример использования:
?- phrase(natural_number(N), "123").
N = 123 ;
false.
Я оставляю обобщение этого на другие числа в качестве упражнения.
Вот грамматика ABNF для числового литерала, такого как вы можете найти на компьютерном языке:
NUMERIC-CONSTANT = INTEGER-PART 0*1(FRACTIONAL-PART) 0*1(EXPONENT)
INTEGER-PART = 0*1(SIGN) 1*(DIGIT)
FRACTIONAL-PART = 0*1( DECIMAL-POINT 1*(DIGIT) )
EXPONENT = EXP 0*1(SIGN) 1*(DIGIT)
EXP = "E" / "e"
DECIMAL-POINT = "."
SIGN = "+" / "-"
DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"
Так как в этой грамматике нет левой рекурсии, она поддается непосредственно анализатору рекурсивного спуска, например, производимому Prolog DCG:
numeric_constant --> integer , optional_fraction , optional_exponent .
integer --> optional_sign , digits .
optional_sign --> sign .
optional_sign --> [].
digits --> digit , digits .
optional_fraction --> fraction .
optional_fraction --> [].
fraction --> decimal_point , digits .
optional_exponent --> exponent .
optional_exponent --> [].
exponent --> exp , optional_sign , digits .
exp --> ['E'] .
exp --> ['e'] .
decimal_point --> ['.'] .
sign --> ['+'] .
sign --> ['-'] .
digit --> ['0'] .
digit --> ['1'] .
digit --> ['2'] .
digit --> ['3'] .
digit --> ['4'] .
digit --> ['5'] .
digit --> ['6'] .
digit --> ['7'] .
digit --> ['8'] .
digit --> ['9'] .