自定义DCG操作员



假设我想编写一个自定义运算符,以重复的方式编写DCG规则。

例如,假设我有一个DCG,ws,这样:

ws --> [].
ws --> " ", ws.

以匹配零个或多个空格。显然,如果我希望在语法中的每个标记之间都有可选的空白,那么必须在所有地方都放, ws是令人讨厌的。

我可以定义一个新的运算符来代替,/2

:- op(1000, xfy, [ -- ]).
:- meta_predicate --(*,*,?,?).
--(L,R) --> ({callable(L)} -> call(L); L), ws, ({callable(R)} -> call(R); R).

这通过可选的空白规则连接--/2的左手和右手。这基本上很好,但某些事情会让它出错:

rule --> "foo" -- ("bar"; "quux").

如果我尝试执行这个规则,我会得到一个错误,说;/4没有定义。我对这个问题有一个模糊的想法,但基本上问题是:有没有一种方法可以为DCG定义与,/2具有相同通用性的新运算符?

,这是可能的。

目前,主要问题是:

?-可调用("foo"(。是的

所以,我建议这个更简单的定义:

-(L,R(->L、 ws,R.

此外,我建议:

:-set_prolog_flag(双引号,字符(

示例查询:

?-短语(规则,Ls(Ls=[f,o,o,b,a,r];Ls=[f,o,o,q,u,u,x];Ls=[f,o,o',b,a,r];Ls=[f,o,'',q,u,u,x];Ls=[f,o,o','',b,a,r]

作为另一个例子,让我们使用这个规则:

规则-->"foo"--("bar"|"quux"(--"test">

现在我们得到例如:

?-长度(Ls,_(,短语(rule,Ls(Ls=[f,o,o,b,a,r,t,e,s,t];Ls=[f,o,o,b,a,r,'',t,e,s,t];Ls=[f,o,o,q,u,u,x,t,e,s,t];Ls=[f,o,'',b,a,r,t,e,s,t];Ls=[f,o,o,b,a,r,'','',t,e,s,t];Ls=[f,o,o,q,u,u,x,'',t,e,s,t];Ls=[f,o,o'',b,a,r,'',t,e,s,t];Ls=[f,o,'',q,u,u,x,t,e,s,t];Ls=[f,o,o'','',b,a,r,t,e,s,t];Ls=[f,o,o,b,a,r,'','',t,e,s,t]

注意迭代深化是如何用于公平枚举的。

最新更新