0

好的,所以我正在为算术方程编写解析器。例如,我在列表中获取输入,"10+20" = [49,48,43,50,48]然后将所有数字转换为相应的数字,例如[49,48,43,50,48] = [1,0,43,2,0],从那里我想将大于 10 的整数重新组合在一起。

从 ascii -> 数字转换我使用 maplist 和 number_codes 进行转换。

我的一种方法是遍历列表,如果它是 0-9 将其存储在一个变量中,然后检查下一个数字,0-9 将它附加到另一个变量等等,直到我点击一个运算符。我似乎不能简单地附加数字。这是我当前的代码。

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

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

不确定是否有一种简单的方法可以添加到我的代码中(据我所知,maplist 只返回一个与传入的列表长度相等的列表,但我可能会弄错)。

任何帮助表示赞赏:)

4

2 回答 2

1

我前段时间用表达式解析器回答了。

它将向您展示如何将 DCG 用于实际任务,我希望您会欣赏这种方法的通用性和简单性。

SWI-Prolog 只需要一个库谓词,编号//1,在 Sicstus 中很容易实现。如果您需要更多帮助,请告诉我。

于 2012-09-11T14:01:29.620 回答
1

是的,maplist只“返回”一个等长的列表。此外,maplist仅将谓词应用于一个元素(基本上它与上下文无关)。因此,不可能做你想做的事情(将运算符之间的数字组合成一个数字),maplist你必须自己编写递归。

但是,您可以做一些比所有这些来回转换更容易的事情:

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

像这样工作:

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.

自然地,如果你想要一个包含所有相关数字的列表,你将不得不做一些递归的事情,但这有点微不足道。

但是,如果您仍想进行转换,我建议检查定句语法;它将大大简化任务。

于 2012-09-11T10:01:08.680 回答