1:- encoding(utf8).
    2:- module(
    3  abnf,
    4  [
    5  % NON-DETERMINISTIC SEQUENCE PATTERNS WITH NO SEPARATOR
    6    '#'//2,    % ?N, :Dcg_0
    7    '#'//3,    % ?N, :Dcg_1, -Args
    8    '*'//1,    % :Dcg_0
    9    '*'//2,    % :Dcg_1, ?Args
   10    '+'//1,    % :Dcg_0
   11    '+'//2,    % :Dcg_1, ?Args
   12    '?'//1,    % :Dcg_0
   13    '?'//2,    % :Dcg_1, ?Arg
   14    'm*'//2,   % ?M, :Dcg_0
   15    'm*'//3,   % ?M, :Dcg_1, -Args
   16    '*n'//2,   % ?N, :Dcg_0
   17    '*n'//3,   % ?N, :Dcg_1, -Args
   18    'm*n'//3,  % ?M, ?N, :Dcg_0
   19    'm*n'//4,  % ?M, ?N, :Dcg_1, -Args
   20  % DETERMINISTIC SEQUENCE PATTERNS WITH NO SEPARATOR
   21    '#!'//2,   % ?N, :Dcg_0
   22    '#!'//3,   % ?N, :Dcg_1, -Args
   23    '*!'//1,   % :Dcg_0
   24    '*!'//2,   % :Dcg_1, ?Args
   25    '+!'//1,   % :Dcg_0
   26    '+!'//2,   % :Dcg_1, ?Args
   27    '?!'//1,   % :Dcg_0
   28    '?!'//2,   % :Dcg_1, ?Arg
   29    'm*!'//2,  % ?M, :Dcg_0
   30    'm*!'//3,  % ?M, :Dcg_1, -Args
   31    '*n!'//2,  % ?N, :Dcg_0
   32    '*n!'//3,  % ?N, :Dcg_1, -Args
   33    'm*n!'//3, % ?M, ?N, :Dcg_0
   34    'm*n!'//4, % ?M, ?N, :Dcg_1, -Args
   35  % NON-DETERMINISTIC SEQUENCE PATTERNS WITH SEPARATOR
   36    '#&'//3,   % ?N, :Dcg_0, :Sep_0
   37    '#&'//4,   % ?N, :Dcg_1, :Sep_0, -Args
   38    '*&'//2,   % :Dcg_0, :Sep_0
   39    '*&'//3,   % :Dcg_1, :Sep_0, ?Args
   40    '+&'//2,   % :Dcg_0, :Sep_0
   41    '+&'//3,   % :Dcg_1, :Sep_0, ?Args
   42    'm*&'//3,  % ?M, :Dcg_0, :Sep_0
   43    'm*&'//4,  % ?M, :Dcg_1, :Sep_0, -Args
   44    '*&n'//3,  % ?N, :Dcg_0, :Sep_0
   45    '*&n'//4,  % ?N, :Dcg_1, :Sep_0, -Args
   46    'm*&n'//4, % ?M, ?N, :Dcg_0, :Sep_0
   47    'm*&n'//5, % ?M, ?N, :Dcg_1, :Sep_0, -Args
   48  % DETERMINISTIC SEQUENCE PATTERNS WITH SEPARATOR
   49    '#&!'//3,   % ?N, :Dcg_0, :Sep_0
   50    '#&!'//4,   % ?N, :Dcg_1, :Sep_0, -Args
   51    '*&!'//2,   % :Dcg_0, :Sep_0
   52    '*&!'//3,   % :Dcg_1, :Sep_0, ?Args
   53    '+&!'//2,   % :Dcg_0, :Sep_0
   54    '+&!'//3,   % :Dcg_1, :Sep_0, ?Args
   55    'm*&!'//3,  % ?M, :Dcg_0, :Sep_0
   56    'm*&!'//4,  % ?M, :Dcg_1, :Sep_0, -Args
   57    '*&n!'//3,  % ?N, :Dcg_0, :Sep_0
   58    '*&n!'//4,  % ?N, :Dcg_1, :Sep_0, -Args
   59    'm*&n!'//4, % ?M, ?N, :Dcg_0, :Sep_0
   60    'm*&n!'//5  % ?M, ?N, :Dcg_1, :Sep_0, -Args
   61  ]
   62).

