Fixed number parsing

This commit is contained in:
Hugo Sales 2018-12-20 21:38:46 +00:00
parent d054989bc0
commit 1232fa0b3c

View File

@ -445,100 +445,100 @@ parse_number_explicit(_, T, T, [], []) :-
% Parse a floating point number % Parse a floating point number
% %
parse_floating_number(N) --> parse_floating_number(N) -->
{
not(compound(N))
},
[N], [N],
{ { number(N) }.
% Assert it must be between negative and positive infinity
% This uses the CLPR library, which makes this reversible,
% whereas `number(N)` is always false, since it only succeeds
% if the argument is bound (to a integer or float)
(N >= 0; N < 0)
}.
parse_floating_number(op('.', TL, TR)) --> parse_floating_number(op('.', TL, TR)) -->
%% A float is a node with a dot as the operator %% A float is a node with a dot as the operator
%% If there's a number on the left %% If there's a number on the left
parse_number(TL), parse_integer_number(TL),
%% Followed by either point or dot %% Followed by either point or dot
[RadixPoint], [Sep],
{ {
member(RadixPoint, [point, dot]), member(Sep, [point, dot]),
! !
}, },
%% Followed by another number %% Followed by another number
parse_positive_number(TR). parse_positive_integer_number(TR).
parse_floating_number(TN) -->
%% Or any integer
parse_integer_number(TN).
%% Tests:
%% ?- parse_floating_number(TN, [two], _).
%@ TN = 2.
%% ?- parse_floating_number(TN, [two, dot, 4], _).
%@ TN = op('.', 2, 4).
%% ?- parse_floating_number(TN, [negative, two, dot, 4], _).
%@ TN = op('.', op(neg, 2), 4).
%% parse_positive_number(-tree, +stream, -not_consumed) is det %% parse_positive_integer_number(-tree, +stream, -not_consumed) is det
% %
% Parse an positive integer number % Parse an positive integer number
% %
parse_positive_number(N) --> parse_positive_integer_number(N) -->
[N], [N],
{ {
not(compound(N)), integer(N),
%% CLPFD, a number between 0 and infinity %% CLPFD, a number greater than 0
N in 0..sup, ! N #>= 1, !
}. }.
parse_positive_number(T) --> parse_positive_integer_number(T) -->
parse_number_explicit(void, void, T). parse_number_explicit(void, void, T).
%% parse_number(-tree, +stream, -not_consumed) is det %% parse_integer_number(-tree, +stream, -not_consumed) is det
% %
% Parse an integer number % Parse an integer number
% %
parse_number(N) --> parse_integer_number(N) -->
[N], [N],
%% CLPFD, a number between negative infinity and positive infinity { integer(N), ! }.
{ N in inf..sup, ! }. parse_integer_number(op(neg, T)) --> % TODO
parse_number(op(neg, T)) --> % TODO %% A number can start with "negative", to negate it
%% A number can start with negative, to negate it
[negative], [negative],
parse_number_explicit(void, void, T). parse_number_explicit(void, void, T).
parse_number(T) --> parse_integer_number(T) -->
parse_number_explicit(void, void, T). parse_number_explicit(void, void, T).
%% Tests: %% Tests:
%% ?- parse_number(T, [two], _). %% ?- parse_integer_number(T, [two], _).
%@ T = 2. %@ T = 2.
%% ?- parse_number(T, [43], _). %% ?- parse_integer_number(T, [43], _).
%@ T = 43. %@ T = 43.
%% ?- parse_number(T, [nineteen, two], _). %% ?- parse_integer_number(T, [nineteen, two], _).
%@ false. %@ false.
%% ?- parse_number(T, [twenty], _). %% ?- parse_integer_number(T, [twenty], _).
%@ T = 20. %@ T = 20.
%% ?- parse_number(T, [twenty, point, two], NC). %% ?- parse_integer_number(T, [twenty, point, two], NC).
%@ T = op('.', 20, 2), %@ T = op('.', 20, 2),
%@ NC = []. %@ NC = [].
%% ?- parse_number(T, [twenty, twenty], _). %% ?- parse_integer_number(T, [twenty, twenty], _).
%@ false. %@ false.
%% ?- parse_number(T, [twenty, one], _). %% ?- parse_integer_number(T, [twenty, one], _).
%@ T = op(+, 20, 1). %@ T = op(+, 20, 1).
%% ?- parse_number(T, [negative, one, hundred], _). %% ?- parse_integer_number(T, [negative, one, hundred], _).
%@ T = op(neg, op(*, 1, 100)) ; %@ T = op(neg, op(*, 1, 100)) ;
%@ false. %@ false.
%% ?- parse_number(T, [three, hundred], _). %% ?- parse_integer_number(T, [three, hundred], _).
%@ T = op(*, 3, 100). %@ T = op(*, 3, 100).
%% ?- parse_number(T, [twenty, hundred], _). %% ?- parse_integer_number(T, [twenty, hundred], _).
%@ T = op(*, 20, 100). %@ T = op(*, 20, 100).
%% ?- parse_number(T, [twenty, one, hundred], _). %% ?- parse_integer_number(T, [twenty, one, hundred], _).
%@ T = op(*, op(+, 20, 1), 100). %@ T = op(*, op(+, 20, 1), 100).
%% ?- parse_number(T, [two, hundred, and, one], _). %% ?- parse_integer_number(T, [two, hundred, and, one], _).
%@ T = op(+, op(*, 2, 100), 1). %@ T = op(+, op(*, 2, 100), 1).
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one], _). %% ?- parse_integer_number(T, [twenty, one, hundred, and, twenty, one], _).
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1). %@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1).
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC). %% ?- parse_integer_number(T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC).
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1), %@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1),
%@ NC = [foo, bar, blah]. %@ NC = [foo, bar, blah].
%% ?- parse_number(T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC). %% ?- parse_integer_number(T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC).
%@ T = op(*, op(+, 20, 1), 100), %@ T = op(*, op(+, 20, 1), 100),
%@ NC = [and, bleg, twenty, quux, one, foo, bar]. %@ NC = [and, bleg, twenty, quux, one, foo, bar].
%% ?- parse_number(T, [two, hundred, thousand], _). %% ?- parse_integer_number(T, [two, hundred, thousand], _).
%@ T = op(*, op(*, 2, 100), 1000). %@ T = op(*, op(*, 2, 100), 1000).
%% ?- parse_number(T, [twenty, one, hundred, thousand], _). %% ?- parse_integer_number(T, [twenty, one, hundred, thousand], _).
%@ T = op(*, op(*, op(+, 20, 1), 100), 1000). %@ T = op(*, op(*, op(+, 20, 1), 100), 1000).
%% ?- parse_number(T, [thirty, five, million, five, hundred, thirty, four], _). %% ?- parse_integer_number(T, [thirty, five, million, five, hundred, thirty, four], _).
%@ T = op(+, op(+, op(*, op(+, op(*, op(+, 30, 5), 1000000), 5), 100), 30), 4). %@ T = op(+, op(+, op(*, op(+, op(*, op(+, 30, 5), 1000000), 5), 100), 30), 4).
%% ?- parse_number(T, [foo, five, million], NC). %% ?- parse_integer_number(T, [foo, five, million], NC).
%@ false. %@ false.
%% nlp_parse_power(?List, ?List) is det %% nlp_parse_power(?List, ?List) is det
@ -554,7 +554,7 @@ parse_power(op(^, TB, 3)) -->
parse_power(op(^, TB, TN)) --> parse_power(op(^, TB, TN)) -->
parse_polynomial_variable(TB), parse_polynomial_variable(TB),
[raised, to], [raised, to],
parse_positive_number(TN). parse_positive_integer_number(TN).
parse_power(TB) --> parse_power(TB) -->
parse_polynomial_variable(TB). parse_polynomial_variable(TB).