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 回答