RegEx-like extensions for DCG

This module introduces support for the variable repetition meta-syntactic construct as defined in RFC 5234. It also offers several other metasyntactic constructs that are specializations of variable repetition, including specific repetition (`#'), Kleene star (`*'), Kleene sum (`+'), and optional sequence (`?').

There are variants that allow a separator Sep_0 to be processed in between productions of Dcg_n. This covers several very common cases, like comma-separated lists or tokens separated by whitespace.

This module also defines the DCGs correlates to the ISO call/[1-8] predicates. Since DCGs take two extra predicate, we can only define dcg_call//[1,6].

See also
- https://tools.ietf.org/html/rfc5234

*/

Compatibility
- RFC 5234 ― Augmented BNF for Syntax Specifications: ABNF
   86:- use_module(library(dcg)).   87
   88:- meta_predicate
   89    #(+, //, ?, ?),
   90    #(+, 3, -, ?, ?),
   91    *(//, ?, ?),
   92    *(3, -, ?, ?),
   93    +(//, ?, ?),
   94    +(3, -, ?, ?),
   95    ?(//, ?, ?),
   96    ?(3, ?, ?, ?),
   97    'm*'(?, //, ?, ?),
   98    'm*'(?, 3, -, ?, ?),
   99    '*n'(?, //, ?, ?),
  100    '*n'(?, 3, -, ?, ?),
  101    'm*n'(?, ?, //, ?, ?),
  102    'm*n'(?, ?, 3, -, ?, ?),
  103    'm*n__g'(?, ?, +, //, ?, ?),
  104    'm*n__g'(?, ?, +, 3, -, ?, ?),
  105    'm*n__p'(?, ?, +, //, ?, ?),
  106    'm*n__p'(?, ?, +, 3, -, ?, ?),
  107    '#!'(+, //, ?, ?),
  108    '#!'(+, 3, -, ?, ?),
  109    '*!'(//, ?, ?),
  110    '*!'(3, -, ?, ?),
  111    '+!'(//, ?, ?),
  112    '+!'(3, -, ?, ?),
  113    '?!'(//, ?, ?),
  114    '?!'(3, ?, ?, ?),
  115    'm*!'(?, //, ?, ?),
  116    'm*!'(?, 3, -, ?, ?),
  117    '*n!'(?, //, ?, ?),
  118    '*n!'(?, 3, -, ?, ?),
  119    'm*n!'(?, ?, //, ?, ?),
  120    'm*n!'(?, ?, 3, -, ?, ?),
  121    'm*n__g!'(?, ?, +, //, ?, ?),
  122    'm*n__g!'(?, ?, +, 3, -, ?, ?),
  123    'm*n__p!'(?, ?, +, //, ?, ?),
  124    'm*n__p!'(?, ?, +, 3, -, ?, ?),
  125    #&(+, //, //, ?, ?),
  126    #&(+, 3, //, -, ?, ?),
  127    *&(//, //, ?, ?),
  128    *&(3, //, -, ?, ?),
  129    +&(//, //, ?, ?),
  130    +&(3, //, -, ?, ?),
  131    'm*&'(?, //, //, ?, ?),
  132    'm*&'(?, 3, //, -, ?, ?),
  133    '*&n'(?, //, //, ?, ?),
  134    '*&n'(?, 3, //, -, ?, ?),
  135    'm*&n'(?, ?, //, //, ?, ?),
  136    'm*&n'(?, ?, 3, //, -, ?, ?),
  137    'm*&n__g'(?, ?, +, //, //, ?, ?),
  138    'm*&n__g'(?, ?, +, 3, //, -, ?, ?),
  139    'm*&n__p'(?, ?, +, //, //, ?, ?),
  140    'm*&n__p'(?, ?, +, 3, //, -, ?, ?),
  141    '#&!'(+, //, //, ?, ?),
  142    '#&!'(+, 3, //, -, ?, ?),
  143    '*&!'(//, //, ?, ?),
  144    '*&!'(3, //, -, ?, ?),
  145    '+&!'(//, //, ?, ?),
  146    '+&!'(3, //, -, ?, ?),
  147    'm*&!'(?, //, //, ?, ?),
  148    'm*&!'(?, 3, //, -, ?, ?),
  149    '*&n!'(?, //, //, ?, ?),
  150    '*&n!'(?, 3, //, -, ?, ?),
  151    'm*&n!'(?, ?, //, //, ?, ?),
  152    'm*&n!'(?, ?, 3, //, -, ?, ?),
  153    'm*&n__g!'(?, ?, +, //, //, ?, ?),
  154    'm*&n__g!'(?, ?, +, 3, //, -, ?, ?),
  155    'm*&n__p!'(?, ?, +, //, //, ?, ?),
  156    'm*&n__p!'(?, ?, +, 3, //, -, ?, ?).
 ?N # :Dcg_0// is semidet
 #(?N, :Dcg_1, ?Args:list)// is semidet
  163#(N, Dcg_0) -->
  164  'm*n'(N, N, Dcg_0).
  165
  166
  167#(N, Dcg_1, Args) -->
  168  'm*n'(N, N, Dcg_1, Args).
 *(:Dcg_0)// is nondet
 :Dcg_1 * ?Args:list// is nondet
  175*(Dcg_0) -->
  176  'm*n'(0, _, Dcg_0).
  177
  178
  179*(Dcg_1, Args) -->
  180  'm*n'(0, _, Dcg_1, Args).
 + :Dcg_0// is nondet
 :Dcg_1 + ?Args:list// is nondet
  187+(Dcg_0) -->
  188  'm*n'(1, _, Dcg_0).
  189
  190
  191+(Dcg_1, Args) -->
  192  'm*n'(1, _, Dcg_1, Args).
 ?(:Dcg_0)// is nondet
 :Dcg_1 ? ?Arg// is nondet
  199?(Dcg_0) -->
  200  Dcg_0.
  201?(_) --> "".
  202
  203
  204?(Dcg_1, Arg) -->
  205  dcg_call(Dcg_1, Arg).
  206?(_, _) --> "".
 m*(?M:nonneg, :Dcg_0)// is nondet
 m*(?M:nonneg, :Dcg_1, ?Args:list)// is nondet
  213'm*'(M, Dcg_0) -->
  214  'm*n'(M, _, Dcg_0).
  215
  216
  217'm*'(M, Dcg_1, Args) -->
  218  'm*n'(M, _, Dcg_1, Args).
 *n(?N:nonneg, :Dcg_0)// is nondet
 *n(?N:nonneg, :Dcg_1, ?Args:list)// is nondet
  225'*n'(N, Dcg_0) -->
  226  'm*n'(_, N, Dcg_0).
  227
  228'*n'(N, Dcg_1, Args) -->
  229  'm*n'(_, N, Dcg_1, Args).
 m*n(?M:nonneg, ?N:nonneg, :Dcg_0)// is nondet
 m*n(?M:nonneg, ?N:nonneg, :Dcg_1, ?Args:list)// is nondet
  236'm*n'(M, N, Dcg_0) -->
  237  parsing, !,
  238  'm*n__p'(M, N, 0, Dcg_0).
  239'm*n'(M, N, Dcg_0) -->
  240  'm*n__g'(M, N, 0, Dcg_0).
  241
  242'm*n__g'(M, _, Count, _) -->
  243  {(var(M) -> true ; M =< Count)}.
  244'm*n__g'(M, N, Count1, Dcg_0) -->
  245  {(var(N) -> true ; Count1 < N)},
  246  Dcg_0,
  247  {Count2 is Count1 + 1},
  248  'm*n__g'(M, N, Count2, Dcg_0).
  249
  250'm*n__p'(M, N, Count1, Dcg_0) -->
  251  {(var(N) -> true ; Count1 < N)},
  252  Dcg_0,
  253  {Count2 is Count1 + 1},
  254  'm*n__p'(M, N, Count2, Dcg_0).
  255'm*n__p'(M, _, Count, _) -->
  256  {(var(M) -> true ; M =< Count)}.
  257
  258
  259'm*n'(M, N, Dcg_1, Args) -->
  260  parsing, !,
  261  'm*n__p'(M, N, 0, Dcg_1, Args).
  262'm*n'(M, N, Dcg_1, Args) -->
  263  'm*n__g'(M, N, 0, Dcg_1, Args).
  264
  265'm*n__g'(M, _, Count, _, []) -->
  266  {(var(M) -> true ; M =< Count)}.
  267'm*n__g'(M, N, Count1, Dcg_1, [H|T]) -->
  268  {(var(N) -> true ; Count1 < N)},
  269  dcg_call(Dcg_1, H),
  270  {Count2 is Count1 + 1},
  271  'm*n__g'(M, N, Count2, Dcg_1, T).
  272
  273'm*n__p'(M, N, Count1, Dcg_1, [H|T]) -->
  274  {(var(N) -> true ; Count1 < N)},
  275  dcg_call(Dcg_1, H),
  276  {Count2 is Count1 + 1},
  277  'm*n__p'(M, N, Count2, Dcg_1, T).
  278'm*n__p'(M, _, Count, _, []) -->
  279  {(var(M) -> true ; M =< Count)}.
 #!(?N, :Dcg_0)// is semidet
 #!(?N, :Dcg_1, ?Args:list)// is semidet
  286'#!'(N, Dcg_0) -->
  287  'm*n!'(N, N, Dcg_0).
  288
  289
  290'#!'(N, Dcg_1, Args) -->
  291  'm*n!'(N, N, Dcg_1, Args).
 *!(:Dcg_0)// is nondet
 *!(:Dcg_1, ?Args:list)// is nondet
  298'*!'(Dcg_0) -->
  299  'm*n!'(0, _, Dcg_0).
  300
  301
  302'*!'(Dcg_1, Args) -->
  303  'm*n!'(0, _, Dcg_1, Args).
 +!(:Dcg_0)// is nondet
 +!(:Dcg_1, ?Args:list)// is nondet
  310'+!'(Dcg_0) -->
  311  'm*n!'(1, _, Dcg_0).
  312
  313
  314'+!'(Dcg_1, Args) -->
  315  'm*n!'(1, _, Dcg_1, Args).
 ?!(:Dcg_0)// is nondet
 ?!(:Dcg_1, ?Arg)// is nondet
  322'?!'(Dcg_0) -->
  323  Dcg_0, !.
  324'?!'(_) --> "".
  325
  326
  327'?!'(Dcg_1, Arg) -->
  328  dcg_call(Dcg_1, Arg), !.
  329'?!'(_, _) --> "".
 m*!(?M:nonneg, :Dcg_0)// is nondet
 m*!(?M:nonneg, :Dcg_1, ?Args:list)// is nondet
  336'm*!'(M, Dcg_0) -->
  337  'm*n!'(M, _, Dcg_0).
  338
  339
  340'm*!'(M, Dcg_1, Args) -->
  341  'm*n!'(M, _, Dcg_1, Args).
 *n!(?N:nonneg, :Dcg_0)// is nondet
 *n!(?N:nonneg, :Dcg_1, ?Args:list)// is nondet
  348'*n!'(N, Dcg_0) -->
  349  'm*n!'(_, N, Dcg_0).
  350
  351'*n!'(N, Dcg_1, Args) -->
  352  'm*n!'(_, N, Dcg_1, Args).
 m*n!(?M:nonneg, ?N:nonneg, :Dcg_0)// is nondet
 m*n!(?M:nonneg, ?N:nonneg, :Dcg_1, ?Args:list)// is nondet
  359'm*n!'(M, N, Dcg_0) -->
  360  parsing, !,
  361  'm*n__p!'(M, N, 0, Dcg_0).
  362'm*n!'(M, N, Dcg_0) -->
  363  'm*n__g!'(M, N, 0, Dcg_0).
  364
  365'm*n__g!'(M, _, Count, _) -->
  366  {(var(M) -> true ; M =< Count)}, !.
  367'm*n__g!'(M, N, Count1, Dcg_0) -->
  368  {(var(N) -> true ; Count1 < N)},
  369  Dcg_0,
  370  {Count2 is Count1 + 1},
  371  'm*n__g!'(M, N, Count2, Dcg_0).
  372
  373'm*n__p!'(M, N, Count1, Dcg_0) -->
  374  {(var(N) -> true ; Count1 < N)},
  375  Dcg_0, !,
  376  {Count2 is Count1 + 1},
  377  'm*n__p!'(M, N, Count2, Dcg_0).
  378'm*n__p!'(M, _, Count, _) -->
  379  {(var(M) -> true ; M =< Count)}.
  380
  381
  382'm*n!'(M, N, Dcg_1, Args) -->
  383  parsing, !,
  384  'm*n__p!'(M, N, 0, Dcg_1, Args).
  385'm*n!'(M, N, Dcg_1, Args) -->
  386  'm*n__g!'(M, N, 0, Dcg_1, Args).
  387
  388'm*n__g!'(M, _, Count, _, []) -->
  389  {(var(M) -> true ; M =< Count)}, !.
  390'm*n__g!'(M, N, Count1, Dcg_1, [H|T]) -->
  391  {(var(N) -> true ; Count1 < N)},
  392  dcg_call(Dcg_1, H),
  393  {Count2 is Count1 + 1},
  394  'm*n__g!'(M, N, Count2, Dcg_1, T).
  395
  396'm*n__p!'(M, N, Count1, Dcg_1, [H|T]) -->
  397  {(var(N) -> true ; Count1 < N)},
  398  dcg_call(Dcg_1, H), !,
  399  {Count2 is Count1 + 1},
  400  'm*n__p!'(M, N, Count2, Dcg_1, T).
  401'm*n__p!'(M, _, Count, _, []) -->
  402  {(var(M) -> true ; M =< Count)}.
 #&(?N, :Dcg_0, :Sep_0)// is semidet
 #&(?N, :Dcg_1, :Sep_0, ?Args:list)// is semidet
  409#&(N, Dcg_0, Sep_0) -->
  410  'm*&n'(N, N, Dcg_0, Sep_0).
  411
  412
  413#&(N, Dcg_1, Sep_0, Args) -->
  414  'm*&n'(N, N, Dcg_1, Sep_0, Args).
 *&(:Dcg_0, :Sep_0)// is nondet
 *&(:Dcg_1, :Sep_0, ?Args:list)// is nondet
  421*&(Dcg_0, Sep_0) -->
  422  'm*&n'(0, _, Dcg_0, Sep_0).
  423
  424
  425*&(Dcg_1, Sep_0, Args) -->
  426  'm*&n'(0, _, Dcg_1, Sep_0, Args).
 +&(:Dcg_0, :Sep_0)// is nondet
 +&(:Dcg_1, :Sep_0, ?Args:list)// is nondet
  433+&(Dcg_0, Sep_0) -->
  434  'm*&n'(1, _, Dcg_0, Sep_0).
  435
  436
  437+&(Dcg_1, Sep_0, Args) -->
  438  'm*&n'(1, _, Dcg_1, Sep_0, Args).
 m*&(?M:nonneg, :Dcg_0, :Sep_0)// is nondet
 m*&(?M:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is nondet
  445'm*&'(M, Dcg_0, Sep_0) -->
  446  'm*&n'(M, _, Dcg_0, Sep_0).
  447
  448
  449'm*&'(M, Dcg_1, Sep_0, Args) -->
  450  'm*&n'(M, _, Dcg_1, Sep_0, Args).
 *&n(?N:nonneg, :Dcg_0, :Sep_0)// is nondet
 *&n(?N:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is nondet
  457'*&n'(N, Dcg_0, Sep_0) -->
  458  'm*&n'(_, N, Dcg_0, Sep_0).
  459
  460'*&n'(N, Dcg_1, Sep_0, Args) -->
  461  'm*&n'(_, N, Dcg_1, Sep_0, Args).
 m*&n(?M:nonneg, ?N:nonneg, :Dcg_0, :Sep_0)// is nondet
 m*&n(?M:nonneg, ?N:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is nondet
Notice that it is possible for a production of ~Sep_0~ to appear after the last production of ~Dcg_n~. This meand that eager parsing must cut after ~(Sep_0, Dcg_n)~, and not after ~Sep_0~ alone.
  472'm*&n'(M, N, Dcg_0, Sep_0) -->
  473  parsing, !,
  474  'm*&n__p'(M, N, 0, Dcg_0, Sep_0).
  475'm*&n'(M, N, Dcg_0, Sep_0) -->
  476  'm*&n__g'(M, N, 0, Dcg_0, Sep_0).
  477
  478'm*&n__g'(M, _, Count, _, _) -->
  479  {(var(M) -> true ; M =< Count)}.
  480'm*&n__g'(M, N, Count1, Dcg_0, Sep_0) -->
  481  {(var(N) -> true ; Count1 < N)},
  482  ({Count1 =:= 0} -> "" ; Sep_0),
  483  Dcg_0,
  484  {Count2 is Count1 + 1},
  485  'm*&n__g'(M, N, Count2, Dcg_0, Sep_0).
  486
  487'm*&n__p'(M, N, Count1, Dcg_0, Sep_0) -->
  488  {(var(N) -> true ; Count1 < N)},
  489  ({Count1 =:= 0} -> "" ; Sep_0),
  490  Dcg_0,
  491  {Count2 is Count1 + 1},
  492  'm*&n__p'(M, N, Count2, Dcg_0, Sep_0).
  493'm*&n__p'(M, _, Count, _, _) -->
  494  {(var(M) -> true ; M =< Count)}.
  495
  496
  497'm*&n'(M, N, Dcg_1, Sep_0, Args) -->
  498  parsing, !,
  499  'm*&n__p'(M, N, 0, Dcg_1, Sep_0, Args).
  500'm*&n'(M, N, Dcg_1, Sep_0, Args) -->
  501  'm*&n__g'(M, N, 0, Dcg_1, Sep_0, Args).
  502
  503'm*&n__g'(M, _, Count, _, _, []) -->
  504  {(var(M) -> true ; M =< Count)}.
  505'm*&n__g'(M, N, Count1, Dcg_1, Sep_0, [H|T]) -->
  506  {(var(N) -> true ; Count1 < N)},
  507  ({Count1 =:= 0} -> "" ; Sep_0),
  508  dcg_call(Dcg_1, H),
  509  {Count2 is Count1 + 1},
  510  'm*&n__g'(M, N, Count2, Dcg_1, Sep_0, T).
  511
  512'm*&n__p'(M, N, Count1, Dcg_1, Sep_0, [H|T]) -->
  513  {(var(N) -> true ; Count1 < N)},
  514  ({Count1 =:= 0} -> "" ; Sep_0),
  515  dcg_call(Dcg_1, H),
  516  {Count2 is Count1 + 1},
  517  'm*&n__p'(M, N, Count2, Dcg_1, Sep_0, T).
  518'm*&n__p'(M, _, Count, _, _, []) -->
  519  {(var(M) -> true ; M =< Count)}.
 #&!(?N, :Dcg_0, :Sep_0)// is semidet
 #&!(?N, :Dcg_1, :Sep_0, ?Args:list)// is semidet
  526'#&!'(N, Dcg_0, Sep_0) -->
  527  'm*&n!'(N, N, Dcg_0, Sep_0).
  528
  529
  530'#&!'(N, Dcg_1, Sep_0, Args) -->
  531  'm*&n!'(N, N, Dcg_1, Sep_0, Args).
 *&!(:Dcg_0, :Sep_0)// is det
 *&!(:Dcg_1, :Sep_0, ?Args:list)// is det
  538'*&!'(Dcg_0, Sep_0) -->
  539  'm*&n!'(0, _, Dcg_0, Sep_0).
  540
  541
  542'*&!'(Dcg_1, Sep_0, Args) -->
  543  'm*&n!'(0, _, Dcg_1, Sep_0, Args).
 +&!(:Dcg_0, :Sep_0)// is det
 +&!(:Dcg_1, :Sep_0, ?Args:list)// is det
  550'+&!'(Dcg_0, Sep_0) -->
  551  'm*&n!'(1, _, Dcg_0, Sep_0).
  552
  553
  554'+&!'(Dcg_1, Sep_0, Args) -->
  555  'm*&n!'(1, _, Dcg_1, Sep_0, Args).
 m*&!(?M:nonneg, :Dcg_0, :Sep_0)// is det
 m*&!(?M:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is det
  562'm*&!'(M, Dcg_0, Sep_0) -->
  563  'm*&n!'(M, _, Dcg_0, Sep_0).
  564
  565
  566'm*&!'(M, Dcg_1, Sep_0, Args) -->
  567  'm*&n!'(M, _, Dcg_1, Sep_0, Args).
 *&n!(?N:nonneg, :Dcg_0, :Sep_0)// is det
 *&n!(?N:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is det
  574'*&n!'(N, Dcg_0, Sep_0) -->
  575  'm*&n!'(_, N, Dcg_0, Sep_0).
  576
  577
  578'*&n!'(N, Dcg_1, Sep_0, Args) -->
  579  'm*&n!'(_, N, Dcg_1, Sep_0, Args).
 m*&n!(?M:nonneg, ?N:nonneg, :Dcg_0, :Sep_0)// is det
 m*&n!(?M:nonneg, ?N:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is det
Notice that it is possible for a production of ~Sep_0~ to appear after the last production of ~Dcg_n~. This meand that eager parsing must cut after ~(Sep_0, Dcg_n)~, and not after ~Sep_0~ alone.
  590'm*&n!'(M, N, Dcg_0, Sep_0) -->
  591  parsing, !,
  592  'm*&n__p!'(M, N, 0, Dcg_0, Sep_0).
  593'm*&n!'(M, N, Dcg_0, Sep_0) -->
  594  'm*&n__g!'(M, N, 0, Dcg_0, Sep_0).
  595
  596'm*&n__g!'(M, _, Count, _, _) -->
  597  {(var(M) -> true ; M =< Count)}, !.
  598'm*&n__g!'(M, N, Count1, Dcg_0, Sep_0) -->
  599  {(var(N) -> true ; Count1 < N)},
  600  ({Count1 =:= 0} -> "" ; Sep_0),
  601  Dcg_0,
  602  {Count2 is Count1 + 1},
  603  'm*&n__g!'(M, N, Count2, Dcg_0, Sep_0).
  604
  605'm*&n__p!'(M, N, Count1, Dcg_0, Sep_0) -->
  606  {(var(N) -> true ; Count1 < N)},
  607  ({Count1 =:= 0} -> "" ; Sep_0),
  608  Dcg_0,
  609  {Count2 is Count1 + 1},
  610  'm*&n__p!'(M, N, Count2, Dcg_0, Sep_0).
  611'm*&n__p!'(M, _, Count, _, _) -->
  612  {(var(M) -> true ; M =< Count)}.
  613
  614
  615'm*&n!'(M, N, Dcg_1, Sep_0, Args) -->
  616  parsing, !,
  617  'm*&n__p!'(M, N, 0, Dcg_1, Sep_0, Args).
  618'm*&n!'(M, N, Dcg_1, Sep_0, Args) -->
  619  'm*&n__g!'(M, N, 0, Dcg_1, Sep_0, Args).
  620
  621'm*&n__g!'(M, _, Count, _, _, []) -->
  622  {(var(M) -> true ; M =< Count)}, !.
  623'm*&n__g!'(M, N, Count1, Dcg_1, Sep_0, [H|T]) -->
  624  {(var(N) -> true ; Count1 < N)},
  625  ({Count1 =:= 0} -> "" ; Sep_0),
  626  dcg_call(Dcg_1, H),
  627  {Count2 is Count1 + 1},
  628  'm*&n__g!'(M, N, Count2, Dcg_1, Sep_0, T).
  629
  630'm*&n__p!'(M, N, Count1, Dcg_1, Sep_0, [H|T]) -->
  631  {(var(N) -> true ; Count1 < N)},
  632  ({Count1 =:= 0} -> "" ; Sep_0),
  633  dcg_call(Dcg_1, H),
  634  {Count2 is Count1 + 1},
  635  'm*&n__p!'(M, N, Count2, Dcg_1, Sep_0, T).
  636'm*&n__p!'(M, _, Count, _, _, []) -->
  637  {(var(M) -> true ; M =< Count)}