/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Turtle RDF 1.1 Gramamr.
// This is not the usual parser used by RIOT.
// RIOT has it's own tokenizer/parser which is faster.
// This grammar exists as a more convenient base for new languages.

options
{
//     // \ u processed in the input stream
//     JAVA_UNICODE_ESCAPE   = true ;
//     UNICODE_INPUT         = false ;

  // \ u processed after parsing.
  // strings, IRIs
  JAVA_UNICODE_ESCAPE   = false ;
  UNICODE_INPUT         = true ;

  STATIC                = false ;
//   DEBUG_PARSER          = true ;
//   DEBUG_TOKEN_MANAGER   = true ;
}

PARSER_BEGIN(TurtleJavacc)
/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.jena.riot.lang.extra.javacc;

import org.apache.jena.graph.*;
import org.apache.jena.riot.lang.extra.* ;

public class TurtleJavacc extends TurtleParserBase
{}
PARSER_END(TurtleJavacc)

// Entry point
void parse(): { }
{
  ByteOrderMark()
  (Statement())*
  <EOF>
}

void ByteOrderMark() : {}
{
  (<BOM>)?
}

void Statement() : {}
{
    Directive()
  | DirectiveOld()
//  | (TriplesSameSubject() (<DOT> | <EOF> ) )
  // Strict
  | (TriplesSameSubject() <DOT> )
}

void Directive() : { Token t ; String iri ; }
{
    <PREFIX> t = <PNAME_NS> iri = IRIREF()
    { String s = fixupPrefix(t.image, t.beginLine, t.beginColumn) ;
      setPrefix(s, iri, t.beginLine, t.beginColumn) ; }
 |
    t = <BASE> iri = IRIREF()
    { setBase(iri, t.beginLine, t.beginColumn) ; }
}

void DirectiveOld() : { Token t ; String iri ; }
{
    <PREFIX_OLD> t = <PNAME_NS> iri = IRIREF() <DOT>
    { String s = fixupPrefix(t.image, t.beginLine, t.beginColumn) ;
      setPrefix(s, iri, t.beginLine, t.beginColumn) ; }
 |
    t = <BASE_OLD> iri = IRIREF() <DOT>
    { setBase(iri, t.beginLine, t.beginColumn) ; }
}

Token AnyDirective() : { Token t ; }
{
    ( t = <PREFIX> | t = <BASE> ) { return t ; }
}

void TriplesSameSubject() : { Node s ; } 
{
  s = SubjectNode()
  PropertyListNotEmpty(s) 
|
  s = TriplesNode()
  PropertyList(s)
}

void PropertyList(Node s) : { }
{
  ( PropertyListNotEmpty(s) ) ?
}

void PropertyListNotEmpty(Node s) : { Node p = null ; }
{
    p = Verb()
    ObjectList(s, p)
    (<SEMICOLON> (p = Verb() ObjectList(s, p))? )*
}

void ObjectList(Node s, Node p): { Node o ; } 
{
  Object(s, p)
  ( <COMMA> Object(s, p) )*
}

void Object(Node s, Node p): { Node o ; }
{
  o = GraphNode() 
  { emitTriple(token.beginLine, token.beginColumn, s, p, o) ; }
}

Node Verb() : { Node p ; String iri;}
{
  ( iri = iri() { p = createNode(iri); }
  | <KW_A> { p = nRDFtype ; }
  )
  { return p ; }
}

// -------- Triple expansions

// Anything that can stand in a node slot and which is
// a number of triples

Node TriplesNode() : { Node n ; }
{
  n = Collection() { return n ; }
 |
  n = BlankNodePropertyList() { return n ; }
//  |
//   n = TripleStar() { return n ; }
}

Node BlankNodePropertyList() : { Token t ; }
{
  t = <LBRACKET> 
    { Node n = createBNode( t.beginLine, t.beginColumn) ; }
  PropertyListNotEmpty(n)
  <RBRACKET>
    { return n ; }
}

// The syntax for RDF* 
//Node TripleStar() : 
//     { Node s , p , o ; Token t ; }
// {
//   t = "<<"
//     { int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
//         id = createTripleId(beginLine, beginColumn() ;
//     }
//   s = GraphNode()
//   p = GraphNode()
//   o = GraphNode()
//   ">>"
//   { Node n = tripleStar(s, p, o);
//     return n;
//   }
// }
// 

// ------- RDF collections
// Ordering?

Node Collection() : 
    { Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; }
{
  t = <LPAREN>
  { int line = t.beginLine; int column = t.beginColumn;
    listStart(line, column);
  }
  (
    { Node cell = createListNode(line, column) ;
      if ( listHead == nRDFnil )
         listHead = cell ;
      if ( lastCell != null )
        listTriple(line, column, lastCell, nRDFrest,  cell) ;
    }
    n = GraphNode()
    {
      listTriple(line, column, cell, nRDFfirst, n) ;
      lastCell = cell ;
    }
  ) +
  // Not * here - "()" is handled separately.
  <RPAREN>
   { if ( lastCell != null )
       listTriple(line, column, lastCell, nRDFrest,  nRDFnil) ;
     listFinish(line, column);
     return listHead ; }
}

