0

Alright so I am coding a parser for arithmetic equations. I get the input in a list, e.g. "10+20" = [49,48,43,50,48] and then I convert all the digits to there corresponding numbers e.g. [49,48,43,50,48] = [1,0,43,2,0] and from there I want to put integers > 10 back together.

Converting from ascii -> digits I use a maplist and number_codes to convert.

One approach I had was to just traverse the list and if it's 0-9 store it in a variable and then check the next number, 0-9 append it to the other variable and so on until I hit an operator. I can't seem to simply append digits as it were. Here's my current code.

expression(L) :-
    maplist(chars, L, Ls).

chars(C, N) :-
    (
        C >= "0", "9" >= C -> number_codes(N, [C]);
        N is C
    ).

Not sure if there's a simple way to add to my code (as far as I know, maplist only gives back a list of equal length to the list passed in but I could be mistaken).

Any help is appreciated :)

false
  • 10,264
  • 13
  • 101
  • 209
WhaleFanny
  • 77
  • 3
  • 9

2 Answers2

1

Yes, maplist only 'gives back' a list of equal length. Moreover, maplist applies a predicate only to one element (basically it's context-free). Therefore, it is not possible to do what you want (combine digits between operators to a single number) with maplist and you would have to write the recursion yourself.

However, you can do something way easier than all this converting back and forth:

expression(L, E):-
    string_to_atom(L,A),
    atom_to_term(A,E,[]).

Which works like this:

2 ?- expression("1+2",E).
E = 1+2.

3 ?- expression("1+2",E), X is E.
E = 1+2, X = 3.

4 ?- expression("1+2",E), X+Y =  E.
E = 1+2, X = 1, Y = 2.

5 ?- expression("1+2+3",E), X+Y =  E.
E = 1+2+3, X = 1+2, Y = 3.

Naturally, if you want a list with all the numbers involved you will have to do something recursive but this is kinda trivial imho.

If however you still want to do the converting, I suggest checking Definite Clause Grammars; it will simplify the task a lot.

Thanos Tintinidis
  • 5,828
  • 1
  • 20
  • 31
1

I answered some time ago with an expression parser.

It will show you how to use DCG for practical tasks, and I hope you will appreciate the generality and simplicity of such approach.

Just a library predicate is required from SWI-Prolog, number//1, easily implemented in Sicstus. Let me know if you need more help on that.

Community
  • 1
  • 1
CapelliC
  • 59,646
  • 5
  • 47
  • 90