% Nombres avec plusieurs digit et point décimal

expr(Z) --> term(X), "+", expr(Y), {Z is X + Y}.
expr(Z) --> term(X), "-", expr(Y), {Z is X - Y}.
expr(X) --> term(X).

term(Z) --> number(X), "*", term(Y), {Z is X * Y}.
term(Z) --> number(X), "/", term(Y), {Y \=0, Z is X / Y}.
term(Z) --> number(Z).

number(C) --> "+", numberNS(C).
number(C) --> "-", numberNS(X),{C is -X}.
number(C) -->  numberNS(C).

numberNS(C) -->  digits(C1,_), ".",  digits(C2,B),
                         {C is C1 + C2/(B*10) } .
numberNS(C) -->  digits(C,_).

 digits(V,B)  --> digit(X), digits(C,B0),
                {B is 10*B0, V is X*B +C}.
digits(C,1) --> digit(C).

digit(X) --> [C], {"0" =< C, C =< "9", X is C - "0"}.

/*

?-  expr(Z,"-2+3*5+11",[]).

Z = 24 ? ;

no
| ?-  expr(Z,"-222+3*5+11",[]).

Z = -196 ? ;

no
| ?-  expr(Z,"-22.2+0.2+11*0.5",[]).

Z = -16.5 ? 
no

 ?-  expr(Z,"-22.2+0.2+11/0.5",[]).

Z = 0.0 ? 
| ?- listing.

digit(A, B, C) :-
        'C'(B, D, C),
        [48]=<D,
        D=<[57],
        A is D-[48].

digits(A, 1, B, C) :-
        digit(A, B, C).
digits(A, B, C, D) :-
        digit(E, C, F),
        digits(G, H, F, D),
        B is 10*H,
        A is E*B+G.
...
*/