Node SubjectNode() : { Node s; String iri ;}
{
  s = BlankNode() { return s ; }
 |
   iri = iri() { return createNode(iri) ; }
}

Node GraphNode() : { Node n ; }
{
  n = GraphTerm() { return n ; }
 |
  n = TriplesNode() { return n ; }
}

Node GraphTerm() : { Node n ; String iri ; }
{
  iri = iri()        { return createNode(iri) ; }
| n = RDFLiteral()      { return n ; }
| n = NumericLiteral()  { return n ; }
| n = BooleanLiteral()  { return n ; }
| n = BlankNode()       { return n ; }   
  //  <LPAREN> <RPAREN>     { return nRDFnil ; }
| <NIL>  { return nRDFnil ; }
}

Node RDFLiteral() : { Token t ; String lex = null ; }
{
  lex = String()
  // Optional lang tag and datatype.
  { String lang = null ; String uri = null ; }
  (
    lang = LangTag()
  |
    <DATATYPE> uri = iri()
  )?
    { return createLiteral(lex, lang, uri) ; }
} 

String LangTag() : { Token t ; }
{
  // Enumerate the directives here because they look like language tags.
  ( t = <LANGTAG> | t = AnyDirective() )
  { String lang = stripChars(t.image, 1) ; return lang ; }
}

Node NumericLiteral() : { Token t ; }
{
  (
    t = <INTEGER> { return createLiteralInteger(t.image) ; }
  | t = <DECIMAL> { return createLiteralDecimal(t.image) ; }
  | t = <DOUBLE>  { return createLiteralDouble(t.image) ; }
  )
}

Node BooleanLiteral() : {}
{
  <TRUE> { return XSD_TRUE ; }
 |
  <FALSE> { return XSD_FALSE ; }
}

String String() : { Token t ; String lex ; }
{
  ( t = <STRING_LITERAL1> { lex = stripQuotes(t.image) ; }
  | t = <STRING_LITERAL2> { lex = stripQuotes(t.image) ; }
  | t = <STRING_LITERAL_LONG1> { lex = stripQuotes3(t.image) ; }
  | t = <STRING_LITERAL_LONG2> { lex = stripQuotes3(t.image) ; }
  )
    {
      lex = unescapeStr(lex,  t.beginLine, t.beginColumn) ;
      return lex ;
    }
}

String iri() : { String iri ; }
{
  iri = IRIREF() { return iri ; }
|
  iri = PrefixedName() { return iri ; }
}

String PrefixedName() : { Token t ; }
{
  ( t = <PNAME_LN>
    { return resolvePName(t.image, t.beginLine, t.beginColumn) ; }
  |
    t = <PNAME_NS>
    { return resolvePName(t.image, t.beginLine, t.beginColumn) ; }
  )
}

Node BlankNode() :  { Token t = null ; }
{
  t = <BLANK_NODE_LABEL>
    { return createBNode(t.image, t.beginLine, t.beginColumn) ; }  
|
//  <LBRACKET> <RBRACKET> { return createBNode(t.beginLine, t.beginColumn) ; }
  t = <ANON> { return createBNode(t.beginLine, t.beginColumn) ; }

}

String IRIREF() : { Token t ; }
{
  t = <IRIref>
  { return resolveQuotedIRI(t.image, t.beginLine, t.beginColumn) ; }
}

// ------------------------------------------
// Tokens

SKIP : { " " | "\t" | "\n" | "\r" | "\f" }

