0

さて、算術方程式のパーサーをコーディングしています。たとえば、入力をリストで取得し、"10+20" = [49,48,43,50,48]すべての数字を対応する数字に変換します。たとえば[49,48,43,50,48] = [1,0,43,2,0]、そこから10を超える整数を元に戻したいとします。

ascii -> digits からの変換 maplist と number_codes を使用して変換します。

私が持っていた1つのアプローチは、リストをトラバースし、それが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述語を 1 つの要素にのみ適用します (基本的には文脈自由です)。したがって、希望すること (演算子間の数字を 1 つの数字に結合すること) を行うことはできず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.

当然、関連するすべての数値を含むリストが必要な場合は、再帰的な何かを行う必要がありますが、これはちょっと些細なことです。

それでも変換を行いたい場合は、Definite Clause Grammars を確認することをお勧めします。タスクが大幅に簡素化されます。

于 2012-09-11T10:01:08.680 に答える