anchor.diff:  OR
       : '||'
       ;
  +    
  +INVERSE
  +    : '^'
  +    ;
   
   OPEN_BRACE
       : '('
  
positive.code:     | A
      ;
  
  triplesNode
      : collection
      | blankNodePropertyList
      ;
  
  blankNodePropertyList
      : OPEN_SQUARE_BRACE propertyListNotEmpty CLOSE_SQUARE_BRACE
      ;
  
  collection
      : OPEN_BRACE graphNode+ CLOSE_BRACE
      ;
  
  graphNode
  
negative.code: // $<Parser
  
  query
      : prologue ( selectQuery | constructQuery | describeQuery | askQuery ) EOF -> ^(QUERY prologue selectQuery* constructQuery* describeQuery* askQuery*)
      | update ( SEMICOLON update)* SEMICOLON? EOF -> ^(UPDATE update+)
      ;
  
  prologue
      : baseDecl? prefixDecl* -> ^(PROLOGUE baseDecl? prefixDecl*)
      ;
  
  baseDecl
      : BASE IRI_REF -> ^(BASE IRI_REF)
      ;
  
  prefixDecl
      : PREFIX PNAME_NS IRI_REF -> ^(PREFIX PNAME_NS IRI_REF)
      ;
  
  selectQuery
      : selectClause datasetClause* whereClause solutionModifier bindingsClause -> ^(SELECT selectClause datasetClause* whereClause* solutionModifier* bindingsClause*)
      ;
  
  subSelect
      : selectClause whereClause solutionModifier	-> ^(SUBSELECT whereClause* solutionModifier)
      ;
      	
  selectClause
      : SELECT ( DISTINCT | REDUCED )? ASTERISK -> ^(SELECTCLAUSE DISTINCT* REDUCED* ASTERISK)
      | SELECT ( DISTINCT | REDUCED )? (v+=selectVariables)+ -> ^(SELECTCLAUSE DISTINCT* REDUCED* $v*)
      ;
  
  selectVariables
      : v=var -> ^(VAR $v) 
      | OPEN_BRACE e=expression AS v=var CLOSE_BRACE -> ^(ALIAS $e $v)
      ;
    
  constructQuery
      : CONSTRUCT constructTemplate datasetClause* whereClause solutionModifier -> ^(CONSTRUCT constructTemplate* datasetClause* whereClause* solutionModifier*)
      ;
  
  describeQuery
      : DESCRIBE ( (v+=varOrIRIref)+ | ASTERISK ) datasetClause* whereClause? solutionModifier -> ^(DESCRIBE $v* ASTERISK* datasetClause* whereClause? solutionModifier*)
      ;
  
  askQuery
      : ASK datasetClause* whereClause -> ^(ASK datasetClause* whereClause)
      ;
  
  datasetClause
      : FROM NAMED? iriRef -> ^(FROM NAMED? iriRef)
      ;
  
  whereClause
      : WHERE? groupGraphPattern -> ^(WHERE_CLAUSE groupGraphPattern) // ^(WHERE groupGraphPattern) 
      ;
  
  solutionModifier
      : groupClause? havingClause? orderClause? limitOffsetClauses?
      ;
  
  groupClause
      : GROUP BY (g+=groupCondition)+ -> ^(GROUPBY $g+)
      ;
      		 
  groupCondition
      : builtInCall
      | functionCall
      | OPEN_BRACE expression (AS var)? CLOSE_BRACE -> ^(AS expression var*)
      | var
      ;
      
  havingClause
      : HAVING (c=constraint)+ -> ^(HAVING $c+)	
      ;
      
  orderClause
      : ORDER BY (o+=orderCondition)+ -> ^(ORDERBY $o+)
      ;
  
  orderCondition
      : ( ( ASC | DESC ) brackettedExpression ) -> ^(ORDERCONDITION ASC* DESC* brackettedExpression)
      | ( constraint | var ) -> ^(ORDERCONDITION constraint* var*)
      ;
  	    
  limitOffsetClauses
      : ( limitClause offsetClause? | offsetClause limitClause? )
      ;
  
  limitClause
      : LIMIT INTEGER -> ^(LIMIT INTEGER)
      ;
  
  offsetClause
      : OFFSET INTEGER -> ^(OFFSET INTEGER)
      ;
  
  bindingsClause
      : ( BINDINGS (v+=var)* OPEN_CURLY_BRACE ( b+=bindingsClauseCache )* CLOSE_CURLY_BRACE )? -> ^(BINDINGS $v* $b*)?
      ;
      
  bindingsClauseCache
      : OPEN_BRACE (b+=bindingValue)* CLOSE_BRACE	-> ^(BINDINGVALUE $b*)
      ;
      	
  bindingValue
      : iriRef | rdfLiteral | numericLiteral | booleanLiteral | UNDEF
      ;
      
  update
      : prologue (load | clear | drop | create | insert | delete | modify) -> ^(UPDATE load* clear* drop* create* insert* delete* modify*)
      ;   
      
  load 	  
      : LOAD SILENT? iriRef ( INTO graphRef )? -> ^(LOAD SILENT* iriRef graphRef*)
      ;
      
  clear
      : CLEAR  SILENT? graphRefAll -> ^(CLEAR SILENT* graphRefAll)
      ;
      
  drop
      : DROP SILENT? graphRefAll -> ^(DROP SILENT* graphRefAll)
      ; 
   
  create
      : CREATE SILENT? graphRef -> ^(CREATE SILENT* graphRef)
      ;
  
  insert
      : INSERT DATA quadPattern -> ^(INSERT DATA quadPattern) //( insertData | insertTemplate )
      ;
  /*    
  insertData
      : DATA quadPattern //( INTO? iriRef )* constructTemplate
      ;
      
  insertTemplate
      : ( INTO? iriRef )* constructTemplate whereClause?
      ;
  */    
  delete 	  
      : DELETE ( deleteData | deleteWhere )
      ;
  
  deleteData
      : DATA quadPattern -> ^(DELETE DATA quadPattern)//( FROM? iriRef )* constructTemplate
      ;
  
  deleteWhere
      : WHERE quadPattern -> ^(DELETE WHERE quadPattern) //( FROM? iriRef )* constructTemplate whereClause?
      ;
      
  modify
      : ( WITH iriRef )? ( deleteClause insertClause? | insertClause ) usingClause* WHERE groupGraphPattern
      ;
    
  deleteClause
      : DELETE quadPattern -> DELETE quadPattern
      ;
        
  insertClause
      : INSERT quadPattern
      ;
  
  usingClause
      : USING NAMED? iriRef -> ^(USING NAMED? iriRef)
      ;
      	    	
  graphRef
      : GRAPH iriRef
      ;
  
  graphRefAll
      : graphRef | DEFAULT | NAMED | ALL
      ;
  
  quadPattern
      : OPEN_CURLY_BRACE quads CLOSE_CURLY_BRACE -> quads
      ;
      
  quads
      : triplesTemplate? ( quadsNotTriples DOT? triplesTemplate? )*
      ;
      
  quadsNotTriples
      : GRAPH varOrIRIref OPEN_CURLY_BRACE triplesTemplate? CLOSE_CURLY_BRACE -> varOrIRIref triplesTemplate? // -> ^(GRAPH varOrIRIref triplesTemplate?)
      ;
      
  triplesTemplate
      : triplesSameSubject ( DOT triplesSameSubject )* DOT? -> ^(TRIPLESTEMPLATE triplesSameSubject+)
      ;
      	
  groupGraphPattern
      : OPEN_CURLY_BRACE ( subSelect | groupGraphPatternSub ) CLOSE_CURLY_BRACE -> ^(GROUPGRAPHPATTERN subSelect* groupGraphPatternSub*)
      ;
      
  groupGraphPatternSub
      : triplesBlock? ( groupGraphPatternSubCache )* -> triplesBlock* groupGraphPatternSubCache* //^(GRAPHPATTERNNOTTRIPLES
      ;
  
  groupGraphPatternSubCache
      :  graphPatternNotTriples DOT? triplesBlock? -> graphPatternNotTriples triplesBlock?
      ; 	
  
  triplesBlock
      : triplesSameSubjectPath ( DOT triplesSameSubjectPath)* DOT? -> ^(TRIPLESBLOCK triplesSameSubjectPath+)
      ;
  
  graphPatternNotTriples
      : groupOrUnionGraphPattern | optionalGraphPattern | minusGraphPattern | graphGraphPattern | serviceGraphPattern | filter
      ;
  
  optionalGraphPattern
      : OPTIONAL groupGraphPattern -> ^(OPTIONAL groupGraphPattern)
      ;
  
  graphGraphPattern
      : GRAPH varOrIRIref groupGraphPattern -> ^(GRAPH varOrIRIref groupGraphPattern)
      ;
  
  serviceGraphPattern
      : SERVICE varOrIRIref groupGraphPattern -> ^(SERVICE varOrIRIref groupGraphPattern)
      ;
      
  minusGraphPattern
      : MINUS_KEYWORD groupGraphPattern -> ^(MINUS_KEYWORD groupGraphPattern)
      ;
  
  groupOrUnionGraphPattern
      : groupGraphPattern ( UNION groupGraphPattern )* -> groupGraphPattern ^(UNION groupGraphPattern*)?
      ;
  
  filter
      : FILTER constraint -> ^(FILTER constraint)
      ;
  
  constraint
  