使用 DCG 解析和生成多级列表结构

Men*_*ong 5 parsing prolog nested-lists dcg

假设我将“a-list”称为零个或多个“a”的列表:

% as = [a,a,a]
as --> [].
as --> [a], as.
Run Code Online (Sandbox Code Playgroud)

假设我想表示一个“b-list”,一个零个或多个 a-list 的列表:

% bs := [ as,      as  ]
% bs  = [ [a,a,a], [a] ]
bs --> [].
bs --> [A], { phrase(as,A) }, bs.
Run Code Online (Sandbox Code Playgroud)

是否有一些更惯用的说法,不需要使用花括号将 DCG 退出到“正常 Prolog”,只需phrase()再次调用?

Pau*_*ura 3

另一种替代方案是使用 lambda 表达式来定义非终结符,我认为这不是更好的方案,因为它的可读性可能较差。bs//0使用 Logtalk(您可以在大多数 Prolog 系统上运行)或 SWI-Prolog(通过library(yall),它实现 Logtalk lambda 表达式):

bs --> [].
bs --> [[A|As],As]>>phrase(as,A), bs.
Run Code Online (Sandbox Code Playgroud)

lambda 表达式提供对语法规则隐式参数的访问。

调用示例:

?- phrase(bs, [[a],[a,a,a],[a,a]]).
true.

?- phrase(bs, [[a],[a,b,a],[a,a]]).
false.
Run Code Online (Sandbox Code Playgroud)