如何为有效数字指定DCG?

时间:2015-09-30 16:14:08

标签: prolog 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 }.

这两种方法都不起作用,而且看起来也很糟糕(对不起,对Prolog很新,并试图学习最佳实践)。

我将如何构建此DCG /谓词来验证它是否为数字?

2 个答案:

答案 0 :(得分:5)

我给你一个描述自然数字的代码示例:

:- set_prolog_flag(double_quotes, chars).

natural_number(N) --> number_(Cs), { number_codes(N, Cs) }.

number_([D|Ds]) --> digit(D), number_(Ds).
number_([D])    --> digit(D).

digit(D) --> [D], { char_type(D, digit) }.

使用示例:

?- phrase(natural_number(N), "123").
N = 123 ;
false.

我将其作为练习将其概括为其他数字。

答案 1 :(得分:3)

以下是数字文字的ABNF grammar,例如您可能会在计算机语言中找到的文字:

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'] .