我无法让这个Prolog DCG代码工作:
String1=" ",string_codes(String1,Codes),phrase(spaces(Output),Codes).
spaces(XXs) -->
[X], {X=32}, spaces(Xs),
{char_code(Ch,X), atom_concat(Ch,Xs,XXs)}, !. %%Space
spaces([]) --> [].
我觉得
改进的解决方案可能是这样的:
spaces(Spaces) --> " ", spaces(S0), { atom_concat(' ', S0, Spaces) }.
spaces('') --> [].
没有必要问代码 32 的字符是什么,你知道它是一个空格。另外,从你的答案[X], {X=32}
比[32]
更好,这仍然比" "
更好。
我通过将基本情况下的 [] 更改为"来解决此问题。
spaces(XXs) -->
[X], {X=32}, spaces(Xs),
{char_code(Ch,X), atom_concat(Ch,Xs,XXs)}, !. %% Space
spaces('') --> [].
String1 = " ",
Codes = [32, 32, 32],
Output = ' '.
如果你正在做DCG并使用SWI-Prolog,那么dcgbasics中有一个常用谓词和DCG子句的库。这可以在代码中使用
:- use_module(library(dcg/basics)).
要列出谓词的代码,请使用 listing/1,例如
?- listing(dcg_basics:_).
该库有一个 DCG 子句blanks//0
可以执行您想要的操作,例如
?- listing(dcg_basics:blanks).
blanks(A, B) :-
blank(A, C),
!,
D=C,
blanks(D, B).
blanks(A, A).
true.
?- listing(dcg_basics:blank).
blank([C|A], B) :-
nonvar(C),
code_type(C, space),
B=A.
true.
其中作为DCG是
blank -->
[C],
{
nonvar(C),
code_type(C,space)
}.
blanks -->
blank, !, blanks.
blanks --> [].
铌
库版本使用 character codes
而不是 characters
。
?- string_codes("",Codes),phrase(blanks,Codes,Rest).
Codes = Rest, Rest = [].
?- string_codes(" ",Codes),phrase(blanks,Codes,Rest).
Codes = [32],
Rest = [].
?- string_codes(" ",Codes),phrase(blanks,Codes,Rest).
Codes = [32, 32],
Rest = [].
?- string_codes(" ",Codes),phrase(blanks,Codes,Rest).
Codes = [32, 32, 32],
Rest = [].