parsing and generating multi-level list structures with DCG

Viewed 81

Suppose I call an "a-list" a list of zero or more "a"s:

% as = [a,a,a]
as --> [].
as --> [a], as.

Suppose I want to represent a "b-list”, a list of zero or more a-lists:

% bs := [ as,      as  ]
% bs  = [ [a,a,a], [a] ]
bs --> [].
bs --> [A], { phrase(as,A) }, bs.

Is there some more idiomatic way of saying this which doesn't require use of the curly braces to drop out of DCG into "normal Prolog", only to call phrase() again?

1 Answers

An alternative, that I don't think is better as it's arguably less readable, is to use a lambda expression for the definition of the bs//0 non-terminal. Using Logtalk (which you can run with most Prolog systems) or SWI-Prolog (via library(yall), which implements Logtalk lambda expressions):

bs --> [].
bs --> [[A|As],As]>>phrase(as,A), bs.

The lambda expression provides access to the grammar rule implicit arguments.

Sample calls:

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

?- phrase(bs, [[a],[a,b,a],[a,a]]).
false.
Related