Expanded parser and fixed parsing numbers

This commit is contained in:
Hugo Sales 2018-12-14 22:46:14 +00:00
parent ea80d57ef9
commit d7f3a9996b
1 changed files with 144 additions and 60 deletions

View File

@ -198,16 +198,16 @@ special_word_number(six, 6, f).
special_word_number(seven, 7, f).
special_word_number(eight, 8, f).
special_word_number(nine, 9, f).
special_word_number(ten, 10, f).
special_word_number(eleven, 11, f).
special_word_number(twelve, 12, f).
special_word_number(thirteen, 13, f).
special_word_number(fourteen, 14, f).
special_word_number(fifteen, 15, f).
special_word_number(sixteen, 16, f).
special_word_number(seventeen, 17, f).
special_word_number(eighteen, 18, f).
special_word_number(nineteen, 19, f).
special_word_number(ten, 10, g).
special_word_number(eleven, 11, g).
special_word_number(twelve, 12, g).
special_word_number(thirteen, 13, g).
special_word_number(fourteen, 14, g).
special_word_number(fifteen, 15, g).
special_word_number(sixteen, 16, g).
special_word_number(seventeen, 17, g).
special_word_number(eighteen, 18, g).
special_word_number(nineteen, 19, g).
special_word_number(twenty, 20, fy).
special_word_number(thirty, 30, fy).
special_word_number(forty, 40, fy).
@ -220,64 +220,76 @@ special_word_number(hundred, 100, xfy).
special_word_number(thousand, 1000, xfy).
special_word_number(million, 1000000, xfy).
parse_number(void, T, [WN | R], NC) :-
parse_number_explicit(void, void, T, [WN | R], NC) :-
special_word_number(WN, N, P),
member(P, [f, fy]),
parse_number(N, T, R, NC),
!.
parse_number(TL, T, [WN | R], NC) :-
member(P, [f, g, fy]),
!,
parse_number_explicit(P, N, T, R, NC).
parse_number_explicit(fy, NL, T, [WN | R], NC) :-
special_word_number(WN, N, f),
!,
parse_number_explicit(P, op(+, NL, N), T, R, NC).
parse_number_explicit(xfy, TL, T, [WN | R], NC) :-
TL \= void,
special_word_number(WN, N, P),
member(P, [f, fy]),
parse_number(op(+, TL, N), T, R, NC),
!.
parse_number(TL, T, [WN | R], NC) :-
member(P, [f, g, fy]),
!,
parse_number_explicit(P, op(+, TL, N), T, R, NC).
parse_number_explicit(P, TL, T, [WN | R], NC) :-
special_word_number(WN, N, xfy),
TL \= void,
parse_number(op(*, TL, N), T, R, NC),
!.
parse_number(TL, T, [and, WN | R], NC) :-
!,
parse_number_explicit(xfy, op(*, TL, N), T, R, NC).
parse_number_explicit(P, TL, T, [and, WN | R], NC) :-
special_word_number(WN, _, _),
parse_number(TL, T, [WN | R], NC),
parse_number_explicit(P, TL, T, [WN | R], NC),
!.
parse_number(T, T, [WN | R], [WN | R]) :-
parse_number_explicit(_, T, T, [WN | R], [WN | R]) :-
T \= void,
not(special_word_number(WN, _, _)),
!.
parse_number(T, T, [], []) :-
parse_number_explicit(_, T, T, [], []) :-
T \= void,
!.
parse_number(T, SL, NC) :-
parse_number_explicit(void, void, T, SL, NC).
%% Tests:
%% ?- parse_number(void, T, [two], _).
%% ?- parse_number(T, [two], _).
%@ T = 2.
%% ?- parse_number(void, T, [twenty], _).
%@ T = 20.
%% ?- parse_number(void, T, [twenty, one], _).
%@ T = op(+, 20, 1).
%% ?- parse_number(void, T, [hundred], _).
%% ?- parse_number(T, [nineteen, two], _).
%@ false.
%% ?- parse_number(void, T, [three, hundred], _).
%% ?- parse_number(T, [twenty], _).
%@ T = 20.
%% ?- parse_number(T, [twenty, twenty], _).
%@ false.
%% ?- parse_number(T, [twenty, one], _).
%@ T = op(+, 20, 1).
%% ?- parse_number(T, [hundred], _).
%@ false.
%% ?- parse_number(T, [three, hundred], _).
%@ T = op(*, 3, 100).
%% ?- parse_number(void, T, [twenty, hundred], _).
%% ?- parse_number(T, [twenty, hundred], _).
%@ T = op(*, 20, 100).
%% ?- parse_number(void, T, [twenty, one, hundred], _).
%% ?- parse_number(T, [twenty, one, hundred], _).
%@ T = op(*, op(+, 20, 1), 100).
%% ?- parse_number(void, T, [two, hundred, and, one], _).
%% ?- parse_number(T, [two, hundred, and, one], _).
%@ T = op(+, op(*, 2, 100), 1).
%% ?- parse_number(void, T, [twenty, one, hundred, and, twenty, one], _).
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one], _).
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1).
%% ?- parse_number(void, T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC).
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC).
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1),
%@ NC = [foo, bar, blah].
%% ?- parse_number(void, T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC).
%% ?- parse_number(T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC).
%@ T = op(*, op(+, 20, 1), 100),
%@ NC = [and, bleg, twenty, quux, one, foo, bar].
%% ?- parse_number(void, T, [two, hundred, thousand], _).
%% ?- parse_number(T, [two, hundred, thousand], _).
%@ T = op(*, op(*, 2, 100), 1000).
%% ?- parse_number(void, T, [twenty, one, hundred, thousand], _).
%% ?- parse_number(T, [twenty, one, hundred, thousand], _).
%@ T = op(*, op(*, op(+, 20, 1), 100), 1000).
%% ?- parse_number(void, T, [thirty, five, million], _).
%@ T = op(*, op(+, 30, 5), 1000000).
%% ?- parse_number(void, T, [foo, five, million], NC).
%% ?- parse_number(T, [thirty, five, million, five, hundred, thirty, four], _).
%@ T = op(+, op(+, op(*, op(+, op(*, op(+, 30, 5), 1000000), 5), 100), 30), 4).
%% ?- parse_number(T, [foo, five, million], NC).
%@ false.
operations(times, *).
@ -285,27 +297,99 @@ operations(plus, +).
parse_operation(Op) --> [WOp], { operations(WOp, Op) }.
parse_expression(TLP-TL, op(Op, TLP-TL, TR)) --> parse_number(void, TL),
parse_operation(Op),
parse_expression(op(Op, TL, TRP)-TRP, TR).
parse_expression(void, T) --> parse_number(void, T), { T \= void }.
parse_expression(TL, TL-TR) --> parse_number(void, TR), { TR \= void, TL \= void }.
parse_polynomial_operand(T) --> parse_number(T).
parse_polynomial_operand(T) --> parse_power(T).
parse_polynomial_operand(T) --> parse_stored_variable(T).
parse_stored_variable(op(load, P, void)) --> %% NOTE Not sure if it's better to load now or later
[P],
polynomial_store(P, T).
parse_polynomial_variable(B) -->
[B],
{ polynomial_variable(B) }.
%% Order matters
parse_power(op(^, TB, 2)) -->
parse_polynomial_variable(TB),
[squared].
parse_power(op(^, TB, 3)) -->
parse_polynomial_variable(TB),
[cubed].
parse_power(op(^, TB, TN)) -->
parse_polynomial_variable(TB),
[raised, to],
parse_number(TN).
parse_power(TB) -->
parse_polynomial_variable(TB).
parse_polynomial(void-_, T) -->
parse_polynomial_operand(TL),
parse_operation(Op),
!,
parse_polynomial(op(Op, TL, TRP)-TRP, T).
parse_polynomial(TLP-TL, T) -->
parse_polynomial_operand(TL),
parse_operation(+),
!,
parse_polynomial(op(+, TLP, TRP)-TRP, T).
parse_polynomial(TLP-T, TLP) -->
parse_polynomial_operand(TL),
parse_operation(*),
!,
parse_polynomial(op(*, TL, TRP)-TRP, T).
parse_polynomial(TLP-TL, TLP) -->
{ TLP \= void },
parse_polynomial_operand(TL),
!,
{ TL \= void }.
parse_polynomial(void-_, T) -->
parse_polynomial_operand(T), { T \= void }.
%% Tests:
%% ?- parse_expression(T, [], _).
%% ?- parse_polynomial(_-_, T, [], _).
%@ false.
%% ?- parse_expression(T, [two], _).
%% ?- parse_polynomial(_-_, T, [two], _).
%@ T = 2.
%% ?- parse_expression(void, T, [two, times, two], _).
%@ T = 2 ;
%@ false.
%@ T = 2 ;
%@ false.
%@ T = op(*, 2, 2).
%% ?- parse_expression(T, [two, times, three, plus, two], _).
%% ?- parse_polynomial(_-_, T, [two, times, three], _).
%@ T = op(*, 2, 3).
%@ T = op(*, 2, op(+, 3, 2)).
%% ?- parse_expression(T, [two, times, times, two], _).
%@ false.
%% ?- parse_polynomial(_-_, T, [two, times, three, plus, four], _).
%@ T = op(+, op(*, 2, 3), 4).
%% ?- parse_polynomial(_-_, T, [two, plus, three, times, four], _).
%@ T = op(+, 2, op(*, 3, 4)).
%% ?- parse_polynomial(_-_, T, [two, plus, three, times, four, plus, six, times, five], _).
%@ T = op(+, 2, op(+, op(*, 3, 4), op(*, 6, 5))).
%% ?- parse_polynomial(_-_, T, [two, times, times, two], NC); write(NC).
%@ _3164
%@ true. %% NOTE Potential problem. It seems NC isn't unified with the list, if it fails
%% ?- parse_polynomial(_-_, T, [two, plus, x, times, four], _).
%@ T = op(+, 2, op(*, x, 4)).
%% ?- parse_polynomial(_-_, T, [two, plus, x, times, four, plus, y, raised, to, five], _).
%@ T = op(+, 2, op(+, op(*, x, 4), op(^, y, 5))).
%% ?- parse_polynomial(_-_, T, [two, plus, two, plus, one, times, y], _).
%@ T = op(+, op(+, 2, 2), op(*, 1, y)).
parse_command(op(show, T, void)) --> %% NOTE Probably easier if the tree is always binary
[show],
parse_polynomial(T).
parse_command(op(show, op(store, P, T))) -->
[show],
parse_polynomial(T),
[as],
[P].
parse_command(op(store, P, T)) -->
[let],
[P],
[be],
parse_polynomial(T).
parse_command(T) -->
[simplify],
parse_polynomial(T).
parse_command(op(*, TN, TP)) -->
[multiply],
parse_number(TN),
[by],
parse_polynomial(TP).