ADDED: Support for higher-order non-terminals phrase//[2,3]
These non-terminals take a grammar rule body and additional arguments
as arguments. These arguments are appended to the first argument.
A key motivation for the introduction of these non-terminals is found
in the discussion and sample code provided by @bakaq in:
https://github.com/mthom/scryer-prolog/discussions/2260
In this way, portable higher-order DCG programming is possible while
keeping the logical grammar rule expansion implementation dependent.
Example:
?- phrase(phrase('.', a, []), Cs).
Cs = "a".
This commit is contained in:
@@ -12,6 +12,8 @@ to learn more about them.
|
|||||||
[op(1105, xfy, '|'),
|
[op(1105, xfy, '|'),
|
||||||
phrase/2,
|
phrase/2,
|
||||||
phrase/3,
|
phrase/3,
|
||||||
|
phrase/4,
|
||||||
|
phrase/5,
|
||||||
seq//1,
|
seq//1,
|
||||||
seqq//1,
|
seqq//1,
|
||||||
... //0,
|
... //0,
|
||||||
@@ -27,6 +29,10 @@ to learn more about them.
|
|||||||
|
|
||||||
:- meta_predicate phrase(2, ?, ?).
|
:- meta_predicate phrase(2, ?, ?).
|
||||||
|
|
||||||
|
:- meta_predicate phrase(2, ?, ?, ?).
|
||||||
|
|
||||||
|
:- meta_predicate phrase(2, ?, ?, ?, ?).
|
||||||
|
|
||||||
%% phrase(+Body, ?Ls).
|
%% phrase(+Body, ?Ls).
|
||||||
%
|
%
|
||||||
% True iff Body describes the list Ls. Body must be a DCG body.
|
% True iff Body describes the list Ls. Body must be a DCG body.
|
||||||
@@ -76,6 +82,34 @@ phrase(GRBody, S0, S) :-
|
|||||||
; call(M:GRBody1, S0, S)
|
; call(M:GRBody1, S0, S)
|
||||||
).
|
).
|
||||||
|
|
||||||
|
phrase(GRBody, Arg, S0, S) :-
|
||||||
|
strip_module(GRBody, M, GRBody1),
|
||||||
|
( var(GRBody) ->
|
||||||
|
instantiation_error(phrase/4)
|
||||||
|
; nonvar(GRBody1),
|
||||||
|
GRBody1 =.. GRBodys1,
|
||||||
|
append(GRBodys1, [Arg], GRBodys2),
|
||||||
|
GRBody2 =.. GRBodys2,
|
||||||
|
dcg_constr(GRBody2),
|
||||||
|
dcg_body(GRBody2, S0, S, GRBody3) ->
|
||||||
|
call(M:GRBody3)
|
||||||
|
; call(M:GRBody1, Arg, S0, S)
|
||||||
|
).
|
||||||
|
|
||||||
|
phrase(GRBody, Arg1, Arg2, S0, S) :-
|
||||||
|
strip_module(GRBody, M, GRBody1),
|
||||||
|
( var(GRBody) ->
|
||||||
|
instantiation_error(phrase/5)
|
||||||
|
; nonvar(GRBody1),
|
||||||
|
GRBody1 =.. GRBodys1,
|
||||||
|
append(GRBodys1, [Arg1,Arg2], GRBodys2),
|
||||||
|
GRBody2 =.. GRBodys2,
|
||||||
|
dcg_constr(GRBody2),
|
||||||
|
dcg_body(GRBody2, S0, S, GRBody3) ->
|
||||||
|
call(M:GRBody3)
|
||||||
|
; call(M:GRBody1, Arg1, Arg2, S0, S)
|
||||||
|
).
|
||||||
|
|
||||||
% The same version of the below two dcg_rule clauses, but with module scoping.
|
% The same version of the below two dcg_rule clauses, but with module scoping.
|
||||||
dcg_rule(( M:NonTerminal, Terminals --> GRBody ), ( M:Head :- Body )) :-
|
dcg_rule(( M:NonTerminal, Terminals --> GRBody ), ( M:Head :- Body )) :-
|
||||||
dcg_non_terminal(NonTerminal, S0, S, Head),
|
dcg_non_terminal(NonTerminal, S0, S, Head),
|
||||||
@@ -139,6 +173,8 @@ dcg_constr(( _'|'_ )). % 7.14.6 - alternative
|
|||||||
dcg_constr({_}). % 7.14.7
|
dcg_constr({_}). % 7.14.7
|
||||||
dcg_constr(call(_)). % 7.14.8
|
dcg_constr(call(_)). % 7.14.8
|
||||||
dcg_constr(phrase(_)). % 7.14.9
|
dcg_constr(phrase(_)). % 7.14.9
|
||||||
|
dcg_constr(phrase(_,_)). % extension of 7.14.9
|
||||||
|
dcg_constr(phrase(_,_,_)). % extension of 7.14.9
|
||||||
dcg_constr(!). % 7.14.10
|
dcg_constr(!). % 7.14.10
|
||||||
%% dcg_constr(\+ _). % 7.14.11 - not (existence implementation dep.)
|
%% dcg_constr(\+ _). % 7.14.11 - not (existence implementation dep.)
|
||||||
dcg_constr((_->_)). % 7.14.12 - if-then (existence implementation dep.)
|
dcg_constr((_->_)). % 7.14.12 - if-then (existence implementation dep.)
|
||||||
@@ -166,6 +202,8 @@ dcg_cbody(( GREither '|' GROr ), S0, S, ( Either ; Or )) :-
|
|||||||
dcg_cbody({Goal}, S0, S, ( Goal, S0 = S )).
|
dcg_cbody({Goal}, S0, S, ( Goal, S0 = S )).
|
||||||
dcg_cbody(call(Cont), S0, S, call(Cont, S0, S)).
|
dcg_cbody(call(Cont), S0, S, call(Cont, S0, S)).
|
||||||
dcg_cbody(phrase(Body), S0, S, phrase(Body, S0, S)).
|
dcg_cbody(phrase(Body), S0, S, phrase(Body, S0, S)).
|
||||||
|
dcg_cbody(phrase(Body, Arg), S0, S, phrase(Body, Arg, S0, S)).
|
||||||
|
dcg_cbody(phrase(Body, Arg1, Arg2), S0, S, phrase(Body, Arg1, Arg2, S0, S)).
|
||||||
dcg_cbody(!, S0, S, ( !, S0 = S )).
|
dcg_cbody(!, S0, S, ( !, S0 = S )).
|
||||||
% dcg_cbody(\+ GRBody, S0, S, ( \+ phrase(GRBody,S0,_), S0 = S )).
|
% dcg_cbody(\+ GRBody, S0, S, ( \+ phrase(GRBody,S0,_), S0 = S )).
|
||||||
dcg_cbody(( GRIf -> GRThen ), S0, S, ( If -> Then )) :-
|
dcg_cbody(( GRIf -> GRThen ), S0, S, ( If -> Then )) :-
|
||||||
|
|||||||
Reference in New Issue
Block a user