# Notation3 subset which is RDF without extension
# BNF without tokenization
#
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix bnf: <http://www.w3.org/2000/10/swap/grammar/bnf#>.
@prefix rul: <http://www.w3.org/2000/10/swap/grammar/bnf-rules#>.
@prefix : <http://www.w3.org/2000/10/swap/grammar/n3-rdf#>.
@prefix d3: <http://www.w3.org/2000/10/swap/grammar/n3-rdf#>.
@prefix n3: <http://www.w3.org/2000/10/swap/grammar/n3#>.
@prefix list: <http://www.w3.org/2000/10/swap/list#>.
@prefix string: <http://www.w3.org/2000/10/swap/string#>.
@keywords a, is, of.


# Issues:
# - string token regexp not right
# - tokenizing rules in general
# - @keywords affects tokenizing
# - Use of dot for !
# - datatypes and/or* languages in literals (*choice - follow RDF)

# tokenizing:
# Absorb anything until end of regexp, then stil white space
#  period followed IMMEDIATELY by an opener or name char is taken as "!".
#  Except after a "." used instead of in those circumstances,
#	ws may be inserted between tokens.
#  WS MUST be inserted between tokens where ambiguity would arise.
#  (possible ending characters of one and beginning characters overlap)
#

<> bnf:syntaxFor [ bnf:internetMediaType 
		<http://www.w3.org/2003/mediatypes#application/rdf+n3>].


# __________________________________________________________________
#
# The N3 Full Grammar

n3-rdfDocument
	bnf:mustBeOneSequence(
	
		(
			[ bnf:zeroOrMore declaration ]
			[ bnf:zeroOrMore existential ]
			statements_optional
			bnf:eof
		)
	).

statements_optional bnf:mustBeOneSequence (() ( statement "." statements_optional )e ).



statementlist bnf:mustBeOneSequence (
		( )
		( statement statementtail )
	).

statementtail bnf:mustBeOneSequence (
		( )
		( "." statementlist )
	).


existential bnf:mustBeOneSequence(
		(	 "@forSome" 
			 [ bnf:commaSeparatedPeriodTerminatedListOf symbol ]
		)).


symbol bnf:mustBeOneSequence (
		(explicituri)
		(qname)
	).


declaration bnf:mustBeOneSequence(
		( "@base" explicituri "." )
		( "@prefix" qname explicituri "." )
		( "@keywords" [ bnf:commaSeparatedPeriodTerminatedListOf barename ] )
	).


statement bnf:mustBeOneSequence(( subject propertylist )).

propertylist bnf:mustBeOneSequence (
		( )
		( verb  object objecttail propertylisttail )
	).

propertylisttail bnf:mustBeOneSequence (
		( )
		( ";" propertylist )
	).

objecttail bnf:mustBeOneSequence (
		( )
		( ","   object objecttail )
	).


verb bnf:mustBeOneSequence (
		( prop )
		( "@has" prop )
#		( "@is" prop "@of" )  
# would be complicated to allow - would need subjectlist.
		( "@a" )
		( "=" )
	).

prop bnf:mustBeOneSequence ((node)).


subject bnf:mustBeOneSequence(
		( node_subject "!" pathtail )
		( string "^" verb pathtail )
		( numericliteral "^" verb pathtail )
	).

object bnf:mustBeOneSequence(
		( node_object pathtail )   # @@@@@@@@
	).

pathtail bnf:mustBeOneSequence(
		(  )
		( "!" verb pathtail )
		( "^" verb pathtail )
	).


node_subject bnf:mustBeOneSequence (
		( symbol )
		( "[" propertylist "]"  )
		(  "("  objectlist ")"  )
).

node_object bnf:mustBeOneSequence (
		( symbol )
		( numericliteral )
		( string )
		( "[" propertylist "]"  )
		(  "("  itemlist ")"  )
).



objectlist bnf:mustBeOneSequence (() (object objectlist)).
 
#______________________________________________________________________
#
#   TOKENS

alphanumeric 	bnf:matches  	"[a-zA-Z][a-zA-Z0-9_]*";
		bnf:canStartWith	"a".

numericliteral	bnf:matches	"""[-+]?[0-9]+(\\.[0-9]+)?(e[-+]?[0-9]+)?""";
		bnf:canStartWith 	"0", "-", "+".

explicituri 	bnf:matches 	"<[^>].*>";
		bnf:canStartWith 	"<".

qname 		bnf:matches  	"(([a-zA-Z_][a-zA-Z0-9_]*)?:)?([a-zA-Z_][a-zA-Z0-9_]*)?";
		bnf:canStartWith 	"a", "_".  # @@ etc

barename 	bnf:matches  	"[a-zA-Z_][a-zA-Z0-9_]*";  # subset of qname
		bnf:canStartWith 	"a", "_".  # @@ etc


langcode	bnf:matches  	"[a-zA-Z0-9]+(-[a-zA-Z0-9]+)?";
		bnf:canStartWith 	"a".


string		bnf:matches		"(\"\"\"[^\"\\\\]*(?:(?:\\\\.|\"(?!\"\"))[^\"\\\\]*)*\"\"\")|(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\")";
		bnf:canStartWith 	"\"".

#____________________________________________________

#  Axioms reducing the shortcut BNF terms to bnf:musBeOneSequence.

{ ?x bnf:zeroOrMore ?y } => {?x bnf:mustBeOneSequence ( () (?y ?x) ) }.


{ ?x bnf:commaSeparatedPeriodTerminatedListOf ?y } =>
{
	?x bnf:mustBeOneSequence (
		( "." )
		( "," ?y ?x )
	)
}.


#  labelling of things which do not have explicit URIs:

{ ?x bnf:zeroOrMore [ bnf:label ?y].
	( ?y "_s" ) string:concatenation ?str } => { ?x bnf:label ?str }.

{ ?x bnf:commaSeparatedPeriodTerminatedListOf [ bnf:label ?y].
	( ?y "_csl" ) string:concatenation ?str } => { ?x bnf:label ?str }.


#ends