TOKEN: { <#WS: " " | "\t" | "\n" | "\r" | "\f"> }

SPECIAL_TOKEN :
{ <SINGLE_LINE_COMMENT: "#" (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > }

TOKEN : // Case sensitive tokens.
{
  <KW_A:  "a" >
| < PREFIX_OLD:      "@prefix" >
| < BASE_OLD:        "@base" > 
}

TOKEN [IGNORE_CASE] :
{
   < BASE:        "base" >
|  < PREFIX:      "prefix" >

|  < TRUE:        "true" >
|  < FALSE:       "false" >
}

TOKEN :
{
  <#WSC:     <WS> | <SINGLE_LINE_COMMENT> >
| < BOM:     "\uFEFF">

|  <IRIref:  "<"
               ( ~[ ">","<", "\"", "{", "}", "^", "\\", "|", "`","\u0000"-"\u0020"]
               | <UCHAR>
               )*
             ">" >

| < PLUS:    "+" >
| < MINUS:   "-" >

| <#DIGITS:        (["0"-"9"])+>
| <INTEGER:        (<PLUS>|<MINUS>)? <DIGITS> >
| <DECIMAL:        (<PLUS>|<MINUS>)? (<DIGITS>)? "." <DIGITS> >
| <DOUBLE:         (<PLUS>|<MINUS>)?
                     ( (["0"-"9"])+ "." (["0"-"9"])* <EXPONENT>
                     | "." (["0"-"9"])+ (<EXPONENT>)
			         | (["0"-"9"])+ <EXPONENT>
                     ) >
			 
| < #EXPONENT:   ["e","E"] (["+","-"])? (["0"-"9"])+ >

| < #QUOTE_3D:   "\"\"\"" >
| < #QUOTE_3S:   "'''">

| < #ECHAR:      "\\" ( "t"|"b"|"n"|"r"|"f"|"\\"|"\""|"'") >
| < #UCHAR:      <UCHAR4> | <UCHAR8> >
| < #UCHAR4:     "\\" "u" <HEX> <HEX> <HEX> <HEX> >
| < #UCHAR8:     "\\" "U" <HEX> <HEX> <HEX> <HEX> <HEX> <HEX> <HEX> <HEX> >

| < STRING_LITERAL1: 
      // Single quoted string
      "'" ( (~["'","\\","\n","\r"]) | <ECHAR> | <UCHAR> )* "'" > 
| < STRING_LITERAL2:
    // Double quoted string
      "\"" ( (~["\"","\\","\n","\r"]) | <ECHAR> | <UCHAR> )* "\"" >
| < STRING_LITERAL_LONG1:
     <QUOTE_3S> 
      ( ("'" | "''")? (~["'","\\"] | <ECHAR> | <UCHAR> ))*
     <QUOTE_3S> >

| < STRING_LITERAL_LONG2: 
     <QUOTE_3D> 
      ( ("\"" | "\"\"")? (~["\"","\\"] | <ECHAR> | <UCHAR> ))*
     <QUOTE_3D> >

| < LPAREN:    "(" >
| < RPAREN:    ")" >

// All the stuff for NUL is needed just to make a 
// single list "() ." as a triple pattern illegal.
// It leads to a lot of extra work.
// Similarly [].

| <NIL: <LPAREN> (<WSC>)* <RPAREN> >

| < LBRACE:    "{" >
| < RBRACE:    "}" >

| < LBRACKET:  "[" >
| < RBRACKET:  "]" >
| < ANON:      <LBRACKET> (<WSC>)* <RBRACKET> >

| < SEMICOLON: ";" >
| < COMMA:     "," >
| < DOT:       "." >

| < DATATYPE: "^^">
| < AT: "@">

|  <PNAME_NS: (<PN_PREFIX>)? ":" >
|  <PNAME_LN: <PNAME_NS> <PN_LOCAL> >
|  <BLANK_NODE_LABEL: "_:" (<PN_CHARS_U> | ["0"-"9"]) ((<PN_CHARS>|".")* <PN_CHARS>)?  >
|  <LANGTAG: <AT> (<A2Z>)+("-" (<A2ZN>)+)* >
|  <#A2Z: ["a"-"z","A"-"Z"]>
|  <#A2ZN: ["a"-"z","A"-"Z","0"-"9"]>

| <#PN_CHARS_BASE:
          ["A"-"Z"] | ["a"-"z"] |
          ["\u00C0"-"\u00D6"] | ["\u00D8"-"\u00F6"] | ["\u00F8"-"\u02FF"] |
          ["\u0370"-"\u037D"] | ["\u037F"-"\u1FFF"] |
          ["\u200C"-"\u200D"] | ["\u2070"-"\u218F"] | ["\u2C00"-"\u2FEF"] |
          ["\u3001"-"\uD7FF"] | ["\uF900"-"\uFFFD"]
          // | [#x10000-#xEFFFF]
          >
|
  // With underscore
  <#PN_CHARS_U: <PN_CHARS_BASE> | "_" >
|
  <#PN_CHARS: (<PN_CHARS_U> | "-" | ["0"-"9"] | "\u00B7" |
              ["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] ) >
|
  // No leading "_", no trailing ".", can have dot inside prefix name.
  <#PN_PREFIX: <PN_CHARS_BASE> ((<PN_CHARS>|".")* <PN_CHARS>)?  >
|
  // Local part.
  <#PN_LOCAL: (<PN_CHARS_U> | ":" | ["0"-"9"] | <PLX> ) 
              ( (<PN_CHARS> | "." |":" | <PLX> )* 
                (<PN_CHARS> | ":" | <PLX>) )?  >
|
  <#VARNAME: ( <PN_CHARS_U> | ["0"-"9"] )
             ( <PN_CHARS_U> | ["0"-"9"] | "\u00B7" |
               ["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] )* >
|
  < #PN_LOCAL_ESC: "\\" 
          ( "_" | 
            "~" | "." | "-" | "!" | "$" | "&" | "'" | 
           "(" | ")" | "*" | "+" | "," | ";" | "=" | 
           "/" | "?" | "#" | "@" | "%" ) >
|
  <#PLX:  <PERCENT> | <PN_LOCAL_ESC> >
|
  < #HEX: ["0"-"9"] | ["A"-"F"] | ["a"-"f"] >
|
  < #PERCENT: "%" <HEX> <HEX> >
}

// Catch-all tokens.  Must be last.  
// Any non-whitespace.  Causes a parser exception, rather than a
// token manager error (which hides the line numbers).
TOKEN:
{
  <#UNKNOWN: (~[" ","\t","\n","\r","\f" ])+ >
}

/*
# Local Variables:
# tab-width: 4
# indent-tabs-mode: nil
# comment-default-style: "//"
# End:
*/
