@prefix dc: <http://purl.org/dc/elements/1.1/>.  # @@ no #
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<> dc:description """reduce EBNF to BNF;
i.e. rewrite ?, +, * operators using alt and seq
""",
"$Id: ebnf2bnf.n3,v 1.7 2006/11/15 19:46:59 connolly Exp $";
rdfs:seeAlso <ebnf>, <ebnf.n3>, <ebnf.rdf>.

@prefix g: <http://www.w3.org/2000/10/swap/grammar/ebnf#>.

g:empty g:seq ().

{ ?A g:opt ?B } => { ?A g:alt ( g:empty ?B ) }.

{ ?A g:plus ?B } => { ?A g:seq ( ?B [ g:star ?B] ) }.

{ ?A g:star ?B } => { ?A g:alt ( g:empty [ g:seq (?B ?A) ] ) }.


# find all the non-terminals
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix list: <http://www.w3.org/2000/10/swap/list#>.

g:alt rdfs:domain g:Production.
{ ?S [ rdfs:domain ?C] [] } => { ?S a ?C }.

# empty is not a production
{ ?S g:seq [ rdf:rest []] } => { ?S a g:Production }.

{ ?L g:start ?A }
 => { ?A g:nonTerminal ?L }.
{ [ g:seq [ list:member ?A]] g:nonTerminal ?L.
  ?A a g:Production.
 }
 => { ?A g:nonTerminal ?L }.
{ [ g:alt [ list:member ?A]] g:nonTerminal ?L.
  ?A a g:Production.
 }
 => { ?A g:nonTerminal ?L }.


# and find all the terminals used in NonTerminal rules
@prefix log: <http://www.w3.org/2000/10/swap/log#>.

# promote literals to Terminals
{
  [ g:alt [ list:member ?T ]] g:nonTerminal ?L.
  ?T log:rawType log:Literal.
} => { ?L g:terminal ?T }.

{ [ g:seq [ list:member ?T ]] g:nonTerminal ?L.
  ?T log:rawType log:Literal.
} => { ?L g:terminal ?T }.

# find the Terminals that are used...
@prefix re: <http://www.w3.org/2000/10/swap/grammar/regex#>.
re:alt rdfs:domain re:Regex.
re:seq rdfs:domain re:Regex.
re:matches rdfs:domain re:Regex.
re:diff rdfs:domain re:Regex.
re:opt rdfs:domain re:Regex.
re:plus rdfs:domain re:Regex.
re:star rdfs:domain re:Regex.

{ [ g:alt [ list:member ?T ]] g:nonTerminal ?L.
  ?T a re:Regex.
} => { ?L g:terminal ?T }.

{ [ g:seq [ list:member ?T ]] g:nonTerminal ?L.
  ?T a re:Regex.
} => { ?L g:terminal ?T }.
