Skip to content

Instantly share code, notes, and snippets.

@kinow
Created December 21, 2014 03:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kinow/875851f7379abfcb4f13 to your computer and use it in GitHub Desktop.
Save kinow/875851f7379abfcb4f13 to your computer and use it in GitHub Desktop.
JavaCC for JENA-632 #1
/*
* 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.
*/
// ARQ/SPARQL 1.1 Grammar - native syntax for the query engine
#if 0
// (Run through cpp -P -C first)
#endif
#if !defined(ARQ) && !defined(SPARQL_11)
#error Please define one of ARQ and SPARQL_11
#endif
#if defined(ARQ) && defined(SPARQL_11)
#error Please define only one of ARQ and SPARQL_11
#endif
#ifdef SPARQL_11
#define PACKAGE lang.sparql_11
#define CLASS SPARQLParser11
#define PARSERBASE SPARQLParser11Base
#define UPDATE
#endif
#ifdef ARQ
#define PACKAGE lang.arq
#define CLASS ARQParser
#define PARSERBASE ARQParserBase
#define UPDATE
#endif
options
{
// \ u processed in the input stream
// SPARQL 1.0
JAVA_UNICODE_ESCAPE = true ;
UNICODE_INPUT = false ;
// // \ u processed after parsing.
// // strings, prefix names, IRIs
// JAVA_UNICODE_ESCAPE = false ;
// UNICODE_INPUT = true ;
STATIC = false ;
// DEBUG_PARSER = true ;
// DEBUG_TOKEN_MANAGER = true ;
}
PARSER_BEGIN(CLASS)
/**
* 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 com.hp.hpl.jena.sparql.PACKAGE ;
import com.hp.hpl.jena.graph.* ;
import com.hp.hpl.jena.query.* ;
import com.hp.hpl.jena.sparql.core.Var ;
import com.hp.hpl.jena.sparql.syntax.* ;
import com.hp.hpl.jena.sparql.expr.* ;
import com.hp.hpl.jena.sparql.path.* ;
import com.hp.hpl.jena.sparql.expr.aggregate.* ;
#ifdef UPDATE
import com.hp.hpl.jena.update.* ;
import com.hp.hpl.jena.sparql.modify.request.* ;
#endif
public class CLASS extends PARSERBASE
{
boolean allowAggregatesInExpressions = false ;
public static void main(String args[]) {
while (true) {
StringBuilder queryString = new StringBuilder();
java.util.Scanner scanner = new java.util.Scanner(System.in);
boolean firstEmptyLine = false;
System.out.print("Enter input: ");
while (true) {
String line = scanner.nextLine();
if ("".equals(line) || line == null) {
if (firstEmptyLine) break; // wait for a double ^\n
firstEmptyLine = true;
} else {
queryString.append(line + System.lineSeparator());
firstEmptyLine = false;
}
}
try {
Query query = QueryFactory.create(queryString.toString(),
"http://example/query-base", Syntax.syntaxARQ);
java.io.Reader in = new java.io.StringReader(queryString.toString());
CLASS parser = new CLASS(in);
parser.setQuery(query);
parser.QueryUnit();
System.out.println("Parsed query successfully!");
System.out.println("---" + System.lineSeparator());
} catch (Exception e) {
System.out.println("Parser error: " + e.getMessage());
e.printStackTrace(System.err);
}
}
}
}
PARSER_END(CLASS)
// // Common top for single entry point.
// void Top(): {}
// {
// ( Query() | Update() )
// <EOF>
// }
// Query only entry point
void QueryUnit(): { }
{
ByteOrderMark()
{ startQuery() ; }
Query() <EOF>
{ finishQuery() ; }
}
void Query() : { }
{
Prologue()
( LOOKAHEAD(2) SelectQuery() | ConstructQuery() | DescribeQuery() | AskQuery() | JsonTemplateQuery()
// #ifdef ARQ
// | JsonTemplateQuery()
// #endif
)
ValuesClause()
}
#ifdef UPDATE
void UpdateUnit() : {}
{
ByteOrderMark()
{ startUpdateRequest() ; }
Update()
<EOF>
{ finishUpdateRequest() ; }
}
#endif
void ByteOrderMark() : {}
{
(<BOM>)?
}
void Prologue() : {}
{
( BaseDecl() | PrefixDecl() )*
}
void BaseDecl() : { String iri ; }
{
<BASE> iri = IRIREF()
{ getPrologue().setBaseURI(iri) ; }
}
void PrefixDecl() : { Token t ; String iri ; }
{
<PREFIX> t = <PNAME_NS> iri = IRIREF()
{ String s = fixupPrefix(t.image, t.beginLine, t.beginColumn) ;
getPrologue().setPrefix(s, iri) ; }
}
// ---- Query type clauses
void SelectQuery() : { }
{
SelectClause()
( DatasetClause() )*
WhereClause()
SolutionModifier()
}
void SubSelect() :{ }
{
SelectClause()
WhereClause()
SolutionModifier()
ValuesClause()
}
void SelectClause() : { Var v ; Expr expr ; Node n ; }
{
<SELECT>
{ getQuery().setQuerySelectType() ; }
( <DISTINCT> { getQuery().setDistinct(true);}
| <REDUCED> { getQuery().setReduced(true); }
)?
{ allowAggregatesInExpressions = true ; }
(
(
v = Var() { getQuery().addResultVar(v) ; }
|
#if ARQ
// Expressions without ()
( LOOKAHEAD(2)
expr = BuiltInCall() { getQuery().addResultVar((Var)null, expr) ; }
| expr = FunctionCall() { getQuery().addResultVar((Var)null, expr) ; }
| n = RDFLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
| n = NumericLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
| n = BooleanLiteral() { getQuery().addResultVar((Var)null, NodeValue.makeNode(n)) ; }
)
// @@ PROBLEMS: expr = FunctionCall()
// <uri>(?x)
// looks like a function call and also a "<uri> ( ?v )"
//| expr = FunctionCall() { getQuery().addResultVar((Var)null, expr) ; }
|
#endif
// Expressions with ()
(
{ v = null ; }
<LPAREN>
expr = Expression()
#ifdef SPARQL_11
<AS> v = Var()
#endif
#ifdef ARQ
( <AS> v = Var() ) ?
#endif
<RPAREN>
{ getQuery().addResultVar(v, expr) ; }
)
{ getQuery().setQueryResultStar(false) ; }
)+
|
<STAR> { getQuery().setQueryResultStar(true) ; }
)
{ allowAggregatesInExpressions = false ; }
}
#if 0
#include "json-extra.jj"
#endif
void ConstructQuery() : { Template t ;
TripleCollectorBGP acc = new TripleCollectorBGP() ; }
{
// #ifndef ARQ
// <CONSTRUCT>
// { getQuery().setQueryConstructType() ; }
// t = ConstructTemplate()
// { getQuery().setConstructTemplate(t) ; }
// ( DatasetClause() )*
// WhereClause()
// SolutionModifier()
// #else
<CONSTRUCT>
{ getQuery().setQueryConstructType() ; }
(
// Full form.
t = ConstructTemplate()
{ getQuery().setConstructTemplate(t) ; }
( DatasetClause() )*
WhereClause()
SolutionModifier()
|
// Abbreviated CONSTRUCT WHERE {}
( DatasetClause() )*
<WHERE>
// Should have been "ConstructTemplate()"
<LBRACE>
(TriplesTemplate(acc))?
<RBRACE>
SolutionModifier()
{
t = new Template(acc.getBGP()) ;
getQuery().setConstructTemplate(t) ;
// Create a query in the same shape as the query created by writing out in full.
ElementPathBlock epb = new ElementPathBlock(acc.getBGP()) ;
ElementGroup elg = new ElementGroup() ;
elg.addElement(epb) ;
getQuery().setQueryPattern(elg) ;
}
)
//#endif
}
void DescribeQuery() : { Node n ; }
{
<DESCRIBE>
{ getQuery().setQueryDescribeType() ; }
(
( n = VarOrIri() { getQuery().addDescribeNode(n) ; } )+
{ getQuery().setQueryResultStar(false) ; }
|
<STAR>
{ getQuery().setQueryResultStar(true) ; }
)
( DatasetClause() )*
( WhereClause() )?
SolutionModifier()
}
void AskQuery() : {}
{
<ASK> { getQuery().setQueryAskType() ; }
( DatasetClause() )*
WhereClause()
SolutionModifier()
}
void JsonTemplateQuery() : {}
{
SelectJsonClause()
( DatasetClause() )*
WhereClause()
SolutionModifier()
}
void SelectJsonClause() : { Var v; String s;}
{
<SELECT> { getQuery().setQuerySelectType() ; }
<JSON> { getQuery().setJson(true); }
<LBRACE>
// JavaCC couldn't find a COMMA token
s = String() < PNAME_NS >
v = Var() { getQuery().addResultVar(v) ; getQuery().addJsonTemplateMapping(s, v) ; }
(
<COMMA> s = String() < PNAME_NS >
v = Var() { getQuery().addResultVar(v) ; getQuery().addJsonTemplateMapping(s, v) ; }
)*
<RBRACE>
}
// ----
void DatasetClause() : {}
{
<FROM>
( DefaultGraphClause() | NamedGraphClause() )
}
void DefaultGraphClause() : { String iri ; }
{
iri = SourceSelector()
{
// This checks for duplicates
getQuery().addGraphURI(iri) ;
}
}
void NamedGraphClause() : { String iri ; }
{
<NAMED>
iri = SourceSelector()
{
// This checks for duplicates
getQuery().addNamedGraphURI(iri) ;
}
}
String SourceSelector() : { String iri ; }
{
iri = iri() { return iri ; }
}
void WhereClause() : { Element el ; }
{
(<WHERE>)?
{ startWherePattern() ; }
el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; }
{ finishWherePattern() ; }
}
void SolutionModifier() : { }
{
( GroupClause() )?
( HavingClause() )?
( OrderClause() )?
( LimitOffsetClauses() )?
}
void GroupClause() : { }
{
<GROUP> <BY> ( GroupCondition() )+
}
void GroupCondition() : { Var v = null ; Expr expr = null ; }
{
( expr = BuiltInCall() { getQuery().addGroupBy((Var)null, expr) ; }
| expr = FunctionCall() { getQuery().addGroupBy((Var)null, expr) ; }
|
<LPAREN>
expr = Expression()
( <AS> v = Var() )?
<RPAREN>
{ getQuery().addGroupBy(v ,expr) ; }
| v = Var()
{ getQuery().addGroupBy(v) ; }
)
}
void HavingClause() : { }
{
{ allowAggregatesInExpressions = true ; }
<HAVING> (HavingCondition())+
{ allowAggregatesInExpressions = false ; }
}
void HavingCondition() : { Expr c ; }
{
c = Constraint()
{ getQuery().addHavingCondition(c) ; }
}
void OrderClause() : { }
{
{ allowAggregatesInExpressions = true ; }
<ORDER> <BY> ( OrderCondition() )+
{ allowAggregatesInExpressions = false ; }
}
void OrderCondition() :
{ int direction = 0 ; Expr expr = null ; Node v = null ; }
{
{ direction = Query.ORDER_DEFAULT ; }
(
( // These are for clarity in the HTML
( <ASC> { direction = Query.ORDER_ASCENDING ; }
| <DESC> { direction = Query.ORDER_DESCENDING ; } )
expr = BrackettedExpression()
)
|
( expr = Constraint()
| v = Var() //{ expr = asExpr(v) ; }
)
)
{ if ( v == null )
getQuery().addOrderBy(expr, direction) ;
else
getQuery().addOrderBy(v, direction) ; }
}
void LimitOffsetClauses() : { }
{
// SPARQL does not care about the order here.
// SQL (where implemented) does (it's LIMIT then OFFSET generally)
// But that is counter intuitive as it's applied the other way round
(
LimitClause() (OffsetClause())?
|
OffsetClause() (LimitClause())?
)
}
void LimitClause() : { Token t ; }
{
<LIMIT> t = <INTEGER>
{ getQuery().setLimit(integerValue(t.image)) ; }
}
void OffsetClause() : { Token t ; }
{
<OFFSET> t = <INTEGER>
{ getQuery().setOffset(integerValue(t.image)) ; }
}
void ValuesClause() : { Token t ; }
{
(
t = <VALUES>
{ startValuesClause(t.beginLine, t.beginColumn) ; }
DataBlock()
{ finishValuesClause(t.beginLine, t.beginColumn) ; }
)?
}
#ifdef UPDATE
// SPARQL Update + transitional extensions for SPARQL/Update (the W3C submission)
// Update only entry point
#ifdef ARQ
void Update() : { }
{
// Rewrite for no recursion - grammar is not LL(1)
Prologue()
(
Update1()
(
// This syntactic lookahead is necessitated by the optional trailing semicolon and prologue
LOOKAHEAD( <SEMICOLON> Prologue() ( <LOAD> | <CLEAR> | <DROP> | <ADD> |
<MOVE> | <COPY> | <CREATE> | <WITH> | <DELETE> | <INSERT> |
<USING> | <INSERT_DATA> | <DELETE_DATA> | <DELETE_WHERE> ) )
<SEMICOLON>
Prologue()
Update1()
)*
(
<SEMICOLON>
Prologue()
)?
)?
}
#else
// Strict SPARQL 1.1 : mandatory separator, optional terminator.
void Update() : { }
{
// SPARQL - recursion - does not scale for large number of updates in a single request
Prologue()
(Update1() ( <SEMICOLON> Update() )? )?
}
#endif
void Update1() : { Update up = null ; }
{
{ startUpdateOperation() ; }
( up = Load()
| up = Clear()
| up = Drop()
| up = Add()
| up = Move()
| up = Copy()
| up = Create()
| up = DeleteWhere()
| up = Modify()
| InsertData()
| DeleteData()
)
{
if (null != up) emitUpdate(up) ;
finishUpdateOperation() ;
}
}
Update Load() : { String url ; Node dest = null ; boolean silent = false ; }
{
// <LOAD> ( iri() )+
<LOAD> (<SILENT> { silent = true ; })? url = iri()
(<INTO> dest = GraphRef() )?
{ return new UpdateLoad(url, dest, silent) ; }
}
Update Clear() : { boolean silent = false ; Target target ; }
{
<CLEAR> (<SILENT> { silent = true ; })? target = GraphRefAll()
{ return new UpdateClear(target, silent) ; }
}
Update Drop() : { boolean silent = false ; Target target ; }
{
<DROP> (<SILENT> { silent = true ; })? target = GraphRefAll()
{ return new UpdateDrop(target, silent) ; }
}
Update Create() : { Node iri ; boolean silent = false ; }
{
<CREATE> (<SILENT> { silent=true ; } )? iri = GraphRef()
{ return new UpdateCreate(iri, silent) ; }
}
Update Add() : { Target src ; Target dest ; boolean silent = false ; }
{
<ADD> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
{ return new UpdateAdd(src, dest, silent) ; }
}
Update Move() : { Target src ; Target dest ; boolean silent = false ; }
{
<MOVE> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
{ return new UpdateMove(src, dest, silent) ; }
}
Update Copy() : { Target src ; Target dest ; boolean silent = false ; }
{
<COPY> (<SILENT> { silent=true ; } )? src = GraphOrDefault() <TO> dest = GraphOrDefault()
{ return new UpdateCopy(src, dest, silent) ; }
}
// #ifdef ARQ
// void Meta() : { QuadDataAccSink qd = new QuadDataAccSink() ; }
// {
// <META>
// QuadData(qd)
// }
// #endif
void InsertData() : { QuadDataAccSink qd = createInsertDataSink() ; Token t ; }
{
t = <INSERT_DATA>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ startDataInsert(qd, beginLine, beginColumn) ; }
QuadData(qd)
{
finishDataInsert(qd, beginLine, beginColumn) ;
qd.close() ;
}
}
void DeleteData() : { QuadDataAccSink qd = createDeleteDataSink() ; Token t ; }
{
t = <DELETE_DATA>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ startDataDelete(qd, beginLine, beginColumn) ; }
QuadData(qd)
{
finishDataDelete(qd, beginLine, beginColumn) ;
qd.close() ;
}
}
Update DeleteWhere() : { QuadAcc qp = new QuadAcc() ; Token t ; }
{
t = <DELETE_WHERE>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ startDeleteTemplate(qp, beginLine, beginColumn) ; }
QuadPattern(qp)
{ finishDeleteTemplate(qp, beginLine, beginColumn) ; }
{ return new UpdateDeleteWhere(qp) ; }
}
Update Modify() : { Element el ; String iri = null ;
UpdateModify up = new UpdateModify() ; }
{
{ startModifyUpdate() ; }
( <WITH> iri = iri() { Node n = createNode(iri) ; up.setWithIRI(n) ; } )?
( DeleteClause(up) ( InsertClause(up) )?
| InsertClause(up)
)
(UsingClause(up))*
// WHERE is mandatory here.
<WHERE>
{ startWherePattern() ; }
el = GroupGraphPattern() { up.setElement(el) ; }
{ finishWherePattern() ; }
{ finishModifyUpdate() ; }
{ return up ; }
}
void DeleteClause(UpdateModify up) : { QuadAcc qp = up.getDeleteAcc() ; Token t ;}
{
t = <DELETE>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ startDeleteTemplate(qp, beginLine, beginColumn) ; }
QuadPattern(qp)
{ finishDeleteTemplate(qp, beginLine, beginColumn) ; }
{ up.setHasDeleteClause(true) ; }
}
void InsertClause(UpdateModify up) : { QuadAcc qp = up.getInsertAcc() ; Token t ; }
{
t = <INSERT>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ startInsertTemplate(qp, beginLine, beginColumn) ; }
QuadPattern(qp)
{ finishInsertTemplate(qp, beginLine, beginColumn) ; }
{ up.setHasInsertClause(true) ; }
}
void UsingClause(UpdateWithUsing update) : { String iri ; Node n ; }
{
<USING>
( iri = iri()
{ n = createNode(iri) ; update.addUsing(n) ; }
| <NAMED> iri = iri()
{ n = createNode(iri) ; update.addUsingNamed(n) ; }
)
}
Target GraphOrDefault() : { String iri ; }
{
( <DFT> { return Target.DEFAULT ; }
| (<GRAPH>)?
iri = iri()
{ return Target.create(createNode(iri)) ; }
)
}
Node GraphRef() : { String iri ; }
{
<GRAPH> iri = iri()
{ return createNode(iri) ; }
}
Target GraphRefAll() : { Node iri ; }
{
( iri = GraphRef()
{ return Target.create(iri) ; }
| <DFT> { return Target.DEFAULT ; }
| <NAMED> { return Target.NAMED ; }
| <ALL> { return Target.ALL ; }
)
}
void QuadPattern(QuadAcc acc) : { }
{
<LBRACE>
Quads(acc)
<RBRACE>
}
//Ground data : As QuadPattern but don't allow variables.
void QuadData(QuadDataAccSink acc) : { }
{
<LBRACE>
Quads(acc)
<RBRACE>
}
void Quads(QuadAccSink acc) : { }
{
(TriplesTemplate(acc))?
(
QuadsNotTriples(acc)
(<DOT>)?
(TriplesTemplate(acc))?
)*
}
void QuadsNotTriples(QuadAccSink acc) : {Node gn ; Node prev = acc.getGraph() ; }
{
<GRAPH> gn = VarOrIri()
{ setAccGraph(acc, gn) ; }
<LBRACE>
(TriplesTemplate(acc))?
<RBRACE>
{ setAccGraph(acc, prev) ; }
}
void TriplesTemplate(TripleCollector acc) : { }
{ // same as ConstructTriples
#if SPARQL_11
// Version for the spec.
TriplesSameSubject(acc)
(<DOT> (TriplesTemplate(acc))?)?
#endif
#ifdef ARQ
// Rewrite for no recursion - grammar is not LL(1)
TriplesSameSubject(acc)
(LOOKAHEAD(2) (<DOT>) TriplesSameSubject(acc))*
(<DOT>)?
#endif
}
#endif
// ---- General Graph Pattern
Element GroupGraphPattern() : { Element el = null ; Token t ; }
{
t = <LBRACE>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
(
{ startSubSelect(beginLine, beginColumn) ; }
SubSelect()
{
Query q = endSubSelect(beginLine, beginColumn) ;
el = new ElementSubQuery(q) ;
}
| el = GroupGraphPatternSub()
)
<RBRACE>
{ return el ; }
}
Element GroupGraphPatternSub() : { Element el = null ; }
{
{ ElementGroup elg = new ElementGroup() ; }
{ startGroup(elg) ; }
// Ensure two BGP's can't be next to each other
// Done by seeing if there is a non-BGP and recursing
// if there is an intermediate
(
{ startTriplesBlock() ; }
el = TriplesBlock(null)
{ endTriplesBlock() ;
elg.addElement(el) ; }
)?
(
el = GraphPatternNotTriples()
{ elg.addElement(el) ; }
(<DOT>)?
(
{ startTriplesBlock() ; }
el = TriplesBlock(null)
{ endTriplesBlock() ;
elg.addElement(el) ; }
)?
)*
{ endGroup(elg) ; }
{ return elg ; }
}
Element TriplesBlock(ElementPathBlock acc) : { }
{
{ if ( acc == null )
acc = new ElementPathBlock() ;
}
TriplesSameSubjectPath(acc)
( <DOT> (TriplesBlock(acc))? )?
{ return acc ; }
}
// -----
Element GraphPatternNotTriples() : { Element el = null ; }
{
(
// el = GroupGraphPattern()
// |
// el = UnionGraphPattern()
// |
el = GroupOrUnionGraphPattern()
|
el = OptionalGraphPattern()
|
el = MinusGraphPattern()
|
el = GraphGraphPattern()
|
el = ServiceGraphPattern()
|
el = Filter()
|
el = Bind()
|
el = InlineData()
#ifdef ARQ
|
el = Assignment()
|
el = ExistsElt()
|
el = NotExistsElt()
#endif
)
{ return el ; }
}
// ---- Definitions of each pattern element
Element OptionalGraphPattern() : { Element el ; }
{ <OPTIONAL> el = GroupGraphPattern()
{ return new ElementOptional(el) ; }
}
Element GraphGraphPattern() : { Element el ; Node n ;}
{
<GRAPH> n = VarOrIri() el = GroupGraphPattern()
{ return new ElementNamedGraph(n, el) ; }
}
Element ServiceGraphPattern() : { Element el ; Node n ; boolean silent = false ; }
{
<SERVICE>
(<SILENT>
{ silent=true; }
)?
n = VarOrIri()
el = GroupGraphPattern()
{ return new ElementService(n, el, silent) ; }
}
Element Bind() : { Var v ; Expr expr ; }
{
<BIND>
<LPAREN>
expr = Expression()
<AS>
v = Var()
<RPAREN>
{ return new ElementBind(v, expr) ; }
}
Element InlineData() : { ElementData el ; Token t ; }
{
t = <VALUES>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ el = new ElementData() ;
startInlineData(el.getVars(), el.getRows(), beginLine, beginColumn) ; }
DataBlock()
{ finishInlineData(beginLine, beginColumn) ;
return el ; }
}
void DataBlock() : { }
{
( InlineDataOneVar() | InlineDataFull() )
}
void InlineDataOneVar() : { Var v ; Node n ; Token t ; }
{
v = Var()
{ emitDataBlockVariable(v) ; }
t = <LBRACE>
(
n = DataBlockValue()
{ startDataBlockValueRow(-1, -1) ;
emitDataBlockValue(n, -1, -1) ;
finishDataBlockValueRow(-1, -1) ;
}
)*
t = <RBRACE>
}
void InlineDataFull() : { Var v ; Node n ; Token t ; int beginLine; int beginColumn; }
{
(
<NIL>
|
<LPAREN>
(v = Var() { emitDataBlockVariable(v) ; })*
<RPAREN>
)
<LBRACE>
(
t = <LPAREN>
{ beginLine = t.beginLine; beginColumn = t.beginColumn; t = null; }
{ startDataBlockValueRow(beginLine, beginColumn) ; }
(n = DataBlockValue()
{ emitDataBlockValue(n, beginLine, beginColumn) ; }
) *
t = <RPAREN>
{ beginLine = t.beginLine; beginColumn = t.beginColumn; t = null; }
{ finishDataBlockValueRow(beginLine, beginColumn) ; }
|
t = <NIL>
{ beginLine = t.beginLine; beginColumn = t.beginColumn; t = null; }
{ startDataBlockValueRow(beginLine, beginColumn) ; }
{ finishDataBlockValueRow(beginLine, beginColumn) ; }
)*
<RBRACE>
}
Node DataBlockValue() : { Node n ; String iri ; }
{
iri = iri() { return createNode(iri) ; }
| n = RDFLiteral() { return n ; }
| n = NumericLiteral() { return n ; }
| n = BooleanLiteral() { return n ; }
| <UNDEF> { return null ; }
}
#ifdef ARQ
Element Assignment() : { Var v ; Expr expr ; }
{
<LET>
<LPAREN>
v = Var()
<ASSIGN>
expr = Expression()
<RPAREN>
{ return new ElementAssign(v, expr) ; }
}
Element ExistsElt() : { Element el ; }
{
<EXISTS>
el = GroupGraphPattern()
{ return new ElementExists(el) ; }
}
Element NotExistsElt() : { Element el ; }
{
<NOT> <EXISTS>
el = GroupGraphPattern()
{ return new ElementNotExists(el) ; }
}
#endif
Element MinusGraphPattern() : { Element el ; }
{
<MINUS_P>
el = GroupGraphPattern()
{ return new ElementMinus(el) ; }
}
// Element UnionGraphPattern() : { Element el ; }
// {
// <UNION>
// el = GroupGraphPattern()
// { return new ElementUnion(el) ; }
// }
// SPARQL 1.0: {pattern} UNION {pattern} UNION {pattern} ... ::
// SPARQL 1.1 may introduce: { pattern UNION pattern UNION ... }
// G (union G)* can be a single group pattern
// or a group pattern as part of an union.
Element GroupOrUnionGraphPattern() :
{ Element el = null ; ElementUnion el2 = null ; }
{
el = GroupGraphPattern()
( <UNION>
{ if ( el2 == null )
{
el2 = new ElementUnion() ;
el2.addElement(el) ;
}
}
el = GroupGraphPattern()
{ el2.addElement(el) ; }
)*
{ return (el2==null)? el : el2 ; }
}
Element Filter() : { Expr c ; }
{
<FILTER> c = Constraint()
{ return new ElementFilter(c) ; }
}
Expr Constraint() : { Expr c ; }
{
( c = BrackettedExpression()
| c = BuiltInCall()
| c = FunctionCall()
)
{ return c ; }
}
Expr FunctionCall() : { String fname ; ExprList a ; }
{
fname = iri()
a = ArgList()
{ return new E_Function(fname, a) ; }
}
ExprList ArgList() : { Expr expr ; boolean distinct = false ;
ExprList args = new ExprList() ; Token t ; }
{
(
<NIL>
|
<LPAREN>
(t = <DISTINCT> { distinct = true ; }
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{
if ( ! allowAggregatesInExpressions )
throwParseException("Aggregate expression not legal at this point",
beginLine, beginColumn) ;
}
)?
expr = Expression() { args.add(expr) ; }
(<COMMA> expr = Expression() { args.add(expr) ; } )*
<RPAREN>
)
{ return args ; }
}
ExprList ExpressionList() : { Expr expr = null ; ExprList args = new ExprList() ;}
{
(
<NIL>
|
<LPAREN>
expr = Expression() { args.add(expr) ; }
(<COMMA> expr = Expression() { args.add(expr) ; } )*
<RPAREN>
)
{ return args ; }
}
// -------- Construct patterns
Template ConstructTemplate() : { TripleCollectorBGP acc = new TripleCollectorBGP();
Template t = new Template(acc.getBGP()) ; }
{
{ setInConstructTemplate(true) ; }
<LBRACE>
(ConstructTriples(acc))?
<RBRACE>
{ setInConstructTemplate(false) ;
return t ; }
}
void ConstructTriples(TripleCollector acc) : { }
{ // Same as TriplesTemplate, but retain for 1.0 legacy
#ifdef SPARQL_11
// SPARQL - recursion - does not scale for SPARQL/Update
TriplesSameSubject(acc)
(<DOT> (ConstructTriples(acc))? )?
#endif
#ifdef ARQ
// Rewrite for no recursion - grammar is not LL(1)
TriplesSameSubject(acc)
(LOOKAHEAD(2) (<DOT>) TriplesSameSubject(acc))*
(<DOT>)?
#endif
}
// -------- Triple lists with property and object lists
// -------- Without paths: entry: TriplesSameSubject
void TriplesSameSubject(TripleCollector acc) : { Node s ; }
{
s = VarOrTerm()
PropertyListNotEmpty(s, acc)
|
// Any of the triple generating syntax elements
{ ElementPathBlock tempAcc = new ElementPathBlock() ; }
s = TriplesNode(tempAcc)
PropertyList(s, tempAcc)
{ insert(acc, tempAcc) ; }
}
void PropertyList(Node s, TripleCollector acc) : { }
{
( PropertyListNotEmpty(s, acc) ) ?
}
void PropertyListNotEmpty(Node s, TripleCollector acc) :
{ Node p = null ; }
{
p = Verb()
ObjectList(s, p, null, acc)
( <SEMICOLON>
(
p = Verb()
ObjectList(s, p, null, acc)
)?
)*
}
Node Verb() : { Node p ;}
{
// Blank nodes as predicates
// ( p = VarOrBlankNodeOriri() | <KW_A> { p = nRDFtype ; } )
( p = VarOrIri() | <KW_A> { p = nRDFtype ; } )
{ return p ; }
}
void ObjectList(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
Object(s, p, path, acc)
( <COMMA> Object(s, p, path, acc) )*
}
void Object(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
{ ElementPathBlock tempAcc = new ElementPathBlock() ; int mark = tempAcc.mark() ; }
o = GraphNode(tempAcc)
{ insert(tempAcc, mark, s, p, path, o) ; insert(acc, tempAcc) ; }
}
// -------- BGPs with paths.
// -------- Entry point: TriplesSameSubjectPath
void TriplesSameSubjectPath(TripleCollector acc) : { Node s ; }
{
s = VarOrTerm()
PropertyListPathNotEmpty(s, acc)
|
// Any of the triple generating syntax elements
{ ElementPathBlock tempAcc = new ElementPathBlock() ; }
s = TriplesNodePath(tempAcc)
PropertyListPath(s, tempAcc)
{ insert(acc, tempAcc) ; }
}
void PropertyListPath(Node s, TripleCollector acc) : { }
{
( PropertyListPathNotEmpty(s, acc) ) ?
}
void PropertyListPathNotEmpty(Node s, TripleCollector acc) :
{ Path path = null ; Node p = null ; }
{
( path = VerbPath()
| p = VerbSimple()
)
ObjectListPath(s, p, path, acc)
( <SEMICOLON>
{ path = null ; p = null ; }
(
( path = VerbPath()
| p = VerbSimple()
)
ObjectListPath(s, p, path, acc)
)?
)*
#if 0
|
Reification(s, acc)
#endif
}
Path VerbPath() : {Node p ; Path path ; }
{
path = Path() { return path ; }
}
Node VerbSimple() : { Node p ; }
{
// "a" now allowed in paths.
//( p = Var() | <KW_A> { p = nRDFtype ; } )
p = Var()
{ return p ; }
}
void ObjectListPath(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
ObjectPath(s, p, path, acc)
( <COMMA> ObjectPath(s, p, path, acc) )*
}
void ObjectPath(Node s, Node p, Path path, TripleCollector acc): { Node o ; }
{
{ ElementPathBlock tempAcc = new ElementPathBlock() ; int mark = tempAcc.mark() ; }
o = GraphNodePath(tempAcc)
{ insert(tempAcc, mark, s, p, path, o) ; insert(acc, tempAcc) ; }
}
// End paths stuff.
// -------- Paths
#ifdef ARQ
Path PathUnit() : { Path p ; }
{
ByteOrderMark()
p = Path()
<EOF>
{ return p ; }
}
#endif
// Weakest outermost
Path Path() : { Path p ; }
{
p = PathAlternative() { return p ; }
}
Path PathAlternative() : { Path p1 , p2 ; }
{
p1 = PathSequence()
(
<VBAR> p2 = PathSequence()
{ p1 = PathFactory.pathAlt(p1, p2) ; }
)*
{ return p1 ; }
}
Path PathSequence() : { Path p1 , p2 ; }
{
p1 = PathEltOrInverse()
( <SLASH> p2 = PathEltOrInverse()
{ p1 = PathFactory.pathSeq(p1, p2) ; }
#ifdef ARQ
// :p^:q -- Not in SPARQL 1.1
| <CARAT> p2 = PathElt()
{ p1 = PathFactory.pathSeq(p1, new P_Inverse(p2)) ; }
#endif
)*
{ return p1; }
}
// Path unit element, no inverse
Path PathElt() : { String str ; Node n ; Path p ; }
{
p = PathPrimary()
( p = PathMod(p) )?
{ return p ; }
}
// Path unit element, including inverse.
Path PathEltOrInverse() : { String str ; Node n ; Path p ; }
{
( p = PathElt()
| <CARAT>
p = PathElt()
{ p = PathFactory.pathInverse(p) ; }
)
{ return p ; }
}
Path PathMod(Path p) : { long i1 ; long i2 ; }
{
( <QMARK> { return PathFactory.pathZeroOrOne(p) ; }
| <STAR> { return PathFactory.pathZeroOrMore1(p) ; }
| <PLUS> { return PathFactory.pathOneOrMore1(p) ; }
#ifdef ARQ
| <LBRACE>
//{*}
( <STAR> <RBRACE> { return PathFactory.pathZeroOrMoreN(p) ; }
// {+}
| <PLUS> <RBRACE> { return PathFactory.pathOneOrMoreN(p) ; }
| // {N} {N,M} {N,}
i1 = Integer()
( <COMMA>
( // case {N,}
<RBRACE>
{ return PathFactory.pathMod(p, i1, PathFactory.UNSET) ; }
| // case {N,M}
i2 = Integer() <RBRACE> // case {N,M}
{ return PathFactory.pathMod(p, i1, i2) ; }
)
|
<RBRACE> // {N}
{ return PathFactory.pathFixedLength(p, i1) ; }
)
| // {,N}
<COMMA>
i2 = Integer()
<RBRACE>
{ return PathFactory.pathMod(p, PathFactory.UNSET, i2) ; }
)
#endif
)
}
Path PathPrimary() : { String str ; Path p ; Node n ; }
{
(
str = iri()
{ n = createNode(str) ; p = PathFactory.pathLink(n) ; }
| <KW_A>
{ p = PathFactory.pathLink(nRDFtype) ; }
| <BANG> p = PathNegatedPropertySet()
| <LPAREN> p = Path() <RPAREN>
#ifdef ARQ
|
<DISTINCT><LPAREN>
p = Path()
{ p = PathFactory.pathDistinct(p) ; }
<RPAREN>
|
<SHORTEST> <LPAREN>
p = Path()
{ p = PathFactory.pathShortest(p) ; }
<RPAREN>
|
<MULTI><LPAREN>
p = Path()
{ p = PathFactory.pathMulti(p) ; }
<RPAREN>
#endif
)
{ return p ; }
}
Path PathNegatedPropertySet() : { P_Path0 p ; P_NegPropSet pNegSet ; }
{
{ pNegSet = new P_NegPropSet() ; }
( p = PathOneInPropertySet()
{ pNegSet.add(p) ; }
| <LPAREN>
( p = PathOneInPropertySet() { pNegSet.add(p) ; }
(<VBAR> p = PathOneInPropertySet() { pNegSet.add(p) ; }) *
)?
<RPAREN>
)
{ return pNegSet ; }
}
P_Path0 PathOneInPropertySet() : { String str ; Node n ; }
{
( str = iri() { n = createNode(str) ; return new P_Link(n) ; }
| <KW_A> { return new P_Link(nRDFtype) ; }
// This is the !(^:property) form.
| <CARAT>
( str = iri() { n = createNode(str) ; return new P_ReverseLink(n) ; }
| <KW_A> { return new P_ReverseLink(nRDFtype) ; }
)
)
}
long Integer() : {Token t ;}
{
t = <INTEGER>
{ return integerValue(t.image) ; }
}
// -------- Triple expansions
// Anything that can stand in a node slot and which is
// a number of triples
Node TriplesNode(TripleCollectorMark acc) : { Node n ; }
{
n = Collection(acc) { return n ; }
|
n = BlankNodePropertyList(acc) { return n ; }
#if 0
|
n = Reification(null, acc) { return n ; }
#endif
}
Node BlankNodePropertyList(TripleCollector acc) : { Token t ; }
{
t = <LBRACKET>
{ Node n = createBNode( t.beginLine, t.beginColumn) ; }
PropertyListNotEmpty(n, acc)
<RBRACKET>
{ return n ; }
}
Node TriplesNodePath(TripleCollectorMark acc) : { Node n ; }
{
n = CollectionPath(acc) { return n ; }
|
n = BlankNodePropertyListPath(acc) { return n ; }
#if 0
|
n = Reification(null, acc) { return n ; }
#endif
}
Node BlankNodePropertyListPath(TripleCollector acc) : { Token t ; }
{
t = <LBRACKET>
{ Node n = createBNode( t.beginLine, t.beginColumn) ; }
PropertyListPathNotEmpty(n, acc)
<RBRACKET>
{ return n ; }
}
#if 0
Node Reification(Node id, TripleCollectorMark acc) :
{ Node s , p , o ; int mark ; Token t ; }
{
// For generality, should be AndNode for s/p/o
// Insert reification triple before the resulting subtriples (if any)
t = "<<"
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
{ if ( id == null )
id = createBNode(beginLine, beginColumn() ;
mark = acc.mark() ; }
s = GraphNode(acc)
{ insert(acc, mark, id, nRDFsubject, s) ;
mark = acc.mark() ;
}
p = GraphNode(acc)
{ insert(acc, mark, id, nRDFpredicate, p) ;
mark = acc.mark() ;
}
o = GraphNode(acc)
{ insert(acc, mark, id, nRDFobject, o) ; }
">>"
{ return id ; }
}
#endif
// ------- RDF collections
Node Collection(TripleCollectorMark acc) :
{ Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; }
{
t = <LPAREN>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
(
{ Node cell = createListNode( beginLine, beginColumn) ;
if ( listHead == nRDFnil )
listHead = cell ;
if ( lastCell != null )
insert(acc, lastCell, nRDFrest, cell) ;
mark = acc.mark() ;
}
n = GraphNode(acc)
{
insert(acc, mark, cell, nRDFfirst, n) ;
lastCell = cell ;
}
) +
// Not * here - "()" is handled separately.
<RPAREN>
{ if ( lastCell != null )
insert(acc, lastCell, nRDFrest, nRDFnil) ;
return listHead ; }
}
Node CollectionPath(TripleCollectorMark acc) :
{ Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; }
{
t = <LPAREN>
{ int beginLine = t.beginLine; int beginColumn = t.beginColumn; t = null; }
(
{ Node cell = createListNode( beginLine, beginColumn) ;
if ( listHead == nRDFnil )
listHead = cell ;
if ( lastCell != null )
insert(acc, lastCell, nRDFrest, cell) ;
mark = acc.mark() ;
}
n = GraphNodePath(acc)
{
insert(acc, mark, cell, nRDFfirst, n) ;
lastCell = cell ;
}
) +
// Not * here - "()" is handled separately.
<RPAREN>
{ if ( lastCell != null )
insert(acc, lastCell, nRDFrest, nRDFnil) ;
return listHead ; }
}
// -------- Nodes in a graph pattern or template
Node GraphNode(TripleCollectorMark acc) : { Node n ; }
{
n = VarOrTerm() { return n ; }
|
n = TriplesNode(acc) { return n ; }
}
Node GraphNodePath(TripleCollectorMark acc) : { Node n ; }
{
n = VarOrTerm() { return n ; }
|
n = TriplesNodePath(acc) { return n ; }
}
Node VarOrTerm() : {Node n = null ; }
{
( n = Var() | n = GraphTerm() )
{ return n ; }
}
// Property (if no bNodes) + DESCRIBE
Node VarOrIri() : {Node n = null ; String iri ; }
{
( n = Var() | iri = iri() { n = createNode(iri) ; } )
{ return n ; }
}
Var Var() : { Token t ;}
{
( t = <VAR1> | t = <VAR2> )
{ return createVariable(t.image, t.beginLine, t.beginColumn) ; }
}
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 ; }
}
// -------- Constraint syntax
Expr Expression() : { Expr expr ; }
{
expr = ConditionalOrExpression()
{ return expr ; }
}
Expr ConditionalOrExpression() : { Expr expr1, expr2 ; }
{
expr1 = ConditionalAndExpression()
( <SC_OR> expr2 = ConditionalAndExpression()
{ expr1 = new E_LogicalOr(expr1, expr2) ; }
)*
{ return expr1 ; }
}
Expr ConditionalAndExpression() : { Expr expr1, expr2 ;}
{
expr1 = ValueLogical()
( <SC_AND> expr2 = ValueLogical()
{ expr1 = new E_LogicalAnd(expr1, expr2) ; }
)*
{ return expr1 ; }
}
Expr ValueLogical() : { Expr expr ; }
{
expr = RelationalExpression()
{ return expr ; }
}
Expr RelationalExpression() : { Expr expr1, expr2 ; ExprList a ; }
{
expr1 = NumericExpression()
(
<EQ> expr2 = NumericExpression()
{ expr1 = new E_Equals(expr1, expr2) ; }
| <NE> expr2 = NumericExpression()
{ expr1 = new E_NotEquals(expr1, expr2) ; }
| <LT> expr2 = NumericExpression()
{ expr1 = new E_LessThan(expr1, expr2) ; }
| <GT> expr2 = NumericExpression()
{ expr1 = new E_GreaterThan(expr1, expr2) ; }
| <LE> expr2 = NumericExpression()
{ expr1 = new E_LessThanOrEqual(expr1, expr2) ; }
| <GE> expr2 = NumericExpression()
{ expr1 = new E_GreaterThanOrEqual(expr1, expr2) ; }
| <IN> a = ExpressionList()
{ expr1 = new E_OneOf(expr1, a) ; }
| <NOT> <IN> a = ExpressionList()
{ expr1 = new E_NotOneOf(expr1, a) ; }
)?
{ return expr1 ; }
}
Expr NumericExpression () : { Expr expr ; }
{
expr = AdditiveExpression()
{ return expr ; }
}
Expr AdditiveExpression() : { Expr expr1, expr2, expr3 ; boolean addition ; Node n ; }
{
expr1 = MultiplicativeExpression()
( <PLUS> expr2 = MultiplicativeExpression()
{ expr1 = new E_Add(expr1, expr2) ; }
| <MINUS> expr2 = MultiplicativeExpression()
{ expr1 = new E_Subtract(expr1, expr2) ; }
|
(
n = NumericLiteralPositive()
{
n = stripSign(n) ;
expr2 = asExpr(n) ;
addition = true ;
}
|
n = NumericLiteralNegative()
{
n = stripSign(n) ;
expr2 = asExpr(n) ;
addition = false ;
}
)
(
( <STAR> expr3 = UnaryExpression() { expr2 = new E_Multiply(expr2, expr3) ; } )
|
( <SLASH> expr3 = UnaryExpression() { expr2 = new E_Divide(expr2, expr3) ; } )
)*
{ if ( addition )
expr1 = new E_Add(expr1, expr2) ;
else
expr1 = new E_Subtract(expr1, expr2) ;
}
)*
{ return expr1 ; }
}
Expr MultiplicativeExpression() : { Expr expr1, expr2 ; }
{
expr1 = UnaryExpression()
( <STAR> expr2 = UnaryExpression()
{ expr1 = new E_Multiply(expr1, expr2) ; }
| <SLASH> expr2 = UnaryExpression()
{ expr1 = new E_Divide(expr1, expr2) ; }
// | <REM> expr2 = UnaryExpression()
// { expr1 = new E_Modulus(expr1, expr2) ; }
)*
{ return expr1 ; }
}
Expr UnaryExpression() : { Expr expr ; }
{
<BANG> expr = PrimaryExpression()
{ return new E_LogicalNot(expr) ; }
| <PLUS> expr = PrimaryExpression() { return new E_UnaryPlus(expr) ; }
| <MINUS> expr = PrimaryExpression() { return new E_UnaryMinus(expr) ; }
| expr = PrimaryExpression() { return expr ; }
}
Expr PrimaryExpression() : { Expr expr ; Node gn ; }
{
( expr = BrackettedExpression() { return expr ; }
| expr = BuiltInCall() { return expr ; }
| expr = iriOrFunction() { return expr ; }
// NOT | gn = VarOrTerm() { return asExpr(gn) ; }
// Because of iriOrFunction
| gn = RDFLiteral() { return asExpr(gn) ; }
| gn = NumericLiteral() { return asExpr(gn) ; }
| gn = BooleanLiteral() { return asExpr(gn) ; }
| gn = Var() { return asExpr(gn) ; }
#ifdef ARQ
// and not SPARQL 11
// needs checking.
// Use this for ?var(args)
// | expr = VarOrFunction() { return expr ; }
#endif
)
}
Expr BrackettedExpression() : { Expr expr ; }
{
<LPAREN> expr = Expression() <RPAREN> { return expr ; }
}
Expr BuiltInCall() : { Expr expr ; Expr expr1 = null ; Expr expr2 = null ;
Node gn ; ExprList a ; }
{
expr = Aggregate() { return expr ; }
|
<STR> <LPAREN> expr = Expression() <RPAREN>
{ return new E_Str(expr) ; }
| <LANG> <LPAREN> expr = Expression() <RPAREN>
{ return new E_Lang(expr) ; }
| <LANGMATCHES>
<LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_LangMatches(expr1, expr2) ; }
| <DTYPE> <LPAREN> expr = Expression() <RPAREN>
{ return new E_Datatype(expr) ; }
| <BOUND> <LPAREN> gn = Var() <RPAREN>
{ return new E_Bound(new ExprVar(gn)) ; }
| <IRI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IRI(expr) ; }
| <URI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_URI(expr) ; }
| <BNODE>
( <LPAREN> expr1 = Expression() <RPAREN>
{ return new E_BNode(expr1) ; }
|
<NIL> { return new E_BNode() ; }
)
| <RAND> <NIL> { return new E_Random() ; }
| <ABS> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumAbs(expr1) ; }
| <CEIL> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumCeiling(expr1) ; }
| <FLOOR> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumFloor(expr1) ; }
| <ROUND> <LPAREN> expr1 = Expression() <RPAREN> { return new E_NumRound(expr1) ; }
| <CONCAT> a = ExpressionList() { return new E_StrConcat(a) ; }
| expr = SubstringExpression() { return expr ; }
| <STRLEN> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrLength(expr1) ; }
| expr = StrReplaceExpression() { return expr ; }
| <UCASE> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrUpperCase(expr1) ; }
| <LCASE> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrLowerCase(expr1) ; }
| <ENCODE_FOR_URI> <LPAREN> expr1 = Expression() <RPAREN> { return new E_StrEncodeForURI(expr1) ; }
| <CONTAINS> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrContains(expr1, expr2) ; }
| <STRSTARTS> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrStartsWith(expr1, expr2) ; }
| <STRENDS> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrEndsWith(expr1, expr2) ; }
| <STRBEFORE> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrBefore(expr1, expr2) ; }
| <STRAFTER> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrAfter(expr1, expr2) ; }
| <YEAR> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeYear(expr1) ; }
| <MONTH> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeMonth(expr1) ; }
| <DAY> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeDay(expr1) ; }
| <HOURS> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeHours(expr1) ; }
| <MINUTES> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeMinutes(expr1) ; }
| <SECONDS> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeSeconds(expr1) ; }
| <TIMEZONE> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeTimezone(expr1) ; }
| <TZ> <LPAREN> expr1 = Expression() <RPAREN> { return new E_DateTimeTZ(expr1) ; }
| <NOW> <NIL> { return new E_Now() ; }
| <UUID> <NIL> { return new E_UUID() ; }
| <STRUUID> <NIL> { return new E_StrUUID() ; }
| <MD5> <LPAREN> expr1 = Expression() <RPAREN> { return new E_MD5(expr1) ; }
| <SHA1> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA1(expr1) ; }
#if 0
| <SHA224> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA224(expr1) ; }
#endif
| <SHA256> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA256(expr1) ; }
| <SHA384> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA384(expr1) ; }
| <SHA512> <LPAREN> expr1 = Expression() <RPAREN> { return new E_SHA512(expr1) ; }
#if ARQ
| <VERSION> <NIL> { return new E_Version(); }
#endif
| <COALESCE> a = ExpressionList()
{ return new E_Coalesce(a) ; }
#if ARQ
// Maybe also allow ?func(?a1,?a2,...)
// | <CALL> a = ExpressionList()
// { return new E_Call(a) ; }
| <CALL>
// at least one argument (the function to call).
{ a = new ExprList() ; }
<LPAREN>
expr = Expression() { a.add(expr) ; }
( <COMMA> expr = Expression() { a.add(expr) ; } )*
<RPAREN>
{ return new E_Call(a) ; }
#endif
| <IF> <LPAREN> expr = Expression() <COMMA>
expr1 = Expression() <COMMA>
expr2 = Expression() <RPAREN>
{ return new E_Conditional(expr, expr1, expr2) ; }
| <STRLANG> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrLang(expr1, expr2) ; }
| <STRDT> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_StrDatatype(expr1, expr2) ; }
| <SAME_TERM> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN>
{ return new E_SameTerm(expr1, expr2) ; }
| <IS_IRI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsIRI(expr) ; }
| <IS_URI> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsURI(expr) ; }
| <IS_BLANK> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsBlank(expr) ; }
| <IS_LITERAL> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsLiteral(expr) ; }
| <IS_NUMERIC> <LPAREN> expr = Expression() <RPAREN>
{ return new E_IsNumeric(expr) ; }
| // Regular expression matcher
expr = RegexExpression() { return expr ; }
| expr = ExistsFunc() { return expr ; }
| expr = NotExistsFunc() { return expr ; }
}
Expr RegexExpression() :
{ Expr expr ; Expr patExpr = null ; Expr flagsExpr = null ; }
{
<REGEX>
<LPAREN>
expr = Expression()
<COMMA>
patExpr = Expression()
( <COMMA> flagsExpr = Expression() ) ?
<RPAREN>
{ return new E_Regex(expr, patExpr, flagsExpr) ; }
}
Expr SubstringExpression() :
{ Expr expr1 ; Expr expr2 = null ; Expr expr3 = null ; }
{
<SUBSTR>
<LPAREN>
expr1 = Expression()
<COMMA>
expr2 = Expression()
( <COMMA> expr3 = Expression() ) ?
<RPAREN>
{ return new E_StrSubstring(expr1, expr2, expr3) ; }
}
Expr StrReplaceExpression() :
{ Expr expr1 ; Expr expr2 = null ; Expr expr3 = null ; Expr expr4 = null ;}
{
<REPLACE>
<LPAREN>
expr1 = Expression()
<COMMA> expr2 = Expression()
<COMMA> expr3 = Expression()
( <COMMA> expr4 = Expression() ) ?
<RPAREN>
{ return new E_StrReplace(expr1,expr2,expr3,expr4) ; }
}
Expr ExistsFunc() : { Element el ; }
{
<EXISTS>
el = GroupGraphPattern()
{ return createExprExists(el) ; }
}
Expr NotExistsFunc() : { Element el ; }
{
<NOT> <EXISTS>
el = GroupGraphPattern()
{ return createExprNotExists(el) ; }
}
Expr Aggregate() : { Aggregator agg = null ; String sep = null ;
boolean distinct = false ;
Expr expr = null ; Expr expr2 = null ;
ExprList a = new ExprList() ;
ExprList ordered = new ExprList() ;
Token t ; }
{
// Count is special because of COUNT(*)
// GROUP_CONCAT is special because of separator=
( t = <COUNT> <LPAREN>
( <DISTINCT> { distinct = true ; } )?
( <STAR> | expr = Expression() )
<RPAREN>
{ if ( expr == null ) { agg = AggregatorFactory.createCount(distinct) ; }
if ( expr != null ) { agg = AggregatorFactory.createCountExpr(distinct, expr) ; }
}
| t = <SUM> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createSum(distinct, expr) ; }
| t = <MIN> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createMin(distinct, expr) ; }
| t = <MAX> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createMax(distinct, expr) ; }
| t = <AVG> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createAvg(distinct, expr) ; }
| t = <SAMPLE> <LPAREN> ( <DISTINCT> { distinct = true ; } )? expr = Expression() <RPAREN>
{ agg = AggregatorFactory.createSample(distinct, expr) ; }
| t = <GROUP_CONCAT>
<LPAREN>
(t = <DISTINCT> { distinct = true ; })?
expr = Expression() { a.add(expr) ; }
#ifdef SPARQL_11
// Single arg version
(<SEMICOLON> <SEPARATOR> <EQ> sep=String())?
#endif
#ifdef ARQ
// JavcaCC 5.0 - rewriting as LL(1) didn't work - code generated was wrong
(LOOKAHEAD(2)
( <SEMICOLON> <SEPARATOR> <EQ> sep=String()
(<SEMICOLON> <ORDER><BY> expr2 = Expression() { ordered.add(expr2) ; })?
)
|
(<SEMICOLON> <ORDER><BY> expr2 = Expression() { ordered.add(expr2) ; } )
)?
#endif
<RPAREN>
{ agg = AggregatorFactory.createGroupConcat(distinct, expr, sep, ordered) ; }
#ifdef ARQ
/* Temporary syntax*/
| t = <AGG>
{ String iri ; }
iri = iri() a = ExpressionList()
{ agg = AggregatorFactory.create(iri, a) ; }
#endif
)
{
if ( ! allowAggregatesInExpressions )
throwParseException("Aggregate expression not legal at this point",
t.beginLine, t.beginColumn) ;
}
{ Expr exprAgg = getQuery().allocAggregate(agg) ;
return exprAgg ; }
}
// See also FunctionCall.
// The case of "q:name()" or "q:agg()" or just "q:name"
// by expanding out FunctionCall()
Expr iriOrFunction() : { String iri ; ExprList a = null ;
ExprList params = null ;
boolean distinct = false ; }
{
iri = iri()
(a = ArgList())?
{ if ( a == null )
return asExpr(createNode(iri)) ;
return new E_Function(iri, a) ;
}
}
#ifdef ARQ_CALL
// Needs checking.
// The case of "?var()" or just "?var"
Expr VarOrFunction() : { Var v ; ExprList a = null ; }
{
v = Var()
{ Expr ev = new ExprVar(v) ; }
( a = ExpressionList() )?
{ if ( a == null ) return ev ;
return new E_FunctionDynamic(ev, a) ;
}
}
#endif
Node RDFLiteral() : { Token t ; String lex = null ; }
{
lex = String()
// Optional lang tag and datatype.
{ String lang = null ; String uri = null ; }
(
( t = <LANGTAG> { lang = stripChars(t.image, 1) ; } )
|
( <DATATYPE> uri = iri() )
)?
{ return createLiteral(lex, lang, uri) ; }
}
Node NumericLiteral() : { Node n ; }
{
(
n = NumericLiteralUnsigned()
| n = NumericLiteralPositive()
| n = NumericLiteralNegative()
)
{ return n ; }
}
Node NumericLiteralUnsigned() : { Token t ; }
{
t = <INTEGER> { return createLiteralInteger(t.image) ; }
| t = <DECIMAL> { return createLiteralDecimal(t.image) ; }
| t = <DOUBLE> { return createLiteralDouble(t.image) ; }
}
Node NumericLiteralPositive() : { Token t ; }
{
t = <INTEGER_POSITIVE> { return createLiteralInteger(t.image) ; }
| t = <DECIMAL_POSITIVE> { return createLiteralDecimal(t.image) ; }
| t = <DOUBLE_POSITIVE> { return createLiteralDouble(t.image) ; }
}
Node NumericLiteralNegative() : { Token t ; }
{
t = <INTEGER_NEGATIVE> { return createLiteralInteger(t.image) ; }
| t = <DECIMAL_NEGATIVE> { return createLiteralDecimal(t.image) ; }
| t = <DOUBLE_NEGATIVE> { 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
// Comments and whitespace
SKIP : { " " | "\t" | "\n" | "\r" | "\f" }
SPECIAL_TOKEN :
{ <SINGLE_LINE_COMMENT: "#" (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > }
#if 0
// DISABLED
// C-style comments (they don't nest /* /*...*/ */ is a syntax error)
// When a /* is seen in the DEFAULT state, skip it and switch to the IN_COMMENT state
SKIP : { "/*": IN_COMMENT }
// When any other character is seen in the IN_COMMENT state, skip it.
< IN_COMMENT > SKIP : { < ~[] > }
// When a */ is seen in the IN_COMMENT state, skip it and switch back to the DEFAULT state
< IN_COMMENT > SKIP : { "*/": DEFAULT }
#endif
TOKEN: {
<#WS: " " | "\t" | "\n" | "\r" | "\f">
|
// Whitespace or comment.
<#WSC: <WS> | <SINGLE_LINE_COMMENT> >
|
<BOM: "\uFEFF">
}
// Main tokens */
TOKEN:
{
// Includes # for relative URIs
<IRIref: "<" (~[ ">","<", "\"", "{", "}", "^", "\\", "|", "`",
"\u0000"-"\u0020"])* ">" >
| <PNAME_NS: (<PN_PREFIX>)? ":" >
| <PNAME_LN: <PNAME_NS> <PN_LOCAL> >
| <BLANK_NODE_LABEL: "_:" (<PN_CHARS_U> | ["0"-"9"]) ((<PN_CHARS>|".")* <PN_CHARS>)? >
| <VAR1: "?" <VARNAME> >
| <VAR2: "$" <VARNAME> >
| <LANGTAG: <AT> (<A2Z>)+("-" (<A2ZN>)+)* >
| <#A2Z: ["a"-"z","A"-"Z"]>
| <#A2ZN: ["a"-"z","A"-"Z","0"-"9"]>
}
// -------------------------------------------------
// Keyworks : includes operators that are words and should be
// before general things like IDENTIFIER which swallow almost
// anything
TOKEN : { <KW_A: "a" > }
TOKEN [IGNORE_CASE] :
{
// Prologue
< BASE: "base" >
| < PREFIX: "prefix" >
// Result forms
| < SELECT: "select" >
| < DISTINCT: "distinct" >
| < REDUCED: "reduced" >
| < JSON: "json" >
| < DESCRIBE: "describe" >
| < CONSTRUCT: "construct" >
| < ASK: "ask" >
| < LIMIT: "limit" >
| < OFFSET: "offset" >
| < ORDER: "order" >
| < BY: "by" >
| < VALUES: "values" >
| < UNDEF: "undef" >
| < ASC: "asc" >
| < DESC: "desc" >
// Dataset
| < NAMED: "named" >
| < FROM: "from" >
// Graph pattern operators
| < WHERE: "where" >
| < AND: "and" >
| < GRAPH: "graph" >
| < OPTIONAL: "optional" >
| < UNION: "union" >
| < MINUS_P: "minus" >
| < BIND: "bind" >
| < SERVICE: "service" >
#ifdef ARQ
| < LET: "let" >
#endif
| < EXISTS: "exists" >
| < NOT: "not" >
//| < UNSAID: "unsaid" >
| < AS: "as" >
| < GROUP: "group" >
| < HAVING: "having" >
| < SEPARATOR: "separator" >
| < AGG: "agg" >
| < COUNT: "count" >
| < MIN: "min" >
| < MAX: "max" >
| < SUM: "sum" >
| < AVG: "avg" >
| < STDDEV: "stdev" >
| < SAMPLE: "sample" >
| < GROUP_CONCAT: "group_concat" >
| < FILTER: "filter" >
// Expression operators
| < BOUND: "bound" >
| < COALESCE: "coalesce" >
| < IN: "in" >
| < IF: "if" >
| < BNODE: "bnode" >
| < IRI: "iri" >
| < URI: "uri" >
#ifdef ARQ
| < CAST: "cast" >
| < CALL: "call" >
| < MULTI: "multi" >
| < SHORTEST: "shortest" >
#endif
| < STR: "str" >
| < STRLANG: "strlang" >
| < STRDT: "strdt" >
| < DTYPE: "datatype" >
| < LANG: "lang" >
| < LANGMATCHES: "langmatches" >
| < IS_URI: "isURI" >
| < IS_IRI: "isIRI" >
| < IS_BLANK: "isBlank" >
| < IS_LITERAL: "isLiteral" >
| < IS_NUMERIC: "isNumeric" >
| < REGEX: "regex" >
| < SAME_TERM: "sameTerm" >
| < RAND: "RAND" >
| < ABS: "ABS" >
| < CEIL: "CEIL" >
| < FLOOR: "FLOOR" >
| < ROUND: "ROUND" >
| < CONCAT: "CONCAT" >
| < SUBSTR: "SUBSTR" >
| < STRLEN: "STRLEN" >
| < REPLACE: "REPLACE" >
| < UCASE: "UCASE" >
| < LCASE: "LCASE" >
| < ENCODE_FOR_URI: "ENCODE_FOR_URI" >
| < CONTAINS: "CONTAINS" >
| < STRSTARTS: "STRSTARTS" >
| < STRENDS: "STRENDS" >
| < STRBEFORE: "STRBEFORE" >
| < STRAFTER : "STRAFTER" >
| < YEAR: "YEAR" >
| < MONTH: "MONTH" >
| < DAY: "DAY" >
| < HOURS: "HOURS" >
| < MINUTES: "MINUTES" >
| < SECONDS: "SECONDS" >
| < TIMEZONE: "TIMEZONE" >
| < TZ: "TZ" >
| < NOW: "NOW" >
| < UUID: "UUID" >
| < STRUUID: "STRUUID" >
#ifdef ARQ
| < VERSION: "VERSION" >
#endif
| < MD5: "MD5" >
| < SHA1: "SHA1" >
| < SHA224: "SHA224" >
| < SHA256: "SHA256" >
| < SHA384: "SHA384" >
| < SHA512: "SHA512" >
| < TRUE: "true" >
| < FALSE: "false" >
}
#if defined(UPDATE)
// SPARQL/Update parts.
TOKEN [IGNORE_CASE] :
{
< DATA: "data" >
| < INSERT: "insert">
| < DELETE: "delete" >
| < INSERT_DATA: <INSERT> (<WSC>)* <DATA> >
| < DELETE_DATA: <DELETE> (<WSC>)* <DATA> >
| < DELETE_WHERE: <DELETE> (<WSC>)* <WHERE> >
| < LOAD: "load" >
| < CLEAR: "clear" >
| < CREATE: "create" >
| < ADD: "add" >
| < MOVE: "move" >
| < COPY: "copy" >
| < META: "meta" >
| < SILENT: "silent" >
| < DROP: "drop" >
| < INTO: "into" >
| < TO: "to" >
| < DFT: "default" >
//| < NAMED: "named" >
| < ALL: "all" >
| < WITH: "with" >
| < USING: "using" >
//| < BEGIN: "begin" >
//| < COMMIT: "commit" >
//| < ABORT: "abort" >
}
#endif
// -------------------------------------------------
TOKEN :
{
< #DIGITS: (["0"-"9"])+>
| < INTEGER: <DIGITS> >
//| < DECIMAL: ( <DIGITS> "." (<DIGITS>)* | "." <DIGITS> ) >
| < DECIMAL: (<DIGITS>)? "." <DIGITS> >
| < DOUBLE: // Required exponent.
(
(["0"-"9"])+ "." (["0"-"9"])* <EXPONENT>
| "." (["0"-"9"])+ (<EXPONENT>)
| (["0"-"9"])+ <EXPONENT>
)
>
| < INTEGER_POSITIVE: <PLUS> <INTEGER> >
| < DECIMAL_POSITIVE: <PLUS> <DECIMAL> >
| < DOUBLE_POSITIVE: <PLUS> <DOUBLE> >
| < INTEGER_NEGATIVE: <MINUS> <INTEGER> >
| < DECIMAL_NEGATIVE: <MINUS> <DECIMAL> >
| < DOUBLE_NEGATIVE: <MINUS> <DOUBLE> >
| < #EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ >
| < #QUOTE_3D: "\"\"\"">
| < #QUOTE_3S: "'''">
| <ECHAR: "\\" ( "t"|"b"|"n"|"r"|"f"|"\\"|"\""|"'") >
| < STRING_LITERAL1:
// Single quoted string
"'" ( (~["'","\\","\n","\r"]) | <ECHAR> )* "'" >
| < STRING_LITERAL2:
// Double quoted string
"\"" ( (~["\"","\\","\n","\r"]) | <ECHAR> )* "\"" >
| < STRING_LITERAL_LONG1:
<QUOTE_3S>
( ("'" | "''")? (~["'","\\"] | <ECHAR> ))*
<QUOTE_3S> >
| < STRING_LITERAL_LONG2:
<QUOTE_3D>
( ("\"" | "\"\"")? (~["\"","\\"] | <ECHAR> ))*
<QUOTE_3D> >
}
TOKEN :
{
< 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: "." >
| < EQ: "=" >
| < NE: "!=" >
| < GT: ">" >
| < LT: "<" >
| < LE: "<=" > // Maybe: | "=>" >
| < GE: ">=" > // Maybe: | "=<" >
| < BANG: "!" >
| < TILDE: "~" >
| < COLON: ":" >
| < SC_OR: "||" >
| < SC_AND: "&&" >
| < PLUS: "+" >
| < MINUS: "-" >
| < STAR: "*" >
| < SLASH: "/" >
//| < AMP: "&" >
//| < REM: "%" >
| < DATATYPE: "^^">
| < AT: "@">
#ifdef ARQ
| < ASSIGN: ":=">
#endif
// Path related
| < VBAR: "|" >
| < CARAT: "^" >
| < FPATH: "->" >
| < RPATH: "<-" >
| < QMARK: "?" >
}
// See XML chars.txt for notes
TOKEN:
{
// XML 1.1 NCNameStartChar without "_"
<#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"] )* >
|
// Align with QueryParseBase unescapePName.
< #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:
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment