| /** |
| * 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 Grammar - native syntax for the query engine |
| |
| // #if !defined(ARQ) && !defined(SPARQL_10) && !defined(SPARQL_11) |
| // #error Please define one of ARQ, SPARQL_10 or SPARQL11 |
| // #endif |
| // |
| // #if defined(SPARQL_10) |
| // #define SPARQL |
| // #endif |
| // Constraint expression is derived from Java : |
| // example java1.2-a.jj grammer in JavaCC distribution |
| // Much modifed over time. |
| |
| options |
| { |
| JAVA_UNICODE_ESCAPE = true ; |
| UNICODE_INPUT = false ; |
| |
| STATIC = false ; |
| // DEBUG_PARSER = true ; |
| // DEBUG_TOKEN_MANAGER = true ; |
| } |
| |
| PARSER_BEGIN(SPARQLParser10) |
| /** |
| * 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.lang.sparql_10 ; |
| |
| 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.* ; |
| |
| |
| |
| |
| |
| |
| |
| public class SPARQLParser10 extends SPARQLParser10Base |
| { |
| boolean allowAggregatesInExpressions = false ; |
| } |
| PARSER_END(SPARQLParser10) |
| void QueryUnit(): { } |
| { |
| Query() <EOF> |
| } |
| |
| void Query() : { } |
| { |
| Prologue() |
| ( SelectQuery() | ConstructQuery() | DescribeQuery() | AskQuery() ) |
| } |
| void Prologue() : {} |
| { |
| ( BaseDecl() ) ? |
| ( PrefixDecl() )* |
| } |
| |
| void BaseDecl() : { String iri ; } |
| { |
| <BASE> iri = IRI_REF() |
| { getPrologue().setBaseURI(iri) ; } |
| } |
| |
| |
| void PrefixDecl() : { Token t ; String iri ; } |
| { |
| <PREFIX> t = <PNAME_NS> iri = IRI_REF() |
| { String s = fixupPrefix(t.image, t.beginLine, t.beginColumn) ; |
| getPrologue().setPrefix(s, iri) ; } |
| } |
| |
| // ---- Query type clauses |
| |
| void SelectQuery() : { } |
| { |
| Project() |
| ( DatasetClause() )* |
| WhereClause() |
| SolutionModifier() |
| } |
| |
| void SubSelect() :{ } |
| { |
| Project() |
| WhereClause() |
| SolutionModifier() |
| } |
| |
| void Project() : { Var v ; Expr expr ; Node n ; } |
| { |
| <SELECT> |
| { getQuery().setQuerySelectType() ; } |
| ( <DISTINCT> { getQuery().setDistinct(true);} |
| | <REDUCED> { getQuery().setReduced(true); } |
| )? |
| { allowAggregatesInExpressions = true ; } |
| ( |
| ( |
| ( v = Var() { getQuery().addResultVar(v) ; } ) |
| { getQuery().setQueryResultStar(false) ; } |
| )+ |
| | |
| <STAR> { getQuery().setQueryResultStar(true) ; } |
| ) |
| { allowAggregatesInExpressions = false ; } |
| } |
| |
| void ConstructQuery() : { Template t ; } |
| { |
| <CONSTRUCT> |
| { getQuery().setQueryConstructType() ; } |
| t = ConstructTemplate() |
| { getQuery().setConstructTemplate(t) ; } |
| ( DatasetClause() )* |
| WhereClause() |
| SolutionModifier() |
| } |
| |
| void DescribeQuery() : { Node n ; } |
| { |
| <DESCRIBE> |
| { getQuery().setQueryDescribeType() ; } |
| ( |
| ( n = VarOrIRIref() { getQuery().addDescribeNode(n) ; } )+ |
| { getQuery().setQueryResultStar(false) ; } |
| | |
| <STAR> |
| { getQuery().setQueryResultStar(true) ; } |
| ) |
| ( DatasetClause() )* |
| ( WhereClause() )? |
| SolutionModifier() |
| } |
| |
| void AskQuery() : {} |
| { |
| <ASK> { getQuery().setQueryAskType() ; } |
| ( DatasetClause() )* |
| WhereClause() |
| } |
| |
| // ---- |
| |
| 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 = IRIref() { return iri ; } |
| } |
| |
| |
| void WhereClause() : { Element el ; } |
| { |
| (<WHERE>)? el = GroupGraphPattern() { getQuery().setQueryPattern(el) ; } |
| } |
| |
| void SolutionModifier() : { } |
| { |
| |
| |
| |
| |
| ( OrderClause() )? |
| ( LimitOffsetClauses() )? |
| } |
| void OrderClause() : { } |
| { |
| <ORDER> <BY> ( OrderCondition() )+ |
| } |
| |
| 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)) ; } |
| } |
| |
| // ---- SPARQL/Update (submission) |
| // SPARQL 1.1. Update |
| // ---- General Graph Pattern |
| |
| Element GroupGraphPattern() : { Element el = null ; Token t ; } |
| { |
| t = <LBRACE> |
| 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() | el = Filter() ) |
| { elg.addElement(el) ; } |
| (<DOT>)? |
| |
| ( |
| { startTriplesBlock() ; } |
| el = TriplesBlock(null) |
| { endTriplesBlock() ; |
| elg.addElement(el) ; } |
| )? |
| )* |
| { endGroup(elg) ; } |
| { return elg ; } |
| } |
| |
| // -- TriplesBlock |
| // Two versions - for SPARQL 1.0 and SPARQL 1.1 (with paths) |
| |
| |
| Element TriplesBlock(ElementTriplesBlock acc) : { } |
| { |
| { if ( acc == null ) |
| acc = new ElementTriplesBlock() ; |
| } |
| TriplesSameSubject(acc) |
| ( <DOT> (TriplesBlock(acc))? )? |
| { return acc ; } |
| } |
| // ----- |
| |
| Element GraphPatternNotTriples() : { Element el = null ; } |
| { |
| ( |
| el = OptionalGraphPattern() |
| | |
| // "GroupPattern" or "GroupPattern" union "GroupPattern" |
| el = GroupOrUnionGraphPattern() |
| | |
| el = GraphGraphPattern() |
| ) |
| { 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 = VarOrIRIref() el = GroupGraphPattern() |
| { return new ElementNamedGraph(n, el) ; } |
| } |
| // 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 ; |
| ExprList aParam = null ; |
| boolean distinct = false ;} |
| { |
| |
| fname = IRIref() |
| a = ArgList() |
| { return new E_Function(fname, a) ; } |
| } |
| |
| ExprList ArgList() : { Expr expr ; ExprList args = new ExprList() ; } |
| { |
| ( |
| <NIL> |
| | |
| <LPAREN> |
| expr = Expression() { args.add(expr) ; } |
| (<COMMA> expr = Expression() { args.add(expr) ; } )* |
| <RPAREN> |
| ) |
| { return args ; } |
| } |
| |
| ExprList ParamList() : { Expr expr ; ExprList args = new ExprList() ; } |
| { |
| // "[ expr, expr ]" |
| ( |
| <LBRACKET> |
| expr = Expression() { args.add(expr) ; } |
| (<COMMA> expr = Expression() { args.add(expr) ; } )* |
| <RBRACKET> |
| ) |
| { 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) : { } |
| { |
| |
| // SPARQL - recursion - does not scale for SPARQL/Update |
| TriplesSameSubject(acc) |
| (<DOT> (ConstructTriples(acc))? )? |
| |
| |
| |
| |
| |
| |
| |
| } |
| |
| // -------- 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 |
| s = TriplesNode(acc) |
| PropertyList(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) |
| )? |
| )* |
| } |
| |
| void PropertyList(Node s, TripleCollector acc) : { } |
| { |
| ( PropertyListNotEmpty(s, acc) ) ? |
| } |
| |
| 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 ; } |
| { |
| { int mark = acc.mark() ; } |
| o = GraphNode(acc) |
| { insert(acc, mark, s, p, path, o) ; } |
| } |
| |
| Node Verb() : { Node p ;} |
| { |
| // Blank nodes as predicates |
| // ( p = VarOrBlankNodeOrIRIref() | <KW_A> { p = nRDFtype ; } ) |
| ( p = VarOrIRIref() | <KW_A> { p = nRDFtype ; } ) |
| { return p ; } |
| } |
| |
| // -------- BGPs with paths. |
| // -------- Entry point: TriplesSameSubjectPath |
| // -------- Paths |
| // -------- Triple expansions |
| |
| // Anything that can stand in a node slot and which is |
| // a number of triples |
| |
| Node TriplesNode(TripleCollector acc) : { Node n ; } |
| { |
| n = Collection(acc) { return n ; } |
| | |
| n = BlankNodePropertyList(acc) { return n ; } |
| |
| |
| |
| |
| } |
| |
| Node BlankNodePropertyList(TripleCollector acc) : { Token t ; } |
| { |
| t = <LBRACKET> |
| { Node n = createBNode(t.beginLine, t.beginColumn) ; } |
| PropertyListNotEmpty(n, acc) |
| <RBRACKET> |
| { return n ; } |
| } |
| // ------- RDF collections |
| |
| Node Collection(TripleCollector acc) : |
| { Node listHead = nRDFnil ; Node lastCell = null ; int mark ; Node n ; Token t ; } |
| { |
| t = <LPAREN> |
| ( |
| { Node cell = createListNode(t.beginLine, t.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 ; } |
| } |
| |
| // -------- Nodes in a graph pattern or template |
| |
| Node GraphNode(TripleCollector acc) : { Node n ; } |
| { |
| n = VarOrTerm() { return n ; } |
| | |
| n = TriplesNode(acc) { return n ; } |
| } |
| |
| Node VarOrTerm() : {Node n = null ; } |
| { |
| ( n = Var() | n = GraphTerm() ) |
| { return n ; } |
| } |
| |
| // Property (if no bNodes) + DESCRIBE |
| Node VarOrIRIref() : {Node n = null ; String iri ; } |
| { |
| ( n = Var() | iri = IRIref() { 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 = IRIref() { 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) ; } |
| |
| |
| |
| |
| |
| |
| )? |
| { 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) ; } |
| |
| // SPARQL Bug. |
| // | n = NumericLiteralPositive() |
| // { |
| // n = stripSign(n) ; |
| // expr2 = asExpr(n) ; |
| // expr1 = new E_Add(expr1, expr2) ; |
| // } |
| // | |
| // n = NumericLiteralNegative() |
| // { |
| // n = stripSign(n) ; |
| // expr2 = asExpr(n) ; |
| // expr1 = new E_Subtract(expr1, expr2) ; |
| // } |
| // )* |
| |
| // Expression - no + or - |
| | |
| ( |
| 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 = IRIrefOrFunction() { return expr ; } |
| |
| // NOT | gn = VarOrTerm() { return asExpr(gn) ; } |
| // Because of IRIrefOrFunction vs <NIL> and blank nodes |
| | gn = RDFLiteral() { return asExpr(gn) ; } |
| | gn = NumericLiteral() { return asExpr(gn) ; } |
| | gn = BooleanLiteral() { return asExpr(gn) ; } |
| | gn = Var() { return asExpr(gn) ; } |
| |
| |
| |
| ) |
| } |
| |
| Expr BrackettedExpression() : { Expr expr ; } |
| { |
| <LPAREN> expr = Expression() <RPAREN> { return expr ; } |
| } |
| |
| Expr BuiltInCall() : { Expr expr ; Expr expr1 = null ; Expr expr2 = null ; |
| Node gn ; Token t ; ExprList a ; } |
| { |
| <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)) ; } |
| | <SAME_TERM> <LPAREN> expr1 = Expression() <COMMA> expr2 = Expression() <RPAREN> |
| { return new E_SameTerm(expr1, expr2) ; } |
| |
| | t = <IS_IRI> <LPAREN> expr = Expression() <RPAREN> |
| { return new E_IsIRI(expr) ; } |
| |
| | t = <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) ; } |
| |
| | // Regular expression matcher |
| expr = RegexExpression() { 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) ; } |
| } |
| // See also FunctionCall. |
| // The case of "q:name()" or "q:agg[]()" or just "q:name" |
| // by expanding out FunctionCall() |
| |
| Expr IRIrefOrFunction() : { String iri ; ExprList a = null ; |
| ExprList aParam = null ; |
| boolean distinct = false ; } |
| { |
| iri = IRIref() |
| ( a = ArgList() )? |
| { if ( a == null ) return asExpr(createNode(iri)) ; |
| return new E_Function(iri, a) ; |
| } |
| } |
| 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 = IRIref() ) |
| )? |
| { 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 IRIref() : { String iri ; } |
| { |
| iri = IRI_REF() { 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 = <ANON> { return createBNode( t.beginLine, t.beginColumn) ; } |
| |
| } |
| |
| String IRI_REF() : { Token t ; } |
| { |
| t = <IRIref> |
| { return resolveQuotedIRI(t.image, t.beginLine, t.beginColumn) ; } |
| } |
| |
| // ------------------------------------------ |
| // Tokens |
| |
| // Comments and whitespace |
| |
| SKIP : { " " | "\t" | "\n" | "\r" | "\f" } |
| |
| TOKEN: { <#WS: " " | "\t" | "\n" | "\r" | "\f"> } |
| |
| SPECIAL_TOKEN : |
| { <SINGLE_LINE_COMMENT: "#" (~["\n","\r"])* ("\n"|"\r"|"\r\n")? > } |
| |
| // Main tokens */ |
| |
| TOKEN: |
| { |
| // Includes # for relative URIs |
| <IRIref: "<" (~[ ">","<", "\"", "{", "}", "^", "\\", "|", "`", |
| "\u0000"-"\u0020"])* ">" > |
| | <PNAME_NS: (<PN_PREFIX>)? ":" > |
| | <PNAME_LN: <PNAME_NS> <PN_LOCAL> > |
| | <BLANK_NODE_LABEL: "_:" <PN_LOCAL> > |
| | <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" > |
| | < DESCRIBE: "describe" > |
| | < CONSTRUCT: "construct" > |
| | < ASK: "ask" > |
| |
| | < LIMIT: "limit" > |
| | < OFFSET: "offset" > |
| | < ORDER: "order" > |
| | < BY: "by" > |
| |
| | < ASC: "asc" > |
| | < DESC: "desc" > |
| |
| // Dataset |
| | < NAMED: "named" > |
| | < FROM: "from" > |
| |
| // Graph pattern operators |
| | < WHERE: "where" > |
| | < AND: "and" > |
| | < GRAPH: "graph" > |
| | < OPTIONAL: "optional" > |
| | < UNION: "union" > |
| | < FILTER: "filter" > |
| |
| // Expression operators |
| | < BOUND: "bound" > |
| | < STR: "str" > |
| | < STRLANG: "strlang" > |
| | < STRDT: "strdt" > |
| | < DTYPE: "datatype" > |
| | < LANG: "lang" > |
| | < LANGMATCHES: "langmatches" > |
| | < IS_URI: "isURI" > |
| | < IS_IRI: "isIRI" > |
| | < IS_BLANK: "isBlank" > |
| | < IS_LITERAL: "isLiteral" > |
| | < REGEX: "regex" > |
| | < SAME_TERM: "sameTerm" > |
| |
| | <TRUE: "true" > |
| | <FALSE: "false" > |
| } |
| // ------------------------------------------------- |
| |
| TOKEN : |
| { |
| < #DIGITS: (["0"-"9"])+> |
| | < INTEGER: <DIGITS> > |
| | < DECIMAL: ( <DIGITS> "." (<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: ")" > |
| |
| | <NIL: <LPAREN> (<WS>|<SINGLE_LINE_COMMENT>)* <RPAREN> > |
| |
| | < LBRACE: "{" > |
| | < RBRACE: "}" > |
| |
| | < LBRACKET: "[" > |
| | < RBRACKET: "]" > |
| | < ANON: <LBRACKET> (<WS>|<SINGLE_LINE_COMMENT>)* <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: "@"> |
| } |
| |
| // 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] |
| | |
| <#PN_CHARS_U: <PN_CHARS_BASE> | "_" > |
| | |
| // No DOT |
| <#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>)? > |
| | |
| // With a leading "_", no dot at end of local name. |
| <#PN_LOCAL: (<PN_CHARS_U> | ["0"-"9"]) ((<PN_CHARS>|".")* <PN_CHARS>)? > |
| | |
| // NCNAME without "-" and ".", allowing leading digits. |
| <#VARNAME: ( <PN_CHARS_U> | ["0"-"9"] ) |
| ( <PN_CHARS_U> | ["0"-"9"] | "\u00B7" | |
| ["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] )* > |
| } |
| |
| // Catch-all tokens. Must be last. |
| // Any non-whitespace. Causes a parser exception, rather than a |
| // token manager error (with hidden line numbers). |
| // Only bad IRIs (e.g. spaces) now give unhelpful parse errors. |
| TOKEN: |
| { |
| <#UNKNOWN: (~[" ","\t","\n","\r","\f" ])+ > |
| } |
| |
| /* |
| # Local Variables: |
| # tab-width: 4 |
| # indent-tabs-mode: nil |
| # comment-default-style: "//" |
| # End: |
| */ |