I'm working on implementation of the Google Protobuf compiler for proto files in Prolog for generating Prolog programs. Prolog is SWI-Prolog.
I'm translating EBNF definitions into DCG and ran across a few problems:
I have to deal with
[ ... ]
and{ ... }
EBNF construct - meaningoptional
( executable zero or one times ) andrepeatative
( executable any number of times );I have to insert the callbacks into DCG code to implement the part of compiler functionality (syntax switching/importing/ etc.) using DCG's construct
{ ... }
, which allows goals in Prolog syntax inside DCG rules.
I'm applying for optional
and repeatative
the meta-predicates: $$rep/1
, $$opt/1
:
EBNF
decimals = decimalDigit { decimalDigit }
exponent = ( "e" | "E" ) [ "+" | "-" ] decimals
DCG
decimals --> decimalDigit, '$$rep'( decimalDigit ).
exponent --> ( "e"; "E" ), '$$opt'( "+"; "-" ), decimals.
'$$rep'( Goal ) :- repeat, call(Goal); !, fail.
'$$opt'( Goal ) :- once(Goal) ; \+ Goal.
"Callback:"
import --> "import", opt(( "weak" ; "public", { record(public)} )), strLit,
{
import(public, strlit )
}, ";".
Looking awkward (if not to say ugly) for me...
Questions:
What's wrong with my solutions?
Should I manually translate EBNG into DCG without using meta-predicates?
What is the alternative for the awkward penetration into a DCG rule?
repeatatives
(zero or more ) usually is something like this: decimals([]) --> []. decimals([ D | Ds ]) --> decimal(D), !, decimals(Ds). – Shiftless