这个答案是:Very basic dcg prolog syntax帮了我一点点,但是X只得到了下一个角色,我要整个孩子,读下去!
我正在使用GNU Prolog编写命令选项解析器,并且我被困在DCG点上。例如,我有一个语法规则,查找"foo --as=json“,我只是想不出如何得到”任何东西“的结果,代码:
as_opt --> "--as=", anything, { c( as_opt )}, !.
anything --> [], {c(anything_match)}.而gprolog的扩展是:
as_opt([45, 45, 97, 115, 61|A], B) :-
anything(A, C),
c(as_opt), !,
C = B.
anything(A, B) :-
c(anything_match), !,
A = B."c()“谓词很简单,只用于跟踪使用stdout的格式()执行的规则,这样我就可以看到它运行时发生了什么。如果我是手工编写代码的话,我会这样做的:
%% for completeness here!
c(Msg) :- format("Processed ~w~n", [Msg]).
as_opt([45, 45, 97, 115, 61|A], B) :-
anything(A, C),
c(as_opt), !,
C = B,
{ g_assign( gvValue, B )}. %% just for example回到原来的DCG:
as_opt --> "--as=", anything, { c( as_opt ), gassign( gvValue, ??? )}, !.那么,“??”是。一定是possible...it吧。我将重新阅读gprolog规则如何再次扩展DCG规则,以防我自己(facepalm),但在此期间,任何援助都将是最受欢迎的。
谢了肖恩。
发布于 2013-09-06 12:12:22
您所要求的是最简单的DCG非终端之一,它描述了任何列表:
list --> [].
list --> [_], list.要实际访问所描述的列表,请引入一个参数:
list([]) --> [].
list([L|Ls) --> [L], list(Ls)你可以这样使用它:
as_opt(Option) --> "--as=", list(Option).发布于 2013-09-07 11:40:24
有一个比mat描述的更好的解决方案,它更快并且避免虚假的选择点,但是它需要支持call//1内置的非终端,例如SWI、GNU Prolog和其他Prolog编译器。也在Logtalk上。考虑:
as_opt(Option) --> "--as=", list(Option).
list([L|Ls]) --> [L], list(Ls).
list([]) --> [].
as_opt2(Option) --> "--as=", call(rest(Option)).
rest(Rest, Rest, _).使用SWI更好地说明这些差异:
?- phrase(as_opt(Option), "--as=json").
Option = [106, 115, 111, 110] ;
false.
?- phrase(as_opt2(Option), "--as=json").
Option = [106, 115, 111, 110].
?- time(phrase(as_opt(Option), "--as=json")).
% 9 inferences, 0.000 CPU in 0.000 seconds (57% CPU, 562500 Lips)
Option = [106, 115, 111, 110] ;
% 2 inferences, 0.000 CPU in 0.000 seconds (63% CPU, 133333 Lips)
false.
?- time(phrase(as_opt2(Option), "--as=json")).
% 6 inferences, 0.000 CPU in 0.000 seconds (51% CPU, 285714 Lips)
Option = [106, 115, 111, 110].虚假选择点来源于list//1非终端的定义.性能差异在于,虽然call//1允许我们简单地访问隐式列表参数,但list//1非终端则是对该隐式参数逐个元素执行列表复制元素。因此,list//1版本的性能与--as=前缀后面的字符成线性关系,而call//1性能是恒定的,与前缀后面的字符数无关:
?- time(phrase(as_opt(Option), "--as=jsonjsonjsonjsonjsonjsonjsonjsonjsonjsonjsonjson")).
% 54 inferences, 0.000 CPU in 0.000 seconds (83% CPU, 2700000 Lips)
Option = [106, 115, 111, 110, 106, 115, 111, 110, 106|...] ;
% 4 inferences, 0.000 CPU in 0.000 seconds (69% CPU, 137931 Lips)
false.
?- time(phrase(as_opt2(Option), "--as=jsonjsonjsonjsonjsonjsonjsonjsonjsonjsonjsonjson")).
% 6 inferences, 0.000 CPU in 0.000 seconds (79% CPU, 333333 Lips)
Option = [106, 115, 111, 110, 106, 115, 111, 110, 106|...].发布于 2013-09-06 12:09:17
我认为你不应该使用全局变量。相反,向DCG子句中添加参数,以返回值:
anything([C|Cs]) --> [C], anything(Cs).
anything([]) --> [].否则,其余部分可以作为短语/3的最后一个参数,在规则继承之后,“消耗”标题匹配。
https://stackoverflow.com/questions/18657304
复制相似问题