Did you know ... Search Documentation:
Pack prolog_library_collection -- prolog/abnf.pl
PublicShow source

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
 ?N # :Dcg_0// is semidet
 #(?N, :Dcg_1, ?Args:list)// is semidet
 *(:Dcg_0)// is nondet
 :Dcg_1 * ?Args:list// is nondet
 + :Dcg_0// is nondet
 :Dcg_1 + ?Args:list// is nondet
 ? :Dcg_0// is nondet
 :Dcg_1 ? ?Arg// is nondet
 m*(?M:nonneg, :Dcg_0)// is nondet
 m*(?M:nonneg, :Dcg_1, ?Args:list)// is nondet
 *n(?N:nonneg, :Dcg_0)// is nondet
 *n(?N:nonneg, :Dcg_1, ?Args:list)// is nondet
 m*n(?M:nonneg, ?N:nonneg, :Dcg_0)// is nondet
 m*n(?M:nonneg, ?N:nonneg, :Dcg_1, ?Args:list)// is nondet
 #!(?N, :Dcg_0)// is semidet
 #!(?N, :Dcg_1, ?Args:list)// is semidet
 *!(:Dcg_0)// is nondet
 *!(:Dcg_1, ?Args:list)// is nondet
 +!(:Dcg_0)// is nondet
 +!(:Dcg_1, ?Args:list)// is nondet
 ?!(:Dcg_0)// is nondet
 ?!(:Dcg_1, ?Arg)// is nondet
 m*!(?M:nonneg, :Dcg_0)// is nondet
 m*!(?M:nonneg, :Dcg_1, ?Args:list)// is nondet
 *n!(?N:nonneg, :Dcg_0)// is nondet
 *n!(?N:nonneg, :Dcg_1, ?Args:list)// is nondet
 m*n!(?M:nonneg, ?N:nonneg, :Dcg_0)// is nondet
 m*n!(?M:nonneg, ?N:nonneg, :Dcg_1, ?Args:list)// is nondet
 #&(?N, :Dcg_0, :Sep_0)// is semidet
 #&(?N, :Dcg_1, :Sep_0, ?Args:list)// is semidet
 *&(:Dcg_0, :Sep_0)// is nondet
 *&(:Dcg_1, :Sep_0, ?Args:list)// is nondet
 +&(:Dcg_0, :Sep_0)// is nondet
 +&(:Dcg_1, :Sep_0, ?Args:list)// is nondet
 m*&(?M:nonneg, :Dcg_0, :Sep_0)// is nondet
 m*&(?M:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is nondet
 *&n(?N:nonneg, :Dcg_0, :Sep_0)// is nondet
 *&n(?N:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is nondet
 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.
 #&!(?N, :Dcg_0, :Sep_0)// is semidet
 #&!(?N, :Dcg_1, :Sep_0, ?Args:list)// is semidet
 *&!(:Dcg_0, :Sep_0)// is det
 *&!(:Dcg_1, :Sep_0, ?Args:list)// is det
 +&!(:Dcg_0, :Sep_0)// is det
 +&!(:Dcg_1, :Sep_0, ?Args:list)// is det
 m*&!(?M:nonneg, :Dcg_0, :Sep_0)// is det
 m*&!(?M:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is det
 *&n!(?N:nonneg, :Dcg_0, :Sep_0)// is det
 *&n!(?N:nonneg, :Dcg_1, :Sep_0, ?Args:list)// is det
 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.

Undocumented predicates

The following predicates are exported, but not or incorrectly documented.

 #(Arg1, Arg2, Arg3, Arg4, Arg5)
 *(Arg1, Arg2, Arg3, Arg4)
 +(Arg1, Arg2, Arg3, Arg4)
 ?(Arg1, Arg2, Arg3, Arg4)
 m*(Arg1, Arg2, Arg3, Arg4, Arg5)
 *n(Arg1, Arg2, Arg3, Arg4, Arg5)
 m*n(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 #!(Arg1, Arg2, Arg3, Arg4, Arg5)
 *!(Arg1, Arg2, Arg3, Arg4)
 +!(Arg1, Arg2, Arg3, Arg4)
 ?!(Arg1, Arg2, Arg3, Arg4)
 m*!(Arg1, Arg2, Arg3, Arg4, Arg5)
 *n!(Arg1, Arg2, Arg3, Arg4, Arg5)
 m*n!(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 #&(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 *&(Arg1, Arg2, Arg3, Arg4, Arg5)
 +&(Arg1, Arg2, Arg3, Arg4, Arg5)
 m*&(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 *&n(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 m*&n(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)
 #&!(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 *&!(Arg1, Arg2, Arg3, Arg4, Arg5)
 +&!(Arg1, Arg2, Arg3, Arg4, Arg5)
 m*&!(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 *&n!(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6)
 m*&n!(Arg1, Arg2, Arg3, Arg4, Arg5, Arg6, Arg7)