3

私はPrologでURIパーサーに取り組んでいますが、現時点ではもっと単純なもので立ち往生しています。文字列を調べて特定の文字「:」を見つけました。それを見つけたら、その前に連結された文字のみを含む文字列が必要です。

このプログラム:

% caratteri speciali
colonCheck(S) :-
   string_to_atom([S], C),
   C = ':'.                        % S==:

headGetter([H|T], [H]) :-
   !.

% struttura uri
uri(Scheme, Userinfo, Host, Port, Path, Query, Fragment).

% parsing uri
parsed_uri(UriInput, uri(Scheme,Userinfo,Host,Port,Path,Query,Fragment)) :-
   scheme(UriInput, uri(S,Userinfo,Host,Port,Path,Query,Fragment)),
   not(headGetter(UriInput, ':')),
   !,
   string_to_atom([S], Scheme).

% controllo Scheme, in ingresso ho i dati da controllare e l'oggetto uri che 
% mi servirà per inviarlo al passaggio successivo ho trovato i due punti
scheme([H|T], uri(Scheme,Userinfo,Host,Port,Path,Query,Fragment)):-
   colonCheck(H),
   !,
   end(Scheme).
% non trovo i due punti e procedo a controllare il prossimo carattere
% (la testa dell'attuale coda)
scheme([H|T], uri(Scheme,Userinfo,Host,Port,Path,Query,Fragment)):-
   not(colonCheck(H)),
   scheme(T, uri(This, Userinfo,Host,Port,Path,Query,Fragment)),
   append([H], This, Scheme).

%fine computazione
end([S]).

この結果が得られます:

?- scheme("http:", uri(A,_,_,_,_,_,_)).
A = [104, 116, 116, 112, _G1205].

その部分は正しいと思いますが、charリストを文字列に変換したいので、最後の行を次のように変更しました。

end([S]) :-
   string_to_atom([S], K).

しかし、私はこのエラーメッセージを受け取ります:

エラー:string_to_atom / 2:引数が十分にインスタンス化されていません

私はおそらく何かが欠けています。それが何であるかわかりますか?

4

1 に答える 1

0

Prolog の文字列は単なる文字コードのリストなので、コードを大幅に簡素化できます:

?- S = "http:/example.com", append(L, [0':|R], S), format('~s and ~s~n', [L,R]).

出力します

http and /example.com
S = [104, 116, 116, 112, 58, 47, 101, 120, 97|...],
L = [104, 116, 116, 112],
R = [47, 101, 120, 97, 109, 112, 108, 101, 46|...] .

colonCheck/1、headGetter/2、end/1 は役に立たない。どの言語でも、特に宣言型言語ではスタイルが悪いと思う。シンボルを必要なく導入する。

構造化データを解析する必要がある場合は、DCG からのより優れたサポートを見つけることができます。

?- phrase((seq(L),":",seq(R)), "http:/example.com", []),format('~s and ~s~n', [L,R]).

どこ

seq([]) --> [].
seq([C|Cs]) --> [C], seq(Cs).

上記と同じものを出力します。

http and /example.com
L = [104, 116, 116, 112],
R = [47, 101, 120, 97, 109, 112, 108, 101, 46|...] .

結論: scheme/2 を次のように置き換えます

scheme(Url, uri(Scheme, _Userinfo, _Host, _Port, _Path, _Query, _Fragment)) :-
    append(Scheme, [0':|_], Url).

そしてあなたは得るでしょう

?- scheme("http:", uri(A,_,_,_,_,_,_)).
A = [104, 116, 116, 112]
于 2012-11-27T18:19:21.470 に答える