首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >DCG:将余数分配给DCG {}代码中的变量

DCG:将余数分配给DCG {}代码中的变量
EN

Stack Overflow用户
提问于 2013-09-06 11:56:55
回答 3查看 402关注 0票数 3

这个答案是:Very basic dcg prolog syntax帮了我一点点,但是X只得到了下一个角色,我要整个孩子,读下去!

我正在使用GNU Prolog编写命令选项解析器,并且我被困在DCG点上。例如,我有一个语法规则,查找"foo --as=json“,我只是想不出如何得到”任何东西“的结果,代码:

代码语言:javascript
复制
as_opt --> "--as=", anything, { c( as_opt )}, !.
anything --> [], {c(anything_match)}.

而gprolog的扩展是:

代码语言:javascript
复制
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的格式()执行的规则,这样我就可以看到它运行时发生了什么。如果我是手工编写代码的话,我会这样做的:

代码语言:javascript
复制
%% 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:

代码语言:javascript
复制
as_opt --> "--as=", anything, { c( as_opt ), gassign( gvValue, ??? )}, !.

那么,“??”是。一定是possible...it吧。我将重新阅读gprolog规则如何再次扩展DCG规则,以防我自己(facepalm),但在此期间,任何援助都将是最受欢迎的。

谢了肖恩。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-06 12:12:22

您所要求的是最简单的DCG非终端之一,它描述了任何列表:

代码语言:javascript
复制
list --> [].
list --> [_], list.

要实际访问所描述的列表,请引入一个参数:

代码语言:javascript
复制
list([])    --> [].
list([L|Ls) --> [L], list(Ls)

你可以这样使用它:

代码语言:javascript
复制
as_opt(Option) --> "--as=", list(Option).
票数 3
EN

Stack Overflow用户

发布于 2013-09-07 11:40:24

有一个比mat描述的更好的解决方案,它更快并且避免虚假的选择点,但是它需要支持call//1内置的非终端,例如SWI、GNU Prolog和其他Prolog编译器。也在Logtalk上。考虑:

代码语言:javascript
复制
as_opt(Option) --> "--as=", list(Option).

list([L|Ls]) --> [L], list(Ls).
list([]) --> [].

as_opt2(Option) --> "--as=", call(rest(Option)).

rest(Rest, Rest, _).

使用SWI更好地说明这些差异:

代码语言:javascript
复制
?- 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性能是恒定的,与前缀后面的字符数无关:

代码语言:javascript
复制
?- 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|...].
票数 3
EN

Stack Overflow用户

发布于 2013-09-06 12:09:17

我认为你不应该使用全局变量。相反,向DCG子句中添加参数,以返回值:

代码语言:javascript
复制
anything([C|Cs]) --> [C], anything(Cs).
anything([]) --> [].

否则,其余部分可以作为短语/3的最后一个参数,在规则继承之后,“消耗”标题匹配。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18657304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档