anchor.diff:  EQUAL
       : '='
       ;
  -
  +fragment
   LESS
       : '<'
       ;
  
positive.code:     : '-'
      ;
  
  ASTERISK
      : '*'
      ;
  
  COMMA
      : ','
      ;
  
  NOT
      : '!'
      ;
  
  
negative.code:     | A
      ;
  
  triplesSameSubjectPath
      : varOrTerm propertyListNotEmptyPath 
      | triplesNode propertyListPath
      ;
    
  propertyListNotEmptyPath
      : ( verbPath | verbSimple ) objectList ( SEMICOLON ( ( verbPath | verbSimple ) objectList )? )* //-> verbPath* verbSimple* objectList verbPath* 
      ;
      
  propertyListPath
      : propertyListNotEmpty?
      ;
      
  verbPath
      : path
      ;
      
  verbSimple
      : var
      ;
      	
  path
      : pathSequence ( PIPE pathSequence )*
      ; 
  
  pathSequence
      : pathEltOrInverse ( DIVIDE pathEltOrInverse )*
      ;
      	  	
  pathElt
      : pathPrimary pathMod?
      ;
      
  pathEltOrInverse
      : pathElt | INVERSE pathElt
      ;
      
  pathMod
      : ( ASTERISK | QUESTION_MARK | PLUS | OPEN_CURLY_BRACE ( INTEGER ( COMMA ( CLOSE_CURLY_BRACE | INTEGER CLOSE_CURLY_BRACE ) | CLOSE_CURLY_BRACE ) | COMMA INTEGER CLOSE_CURLY_BRACE ) )
      ;
  
  pathPrimary
      : ( iriRef | A | NEGATION pathNegatedPropertySet | OPEN_BRACE path CLOSE_BRACE )
      ;
  
  pathNegatedPropertySet
      : ( pathOneInPropertySet | OPEN_BRACE ( pathOneInPropertySet ( PIPE pathOneInPropertySet )* )? CLOSE_BRACE )
      ;  	
  
  pathOneInPropertySet
      : INVERSE? ( iriRef | A )
      ;
  	
  triplesNode
      : OPEN_BRACE graphNode+ CLOSE_BRACE -> ^(COLLECTION graphNode+)
      | OPEN_SQUARE_BRACKET propertyListNotEmpty CLOSE_SQUARE_BRACKET -> ^(BLANKNODEPROPERTYLIST propertyListNotEmpty)
      ;
  
  graphNode
  