/* -*- Mode: c; c-basic-offset: 2 -*- * * sparql_parser.y - Rasqal SPARQL parser over tokens from sparql_lexer.l * * $Id: sparql_parser.y,v 1.1 2008-07-08 10:45:05 larsl Exp $ * * Copyright (C) 2004-2007, David Beckett http://purl.org/net/dajobe/ * Copyright (C) 2004-2005, University of Bristol, UK http://www.bristol.ac.uk/ * * This package is Free Software and part of Redland http://librdf.org/ * * It is licensed under the following three licenses as alternatives: * 1. GNU Lesser General Public License (LGPL) V2.1 or any newer version * 2. GNU General Public License (GPL) V2 or any newer version * 3. Apache License, V2.0 or any newer version * * You may not use this file except in compliance with at least one of * the above three licenses. * * See LICENSE.html or LICENSE.txt at the top of this package for the * complete terms and further detail along with the license texts for * the licenses in COPYING.LIB, COPYING and LICENSE-2.0.txt respectively. * * References: * SPARQL Query Language for RDF, W3C Candidate Recommendation 6 April 2006 * http://www.w3.org/TR/2006/CR-rdf-sparql-query-20060406/ * * Editor's draft of above http://www.w3.org/2001/sw/DataAccess/rq23/ * */ %{ #ifdef HAVE_CONFIG_H #include #endif #ifdef WIN32 #include #endif #include #include #include #include #include #define YY_DECL int sparql_lexer_lex (YYSTYPE *sparql_parser_lval, yyscan_t yyscanner) #define YY_NO_UNISTD_H 1 #include #include /* #undef RASQAL_DEBUG #define RASQAL_DEBUG 2 */ #define DEBUG_FH stdout /* Make verbose error messages for syntax errors */ #define YYERROR_VERBOSE 1 /* Fail with an debug error message if RASQAL_DEBUG > 1 */ #if RASQAL_DEBUG > 1 #define YYERROR_MSG(msg) do { fputs("** YYERROR ", DEBUG_FH); fputs(msg, DEBUG_FH); fputc('\n', DEBUG_FH); YYERROR; } while(0) #else #define YYERROR_MSG(ignore) YYERROR #endif /* Slow down the grammar operation and watch it work */ #if RASQAL_DEBUG > 2 #define YYDEBUG 1 #endif /* the lexer does not seem to track this */ #undef RASQAL_SPARQL_USE_ERROR_COLUMNS /* Missing sparql_lexer.c/h prototypes */ int sparql_lexer_get_column(yyscan_t yyscanner); /* Not used here */ /* void sparql_lexer_set_column(int column_no , yyscan_t yyscanner);*/ /* What the lexer wants */ extern int sparql_lexer_lex (YYSTYPE *sparql_parser_lval, yyscan_t scanner); #define YYLEX_PARAM ((rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context))->scanner /* Pure parser argument (a void*) */ #define YYPARSE_PARAM rq /* Make the yyerror below use the rdf_parser */ #undef yyerror #define yyerror(message) sparql_query_error((rasqal_query*)rq, message) /* Make lex/yacc interface as small as possible */ #undef yylex #define yylex sparql_lexer_lex static int sparql_parse(rasqal_query* rq); static void sparql_query_error(rasqal_query* rq, const char *message); static void sparql_query_error_full(rasqal_query *rq, const char *message, ...) RASQAL_PRINTF_FORMAT(2, 3); %} /* directives */ %pure-parser /* Interface between lexer and parser */ %union { raptor_sequence *seq; rasqal_variable *variable; rasqal_literal *literal; rasqal_triple *triple; rasqal_expression *expr; rasqal_graph_pattern *graph_pattern; double floating; raptor_uri *uri; unsigned char *name; rasqal_formula *formula; } /* * shift/reduce conflicts * FIXME: document this */ %expect 8 /* word symbols */ %token SELECT FROM WHERE %token OPTIONAL DESCRIBE CONSTRUCT ASK DISTINCT REDUCED LIMIT UNION %token PREFIX BASE BOUND %token GRAPH NAMED FILTER OFFSET ORDER BY REGEX ASC DESC LANGMATCHES %token A "a" %token STR "str" %token LANG "lang" %token DATATYPE "datatype" %token ISURI "isUri" %token ISBLANK "isBlank" %token ISLITERAL "isLiteral" %token SAMETERM "sameTerm" /* LAQRS */ %token EXPLAIN GROUP COUNT AS %token DELETE INSERT /* expression delimiters */ %token ',' '(' ')' '[' ']' '{' '}' %token '?' '$' /* SC booleans */ %left SC_OR %left SC_AND /* operations */ %left EQ %left NEQ %left LT %left GT %left LE %left GE /* arithmetic operations */ %left '+' '-' '*' '/' /* unary operations */ /* literals */ %token STRING_LITERAL "string literal" %token DOUBLE_LITERAL "double literal" %token DOUBLE_POSITIVE_LITERAL "double positive literal" %token DOUBLE_NEGATIVE_LITERAL "double negative literal" %token INTEGER_LITERAL "integer literal" %token INTEGER_POSITIVE_LITERAL "integer positive literal" %token INTEGER_NEGATIVE_LITERAL "integer negative literal" %token DECIMAL_LITERAL "decimal literal" %token DECIMAL_POSITIVE_LITERAL "decimal positive literal" %token DECIMAL_NEGATIVE_LITERAL "decimal negative literal" %token BOOLEAN_LITERAL "boolean literal" %token URI_LITERAL "URI literal" %token URI_LITERAL_BRACE "URI literal (" %token QNAME_LITERAL "QName literal" %token QNAME_LITERAL_BRACE "QName literal (" %token BLANK_LITERAL "blank node literal" %token IDENTIFIER "identifier" %type SelectQuery ConstructQuery DescribeQuery %type SelectExpressionList VarOrIRIrefList ArgList ConstructTriplesOpt %type ConstructTemplate OrderConditionList %type GraphNodeListNotEmpty SelectExpressionListTail %type TriplesSameSubject TriplesSameSubjectDotListOpt %type PropertyList PropertyListTailOpt PropertyListNotEmpty %type ObjectList ObjectTail Collection %type VarOrTerm Verb Object GraphNode TriplesNode %type TriplesBlockOpt BlankNodePropertyList %type GroupGraphPattern GraphPattern %type GraphGraphPattern OptionalGraphPattern %type GroupOrUnionGraphPattern GroupOrUnionGraphPatternList %type GraphPatternNotTriples %type FilteredBasicGraphPattern %type Expression ConditionalOrExpression ConditionalAndExpression %type RelationalExpression AdditiveExpression %type MultiplicativeExpression UnaryExpression %type BuiltInCall RegexExpression FunctionCall %type BrackettedExpression PrimaryExpression %type OrderCondition Filter Constraint SelectExpression %type AggregateExpression CountAggregateExpression %type GraphTerm IRIref BlankNode %type VarOrIRIref %type IRIrefBrace SourceSelector %type NumericLiteral NumericLiteralUnsigned %type NumericLiteralPositive NumericLiteralNegative %type Var VarName SelectTerm %destructor { if($$) rasqal_free_literal($$); } STRING_LITERAL DOUBLE_LITERAL INTEGER_LITERAL DECIMAL_LITERAL DOUBLE_POSITIVE_LITERAL DOUBLE_NEGATIVE_LITERAL INTEGER_POSITIVE_LITERAL INTEGER_NEGATIVE_LITERAL DECIMAL_POSITIVE_LITERAL DECIMAL_NEGATIVE_LITERAL BOOLEAN_LITERAL %destructor { if($$) raptor_free_uri($$); } URI_LITERAL URI_LITERAL_BRACE %destructor { if($$) RASQAL_FREE(cstring, $$); } QNAME_LITERAL QNAME_LITERAL_BRACE BLANK_LITERAL IDENTIFIER %destructor { if($$) raptor_free_sequence($$); } SelectQuery ConstructQuery DescribeQuery SelectExpressionList VarOrIRIrefList ArgList ConstructTriplesOpt ConstructTemplate OrderConditionList GraphNodeListNotEmpty SelectExpressionListTail %destructor { if($$) rasqal_free_formula($$); } TriplesSameSubject TriplesSameSubjectDotListOpt PropertyList PropertyListTailOpt PropertyListNotEmpty ObjectList ObjectTail Collection VarOrTerm Verb Object GraphNode TriplesNode TriplesBlockOpt BlankNodePropertyList %destructor { if($$) rasqal_free_graph_pattern($$); } GroupGraphPattern GraphPattern GraphGraphPattern OptionalGraphPattern GroupOrUnionGraphPattern GroupOrUnionGraphPatternList GraphPatternNotTriples FilteredBasicGraphPattern %destructor { if($$) rasqal_free_expression($$); } Expression ConditionalOrExpression ConditionalAndExpression RelationalExpression AdditiveExpression MultiplicativeExpression UnaryExpression BuiltInCall RegexExpression FunctionCall BrackettedExpression PrimaryExpression OrderCondition Filter Constraint SelectExpression AggregateExpression CountAggregateExpression %destructor { if($$) rasqal_free_literal($$); } GraphTerm IRIref BlankNode VarOrIRIref IRIrefBrace SourceSelector NumericLiteral NumericLiteralUnsigned NumericLiteralPositive NumericLiteralNegative %destructor { if($$) rasqal_free_variable($$); } Var VarName SelectTerm %% /* Below here, grammar terms are numbered from * http://www.w3.org/TR/2005/WD-rdf-sparql-query-20051123/ * except where noted */ /* SPARQL Grammar: [1] Query */ Query: Prologue ExplainOpt ReportFormat { } ; /* LAQRS */ ExplainOpt: EXPLAIN { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context); if(sparql->extended) ((rasqal_query*)rq)->explain=1; else sparql_syntax_error((rasqal_query*)rq, "EXPLAIN cannot be used with SPARQL"); } | { /* nothing to do */ } ; /* NEW Grammar Term pulled out of [1] Query */ ReportFormat: SelectQuery { ((rasqal_query*)rq)->selects=$1; ((rasqal_query*)rq)->verb=RASQAL_QUERY_VERB_SELECT; } | ConstructQuery { ((rasqal_query*)rq)->constructs=$1; ((rasqal_query*)rq)->verb=RASQAL_QUERY_VERB_CONSTRUCT; } | DescribeQuery { ((rasqal_query*)rq)->describes=$1; ((rasqal_query*)rq)->verb=RASQAL_QUERY_VERB_DESCRIBE; } | AskQuery { ((rasqal_query*)rq)->verb=RASQAL_QUERY_VERB_ASK; } | DeleteQuery { ((rasqal_query*)rq)->verb=RASQAL_QUERY_VERB_DELETE; } | InsertQuery { ((rasqal_query*)rq)->verb=RASQAL_QUERY_VERB_INSERT; } ; /* SPARQL Grammar: [2] Prologue */ Prologue: BaseDeclOpt PrefixDeclListOpt { /* nothing to do */ } ; /* SPARQL Grammar: [3] BaseDecl */ BaseDeclOpt: BASE URI_LITERAL { rasqal_query_set_base_uri((rasqal_query*)rq, $2); } | /* empty */ { /* nothing to do */ } ; /* SPARQL Grammar: [4] PrefixDecl renamed to include optional list */ PrefixDeclListOpt: PrefixDeclListOpt PREFIX IDENTIFIER URI_LITERAL { raptor_sequence *seq=((rasqal_query*)rq)->prefixes; unsigned const char* prefix_string=$3; size_t l=0; if(prefix_string) l=strlen((const char*)prefix_string); if(raptor_namespaces_find_namespace(((rasqal_query*)rq)->namespaces, prefix_string, l)) { /* A prefix may be defined only once */ sparql_syntax_warning(((rasqal_query*)rq), "PREFIX %s can be defined only once.", prefix_string ? (const char*)prefix_string : ":"); RASQAL_FREE(cstring, prefix_string); raptor_free_uri($4); } else { rasqal_prefix *p=rasqal_new_prefix(prefix_string, $4); if(!p) YYERROR_MSG("PrefixDeclOpt: failed to create new prefix"); if(raptor_sequence_push(seq, p)) YYERROR_MSG("PrefixDeclOpt: cannot push prefix to seq"); if(rasqal_query_declare_prefix(((rasqal_query*)rq), p)) { YYERROR_MSG("PrefixDeclOpt: cannot declare prefix"); } } } | /* empty */ { /* nothing to do, rq->prefixes already initialised */ } ; /* SPARQL Grammar: [5] SelectQuery */ SelectQuery: SELECT DISTINCT SelectExpressionList DatasetClauseListOpt WhereClauseOpt SolutionModifier { $$=$3; ((rasqal_query*)rq)->distinct=1; } | SELECT REDUCED SelectExpressionList DatasetClauseListOpt WhereClauseOpt SolutionModifier { $$=$3; ((rasqal_query*)rq)->distinct=2; } | SELECT SelectExpressionList DatasetClauseListOpt WhereClauseOpt SolutionModifier { $$=$2; } ; /* NEW Grammar Term pulled out of [5] SelectQuery * A list of SelectTerm OR a NULL list and a wildcard */ SelectExpressionList: SelectExpressionListTail { $$=$1; } | '*' { $$=NULL; ((rasqal_query*)rq)->wildcard=1; } ; /* NEW Grammar Term pulled out of [5] SelectQuery * Non-empty list of SelectTerm with optional commas */ SelectExpressionListTail: SelectExpressionListTail SelectTerm { $$=$1; if(raptor_sequence_push($$, $2)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("SelectExpressionListTail 1: sequence push failed"); } } | SelectExpressionListTail ',' SelectTerm { $$=$1; if(raptor_sequence_push($$, $3)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("SelectExpressionListTail 2: sequence push failed"); } } | SelectTerm { /* The variables are freed from the raptor_query field variables */ $$=raptor_new_sequence(NULL, (raptor_sequence_print_handler*)rasqal_variable_print); if(!$$) YYERROR_MSG("SelectExpressionListTail 3: failed to create sequence"); if(raptor_sequence_push($$, $1)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("SelectExpressionListTail 3: sequence push failed"); } } ; /* NEW Grammar Term pulled out of [5] SelectQuery * A variable (?x) or a select expression assigned to a name (x) with AS */ SelectTerm: Var { $$=$1; } | SelectExpression AS VarName { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context); $$=NULL; if(!sparql->extended) sparql_syntax_error((rasqal_query*)rq, "SELECT expression AS Variable cannot be used with SPARQL"); else { if(rasqal_expression_mentions_variable($1, $3)) { sparql_query_error_full((rasqal_query*)rq, "SELECT expression contains the AS variable name '%s'", $3->name); } else { $$=$3; $3->expression=$1; } } } ; /* NEW Grammar Term pulled out of [5] SelectQuery */ SelectExpression: AggregateExpression { $$=$1; } | '(' AggregateExpression ')' { $$=$2; } | '(' Expression ')' { $$=$2; } ; AggregateExpression: CountAggregateExpression { $$=$1; } ; CountAggregateExpression: COUNT '(' Expression ')' { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context); if(!sparql->extended) { sparql_syntax_error((rasqal_query*)rq, "COUNT cannot be used with SPARQL"); $$=NULL; } else { $$=rasqal_new_1op_expression(RASQAL_EXPR_COUNT, $3); if(!$$) YYERROR_MSG("CountAggregateExpression 1: cannot create expr"); } } | COUNT '(' '*' ')' { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context); if(!sparql->extended) { sparql_syntax_error((rasqal_query*)rq, "COUNT cannot be used with SPARQL"); $$=NULL; } else { rasqal_expression* vs=rasqal_new_0op_expression(RASQAL_EXPR_VARSTAR); if(!vs) YYERROR_MSG("CountAggregateExpression 2: cannot create varstar expr"); $$=rasqal_new_1op_expression(RASQAL_EXPR_COUNT, vs); if(!$$) YYERROR_MSG("CountAggregateExpression 2: cannot create expr"); } } ; /* SPARQL Grammar: [6] DescribeQuery */ DescribeQuery: DESCRIBE VarOrIRIrefList DatasetClauseListOpt WhereClauseOpt SolutionModifier { $$=$2; } | DESCRIBE '*' DatasetClauseListOpt WhereClauseOpt SolutionModifier { $$=NULL; } ; /* NEW Grammar Term pulled out of [6] DescribeQuery */ VarOrIRIrefList: VarOrIRIrefList VarOrIRIref { $$=$1; if(raptor_sequence_push($$, $2)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("VarOrIRIrefList 1: sequence push failed"); } } | VarOrIRIrefList ',' VarOrIRIref { $$=$1; if(raptor_sequence_push($$, $3)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("VarOrIRIrefList 2: sequence push failed"); } } | VarOrIRIref { $$=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_literal, (raptor_sequence_print_handler*)rasqal_literal_print); if(!$$) YYERROR_MSG("VarOrIRIrefList 3: cannot create seq"); if(raptor_sequence_push($$, $1)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("VarOrIRIrefList 3: sequence push failed"); } } ; /* SPARQL Grammar: [7] ConstructQuery */ ConstructQuery: CONSTRUCT ConstructTemplate DatasetClauseListOpt WhereClauseOpt SolutionModifier { $$=$2; } ; /* SPARQL Grammar: [8] AskQuery */ AskQuery: ASK DatasetClauseListOpt WhereClauseOpt { /* nothing to do */ } ; /* LAQRS */ DeleteQuery: DELETE DatasetClauseListOpt WhereClauseOpt { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context); if(!sparql->extended) sparql_syntax_error((rasqal_query*)rq, "DELETE cannot be used with SPARQL"); } ; /* LAQRS */ InsertQuery: INSERT DatasetClauseListOpt WhereClauseOpt { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context); if(!sparql->extended) sparql_syntax_error((rasqal_query*)rq, "INSERT cannot be used with SPARQL"); } ; /* SPARQL Grammar: [9] DatasetClause */ DatasetClauseListOpt: DatasetClauseListOpt FROM DefaultGraphClause | DatasetClauseListOpt FROM NamedGraphClause | /* empty */ ; /* SPARQL Grammar: [10] DefaultGraphClause */ DefaultGraphClause: SourceSelector { if($1) { raptor_uri* uri=rasqal_literal_as_uri($1); if(rasqal_query_add_data_graph((rasqal_query*)rq, uri, NULL, RASQAL_DATA_GRAPH_BACKGROUND)) { rasqal_free_literal($1); YYERROR_MSG("DefaultGraphClause: rasqal_query_add_data_graph failed"); } rasqal_free_literal($1); } } ; /* SPARQL Grammar: [11] NamedGraphClause */ NamedGraphClause: NAMED SourceSelector { if($2) { raptor_uri* uri=rasqal_literal_as_uri($2); if(rasqal_query_add_data_graph((rasqal_query*)rq, uri, uri, RASQAL_DATA_GRAPH_NAMED)) { rasqal_free_literal($2); YYERROR_MSG("NamedGraphClause: rasqal_query_add_data_graph failed"); } rasqal_free_literal($2); } } ; /* SPARQL Grammar: [12] SourceSelector */ SourceSelector: IRIref { $$=$1; } ; /* SPARQL Grammar: [13] WhereClause - remained for clarity */ WhereClauseOpt: WHERE GroupGraphPattern { ((rasqal_query*)rq)->query_graph_pattern=$2; } | GroupGraphPattern { ((rasqal_query*)rq)->query_graph_pattern=$1; } | /* empty */ ; /* SPARQL Grammar: [14] SolutionModifier */ SolutionModifier: GroupClauseOpt OrderClauseOpt LimitOffsetClausesOpt ; /* LAQRS */ GroupClauseOpt: GROUP BY OrderConditionList { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)(((rasqal_query*)rq)->context); if(!sparql->extended) sparql_syntax_error((rasqal_query*)rq, "GROUP BY cannot be used with SPARQL"); else if(((rasqal_query*)rq)->verb == RASQAL_QUERY_VERB_ASK) { sparql_query_error((rasqal_query*)rq, "GROUP BY cannot be used with ASK"); } else { raptor_sequence *seq=$3; ((rasqal_query*)rq)->group_conditions_sequence=seq; if(seq) { int i; for(i=0; i < raptor_sequence_size(seq); i++) { rasqal_expression* e=(rasqal_expression*)raptor_sequence_get_at(seq, i); if(e->op == RASQAL_EXPR_ORDER_COND_ASC) e->op = RASQAL_EXPR_GROUP_COND_ASC; else e->op = RASQAL_EXPR_GROUP_COND_DESC; } } } } | /* empty */ ; /* SPARQL Grammar: [15] LimitOffsetClauses */ LimitOffsetClausesOpt: LimitClause OffsetClause | OffsetClause LimitClause | LimitClause | OffsetClause | /* empty */ { } ; /* SPARQL Grammar: [16] OrderClause - remained for clarity */ OrderClauseOpt: ORDER BY OrderConditionList { if(((rasqal_query*)rq)->verb == RASQAL_QUERY_VERB_ASK) { sparql_query_error((rasqal_query*)rq, "ORDER BY cannot be used with ASK"); } else { ((rasqal_query*)rq)->order_conditions_sequence=$3; } } | /* empty */ ; /* NEW Grammar Term pulled out of [16] OrderClauseOpt */ OrderConditionList: OrderConditionList OrderCondition { $$=$1; if($2) if(raptor_sequence_push($$, $2)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("OrderConditionList 1: sequence push failed"); } } | OrderCondition { $$=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_expression, (raptor_sequence_print_handler*)rasqal_expression_print); if(!$$) { if($1) rasqal_free_expression($1); YYERROR_MSG("OrderConditionList 2: cannot create sequence"); } if($1) if(raptor_sequence_push($$, $1)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("OrderConditionList 2: sequence push failed"); } } ; /* SPARQL Grammar: [17] OrderCondition */ OrderCondition: ASC BrackettedExpression { $$=rasqal_new_1op_expression(RASQAL_EXPR_ORDER_COND_ASC, $2); if(!$$) YYERROR_MSG("OrderCondition 1: cannot create expr"); } | DESC BrackettedExpression { $$=rasqal_new_1op_expression(RASQAL_EXPR_ORDER_COND_DESC, $2); if(!$$) YYERROR_MSG("OrderCondition 2: cannot create expr"); } | FunctionCall { /* The direction of ordering is ascending by default */ $$=rasqal_new_1op_expression(RASQAL_EXPR_ORDER_COND_ASC, $1); if(!$$) YYERROR_MSG("OrderCondition 3: cannot create expr"); } | Var { rasqal_literal* l; rasqal_expression *e; l=rasqal_new_variable_literal(((rasqal_query*)rq)->world, $1); if(!l) YYERROR_MSG("OrderCondition 4: cannot create lit"); e=rasqal_new_literal_expression(l); if(!e) YYERROR_MSG("OrderCondition 4: cannot create lit expr"); /* The direction of ordering is ascending by default */ $$=rasqal_new_1op_expression(RASQAL_EXPR_ORDER_COND_ASC, e); if(!$$) YYERROR_MSG("OrderCondition 1: cannot create expr"); } | BrackettedExpression { /* The direction of ordering is ascending by default */ $$=rasqal_new_1op_expression(RASQAL_EXPR_ORDER_COND_ASC, $1); if(!$$) YYERROR_MSG("OrderCondition 5: cannot create expr"); } | BuiltInCall { /* The direction of ordering is ascending by default */ $$=rasqal_new_1op_expression(RASQAL_EXPR_ORDER_COND_ASC, $1); if(!$$) YYERROR_MSG("OrderCondition 6: cannot create expr"); } ; /* SPARQL Grammar: [18] LimitClause - remained for clarity */ LimitClause: LIMIT INTEGER_LITERAL { if(((rasqal_query*)rq)->verb == RASQAL_QUERY_VERB_ASK) { sparql_query_error((rasqal_query*)rq, "LIMIT cannot be used with ASK"); } else { if($2 != NULL) { ((rasqal_query*)rq)->limit=$2->value.integer; rasqal_free_literal($2); } } } ; /* SPARQL Grammar: [19] OffsetClause - remained for clarity */ OffsetClause: OFFSET INTEGER_LITERAL { if(((rasqal_query*)rq)->verb == RASQAL_QUERY_VERB_ASK) { sparql_query_error((rasqal_query*)rq, "LIMIT cannot be used with ASK"); } else { if($2 != NULL) { ((rasqal_query*)rq)->offset=$2->value.integer; rasqal_free_literal($2); } } } ; /* SPARQL Grammar: [20] GroupGraphPattern */ GroupGraphPattern: '{' GraphPattern '}' { $$=$2; } ; /* NEW Grammar Term */ DotOptional: '.' | /* empty */ ; /* SPARQL Grammar: [21] GraphPattern */ GraphPattern: FilteredBasicGraphPattern GraphPatternNotTriples DotOptional GraphPattern { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "GraphPattern 1\n FilteredBasicGraphPattern="); if($1) rasqal_graph_pattern_print($1, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, ", GraphPatternNotTriples="); if($2) rasqal_graph_pattern_print($2, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, ", GraphPattern="); if($4) rasqal_graph_pattern_print($4, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n", DEBUG_FH); #endif $$=$4; /* push ($1,$2) to start of $4 graph sequence */ if($2) if(raptor_sequence_shift($$->graph_patterns, $2)) { if($1) rasqal_free_graph_pattern($1); rasqal_free_graph_pattern($$); $$=NULL; YYERROR_MSG("GraphPattern 1: sequence shift $2 failed"); } if($1) if(raptor_sequence_shift($$->graph_patterns, $1)) { rasqal_free_graph_pattern($$); $$=NULL; YYERROR_MSG("GraphPattern 1: sequence shift $1 failed"); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after grouping graph pattern="); if($$) rasqal_graph_pattern_print($$, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } | FilteredBasicGraphPattern { raptor_sequence *seq; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "GraphPattern 2\n FilteredBasicGraphPattern="); if($1) rasqal_graph_pattern_print($1, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n", DEBUG_FH); #endif seq=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_graph_pattern, (raptor_sequence_print_handler*)rasqal_graph_pattern_print); if(!seq) { if($1) rasqal_free_graph_pattern($1); YYERROR_MSG("GraphPattern 2: cannot create sequence"); } if($1) if(raptor_sequence_push(seq, $1)) { raptor_free_sequence(seq); YYERROR_MSG("GraphPattern 2: sequence push failed"); } $$=rasqal_new_graph_pattern_from_sequence((rasqal_query*)rq, seq, RASQAL_GRAPH_PATTERN_OPERATOR_GROUP); if(!$$) YYERROR_MSG("GraphPattern 2: cannot create gp"); #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after grouping graph pattern="); rasqal_graph_pattern_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } ; /* SPARQL Grammar Term [21] FilteredBasicGraphPattern */ FilteredBasicGraphPattern: TriplesBlockOpt Filter DotOptional FilteredBasicGraphPattern { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "FilteredBasicGraphPattern 1\n TriplesBlockOpt="); if($1) rasqal_formula_print($1, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, ", Constraint="); if($2) rasqal_expression_print($2, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, ", FilteredBasicGraphPattern="); if($4) rasqal_graph_pattern_print($4, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n", DEBUG_FH); #endif $$=$4; if($2) { if(rasqal_graph_pattern_add_constraint($$, $2)) { if($1) rasqal_free_formula($1); rasqal_free_graph_pattern($$); $$=NULL; YYERROR_MSG("FilteredBasicGraphPattern 1: cannot add constraint"); } } /* push $1 to end of $4 graph sequence */ if($1) { rasqal_graph_pattern *gp; gp=rasqal_engine_new_basic_graph_pattern_from_formula((rasqal_query*)rq, $1); if(!gp) { rasqal_free_graph_pattern($$); $$=NULL; YYERROR_MSG("FilteredBasicGraphPattern 1: cannot create gp"); } if(raptor_sequence_push($$->graph_patterns, gp)) { rasqal_free_graph_pattern($$); $$=NULL; YYERROR_MSG("FilteredBasicGraphPattern 1: sequence push failed"); } } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after grouping graph pattern="); if($$) rasqal_graph_pattern_print($$, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } | TriplesBlockOpt { rasqal_graph_pattern *formula_gp=NULL; raptor_sequence *seq; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "FilteredBasicGraphPattern 2\n TriplesBlockOpt="); if($1) rasqal_formula_print($1, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n", DEBUG_FH); #endif if($1) { formula_gp=rasqal_engine_new_basic_graph_pattern_from_formula((rasqal_query*)rq, $1); if(!formula_gp) YYERROR_MSG("FilteredBasicGraphPattern 2: cannot create formula_gp"); } seq=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_graph_pattern, (raptor_sequence_print_handler*)rasqal_graph_pattern_print); if(!seq) { if(formula_gp) rasqal_free_graph_pattern(formula_gp); YYERROR_MSG("FilteredBasicGraphPattern 2: cannot create sequence"); } if(formula_gp) if(raptor_sequence_push(seq, formula_gp)) { raptor_free_sequence(seq); YYERROR_MSG("FilteredBasicGraphPattern 2: sequence push failed"); } $$=rasqal_new_graph_pattern_from_sequence((rasqal_query*)rq, seq, RASQAL_GRAPH_PATTERN_OPERATOR_GROUP); if(!$$) YYERROR_MSG("FilteredBasicGraphPattern 2: cannot create gp"); #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after, group graph pattern="); rasqal_graph_pattern_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } ; /* SPARQL Grammar: [21] TriplesBlock */ TriplesBlockOpt: TriplesSameSubject TriplesSameSubjectDotListOpt { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "TriplesBlockOpt\n TriplesSameSubject="); if($1) rasqal_formula_print($1, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs(" TriplesSameSubjectDotListOpt=", DEBUG_FH); if($2) rasqal_formula_print($2, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n", DEBUG_FH); #endif /* $1 and $2 are freed as necessary */ $$=rasqal_formula_join($1, $2); if(!$$) YYERROR_MSG("TriplesBlockOpt: formula join failed"); #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after joining formula="); rasqal_formula_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } | /* empty */ { $$=NULL; } ; /* New Grammar Term pulled out of [21] TriplesBlock * ( '.' TriplesBlock? )* */ TriplesSameSubjectDotListOpt: TriplesSameSubjectDotListOpt TriplesSameSubject { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "TriplesSameSubjectDotTriplesOpt\n TriplesSameSubjectDotListOpt="); if($1) rasqal_formula_print($1, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs(" TriplesSameSubject=", DEBUG_FH); if($2) rasqal_formula_print($2, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n", DEBUG_FH); #endif /* $1 and $2 are freed as necessary */ $$=rasqal_formula_join($1, $2); if(!$$) YYERROR_MSG("TriplesSameSubjectDotTriplesOpt: formula join failed"); #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after joining formula="); rasqal_formula_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } | TriplesSameSubjectDotListOpt '.' { $$=$1; } | /* empty */ { $$=NULL; } ; /* SPARQL Grammar: [22] GraphPatternNotTriples */ GraphPatternNotTriples: OptionalGraphPattern { $$=$1; } | GroupOrUnionGraphPattern { $$=$1; } | GraphGraphPattern { $$=$1; } ; /* SPARQL Grammar: [23] OptionalGraphPattern */ OptionalGraphPattern: OPTIONAL GroupGraphPattern { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "PatternElementForms 4\n graphpattern="); if($2) rasqal_graph_pattern_print($2, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n\n", DEBUG_FH); #endif if($2) $2->op = RASQAL_GRAPH_PATTERN_OPERATOR_OPTIONAL; $$=$2; } ; /* SPARQL Grammar: [24] GraphGraphPattern */ GraphGraphPattern: GRAPH VarOrIRIref GroupGraphPattern { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "GraphGraphPattern 2\n varoruri="); rasqal_literal_print($2, DEBUG_FH); fprintf(DEBUG_FH, ", graphpattern="); if($3) rasqal_graph_pattern_print($3, DEBUG_FH); else fputs("NULL", DEBUG_FH); fputs("\n\n", DEBUG_FH); #endif if($3) { rasqal_graph_pattern_set_origin($3, $2); $3->op = RASQAL_GRAPH_PATTERN_OPERATOR_GRAPH; } rasqal_free_literal($2); $$=$3; } ; /* SPARQL Grammar: [26] GroupOrUnionGraphPattern */ GroupOrUnionGraphPattern: GroupGraphPattern UNION GroupOrUnionGraphPatternList { $$=$3; if(raptor_sequence_push($$->graph_patterns, $1)) { rasqal_free_graph_pattern($$); $$=NULL; YYERROR_MSG("GroupOrUnionGraphPattern: sequence push failed"); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "UnionGraphPattern\n graphpattern="); rasqal_graph_pattern_print($$, DEBUG_FH); fputs("\n\n", DEBUG_FH); #endif } | GroupGraphPattern { $$=$1; } ; /* NEW Grammar Term pulled out of [26] GroupOrUnionGraphPattern */ GroupOrUnionGraphPatternList: GroupOrUnionGraphPatternList UNION GroupGraphPattern { $$=$1; if($3) if(raptor_sequence_push($$->graph_patterns, $3)) { rasqal_free_graph_pattern($$); $$=NULL; YYERROR_MSG("GroupOrUnionGraphPatternList 1: sequence push failed"); } } | GroupGraphPattern { raptor_sequence *seq; seq=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_graph_pattern, (raptor_sequence_print_handler*)rasqal_graph_pattern_print); if(!seq) { if($1) rasqal_free_graph_pattern($1); YYERROR_MSG("GroupOrUnionGraphPatternList 2: cannot create sequence"); } if($1) if(raptor_sequence_push(seq, $1)) { raptor_free_sequence(seq); YYERROR_MSG("GroupOrUnionGraphPatternList 2: sequence push failed"); } $$=rasqal_new_graph_pattern_from_sequence((rasqal_query*)rq, seq, RASQAL_GRAPH_PATTERN_OPERATOR_UNION); if(!$$) YYERROR_MSG("GroupOrUnionGraphPatternList 1: cannot create gp"); } ; /* SPARQL Grammar: [26] Filter */ Filter: FILTER Constraint { $$=$2; } ; /* SPARQL Grammar: [27] Constraint */ Constraint: BrackettedExpression { $$=$1; } | BuiltInCall { $$=$1; } | FunctionCall { $$=$1; } ; /* SPARQL Grammar: [28] FunctionCall */ FunctionCall: IRIrefBrace ArgList ')' { raptor_uri* uri=rasqal_literal_as_uri($1); if(!$2) { $2=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_expression, (raptor_sequence_print_handler*)rasqal_expression_print); if(!$2) { rasqal_free_literal($1); YYERROR_MSG("FunctionCall: cannot create sequence"); } } uri=raptor_uri_copy(uri); if(raptor_sequence_size($2) == 1 && rasqal_xsd_is_datatype_uri(((rasqal_query*)rq)->world, uri)) { rasqal_expression* e=(rasqal_expression*)raptor_sequence_pop($2); $$=rasqal_new_cast_expression(uri, e); raptor_free_sequence($2); } else { $$=rasqal_new_function_expression(uri, $2); } rasqal_free_literal($1); if(!$$) YYERROR_MSG("FunctionCall: cannot create expr"); } ; /* SPARQL Grammar: [29] ArgList */ ArgList: ArgList ',' Expression { $$=$1; if($3) if(raptor_sequence_push($$, $3)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("ArgList 1: sequence push failed"); } } | Expression { $$=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_expression, (raptor_sequence_print_handler*)rasqal_expression_print); if(!$$) { if($1) rasqal_free_expression($1); YYERROR_MSG("ArgList 2: cannot create sequence"); } if($1) if(raptor_sequence_push($$, $1)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("ArgList 2: sequence push failed"); } } | /* empty */ { $$=NULL; } ; /* SPARQL Grammar: [30] ConstructTemplate */ ConstructTemplate: '{' ConstructTriplesOpt '}' { $$=$2; } ; /* SPARQL Grammar: [31] ConstructTriples renamed for clarity */ ConstructTriplesOpt: TriplesSameSubject '.' ConstructTriplesOpt { $$=NULL; if($1) { $$=$1->triples; $1->triples=NULL; rasqal_free_formula($1); } if($3) { if(!$$) { $$=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_triple, (raptor_sequence_print_handler*)rasqal_triple_print); if(!$$) { raptor_free_sequence($3); YYERROR_MSG("ConstructTriplesOpt: cannot create sequence"); } } if(raptor_sequence_join($$, $3)) { raptor_free_sequence($3); raptor_free_sequence($$); $$=NULL; YYERROR_MSG("ConstructTriplesOpt: sequence join failed"); } raptor_free_sequence($3); } } | TriplesSameSubject { $$=NULL; if($1) { $$=$1->triples; $1->triples=NULL; rasqal_free_formula($1); } } | /* empty */ { $$=NULL; } ; /* SPARQL Grammar: [32] TriplesSameSubject */ TriplesSameSubject: VarOrTerm PropertyListNotEmpty { int i; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "TriplesSameSubject 1\n subject="); rasqal_formula_print($1, DEBUG_FH); if($2) { fprintf(DEBUG_FH, "\n propertyList="); rasqal_formula_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n"); } else fprintf(DEBUG_FH, "\n and empty propertyList\n"); #endif if($2) { raptor_sequence *seq=$2->triples; rasqal_literal *subject=$1->value; /* non-empty property list, handle it */ for(i=0; i < raptor_sequence_size(seq); i++) { rasqal_triple* t2=(rasqal_triple*)raptor_sequence_get_at(seq, i); if(t2->subject) continue; t2->subject=rasqal_new_literal_from_literal(subject); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after substitution propertyList="); rasqal_formula_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n"); #endif } $$=rasqal_formula_join($1, $2); if(!$$) YYERROR_MSG("TriplesSameSubject 1: formula join failed"); #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after joining formula="); rasqal_formula_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } | TriplesNode PropertyList { int i; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "TriplesSameSubject 2\n subject="); rasqal_formula_print($1, DEBUG_FH); if($2) { fprintf(DEBUG_FH, "\n propertyList="); rasqal_formula_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n"); } else fprintf(DEBUG_FH, "\n and empty propertyList\n"); #endif if($2) { raptor_sequence *seq=$2->triples; rasqal_literal *subject=$1->value; /* non-empty property list, handle it */ for(i=0; i < raptor_sequence_size(seq); i++) { rasqal_triple* t2=(rasqal_triple*)raptor_sequence_get_at(seq, i); if(t2->subject) continue; t2->subject=rasqal_new_literal_from_literal(subject); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after substitution propertyList="); rasqal_formula_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n"); #endif } $$=rasqal_formula_join($1, $2); if(!$$) YYERROR_MSG("TriplesSameSubject 2: formula join failed"); #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after joining formula="); rasqal_formula_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } ; /* SPARQL Grammar: [33] PropertyListNotEmpty */ PropertyListNotEmpty: Verb ObjectList PropertyListTailOpt { int i; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "PropertyList 1\n Verb="); rasqal_formula_print($1, DEBUG_FH); fprintf(DEBUG_FH, "\n ObjectList="); rasqal_formula_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n PropertyListTail="); if($3 != NULL) rasqal_formula_print($3, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, "\n"); #endif if($2 == NULL) { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " empty ObjectList not processed\n"); #endif } else if($1 && $2) { raptor_sequence *seq=$2->triples; rasqal_literal *predicate=$1->value; rasqal_formula *formula; rasqal_triple *t2; formula=rasqal_new_formula(); if(!formula) { rasqal_free_formula($1); rasqal_free_formula($2); if($3) rasqal_free_formula($3); YYERROR_MSG("PropertyList 1: cannot create formula"); } formula->triples=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_triple, (raptor_sequence_print_handler*)rasqal_triple_print); if(!formula->triples) { rasqal_free_formula(formula); rasqal_free_formula($1); rasqal_free_formula($2); if($3) rasqal_free_formula($3); YYERROR_MSG("PropertyList 1: cannot create sequence"); } /* non-empty property list, handle it */ for(i=0; ipredicate) t2->predicate=(rasqal_literal*)rasqal_new_literal_from_literal(predicate); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after substitution ObjectList="); raptor_sequence_print(seq, DEBUG_FH); fprintf(DEBUG_FH, "\n"); #endif while(raptor_sequence_size(seq)) { t2=(rasqal_triple*)raptor_sequence_unshift(seq); if(raptor_sequence_push(formula->triples, t2)) { rasqal_free_formula(formula); rasqal_free_formula($1); rasqal_free_formula($2); if($3) rasqal_free_formula($3); YYERROR_MSG("PropertyList 1: sequence push failed"); } } $3=rasqal_formula_join(formula, $3); if(!$3) { rasqal_free_formula($1); rasqal_free_formula($2); YYERROR_MSG("PropertyList 1: formula join failed"); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after appending ObjectList="); rasqal_formula_print($3, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif rasqal_free_formula($2); } if($1) rasqal_free_formula($1); $$=$3; } ; /* NEW Grammar Term pulled out of [33] PropertyListNotEmpty */ PropertyListTailOpt: ';' PropertyList { $$=$2; } | /* empty */ { $$=NULL; } ; /* SPARQL Grammar: [34] PropertyList */ PropertyList: PropertyListNotEmpty { $$=$1; } | /* empty */ { $$=NULL; } ; /* SPARQL Grammar: [35] ObjectList */ ObjectList: Object ObjectTail { rasqal_formula *formula; rasqal_triple *triple; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "ObjectList 1\n"); fprintf(DEBUG_FH, " Object=\n"); rasqal_formula_print($1, DEBUG_FH); fprintf(DEBUG_FH, "\n"); if($2) { fprintf(DEBUG_FH, " ObjectTail="); rasqal_formula_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n"); } else fprintf(DEBUG_FH, " and empty ObjectTail\n"); #endif formula=rasqal_new_formula(); if(!formula) { rasqal_free_formula($1); if($2) rasqal_free_formula($2); YYERROR_MSG("ObjectList: cannot create formula"); } formula->triples=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_triple, (raptor_sequence_print_handler*)rasqal_triple_print); if(!formula->triples) { rasqal_free_formula(formula); rasqal_free_formula($1); if($2) rasqal_free_formula($2); YYERROR_MSG("ObjectList: cannot create sequence"); } triple=rasqal_new_triple(NULL, NULL, $1->value); $1->value=NULL; /* value now owned by triple */ if(!triple) { rasqal_free_formula(formula); rasqal_free_formula($1); if($2) rasqal_free_formula($2); YYERROR_MSG("ObjectList: cannot create triple"); } if(raptor_sequence_push(formula->triples, triple)) { rasqal_free_formula(formula); rasqal_free_formula($1); if($2) rasqal_free_formula($2); YYERROR_MSG("ObjectList: sequence push failed"); } $$=rasqal_formula_join(formula, $1); if(!$$) { if($2) rasqal_free_formula($2); YYERROR_MSG("ObjectList: formula join $1 failed"); } $$=rasqal_formula_join($$, $2); if(!$$) YYERROR_MSG("ObjectList: formula join $2 failed"); #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " objectList is now "); if($$) raptor_sequence_print($$->triples, DEBUG_FH); else fputs("NULL", DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } ; /* NEW Grammar Term pulled out of [35] ObjectList */ ObjectTail: ',' ObjectList { $$=$2; } | /* empty */ { $$=NULL; } ; /* SPARQL Grammar: [36] Object */ Object: GraphNode { $$=$1; } ; /* SPARQL Grammar: [37] Verb */ Verb: VarOrIRIref { $$=rasqal_new_formula(); if(!$$) { if($1) rasqal_free_literal($1); YYERROR_MSG("Verb 1: cannot create formula"); } $$->value=$1; } | A { raptor_uri *uri; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "verb Verb=rdf:type (a)\n"); #endif uri=raptor_new_uri_for_rdf_concept("type"); if(!uri) YYERROR_MSG("Verb 2: uri for rdf concept type failed"); $$=rasqal_new_formula(); if(!$$) { raptor_free_uri(uri); YYERROR_MSG("Verb 2: cannot create formula"); } $$->value=rasqal_new_uri_literal(((rasqal_query*)rq)->world, uri); if(!$$->value) { rasqal_free_formula($$); $$=NULL; YYERROR_MSG("Verb 2: cannot create uri literal"); } } ; /* SPARQL Grammar: [38] TriplesNode */ TriplesNode: Collection { $$=$1; } | BlankNodePropertyList { $$=$1; } ; /* SPARQL Grammar: [39] BlankNodePropertyList */ BlankNodePropertyList: '[' PropertyListNotEmpty ']' { int i; const unsigned char *id; if($2 == NULL) { $$=rasqal_new_formula(); if(!$$) YYERROR_MSG("BlankNodePropertyList: cannot create formula"); } else { $$=$2; if($$->value) { rasqal_free_literal($$->value); $$->value=NULL; } } id=rasqal_query_generate_bnodeid((rasqal_query*)rq, NULL); if(!id) { rasqal_free_formula($$); $$=NULL; YYERROR_MSG("BlankNodeProperyList: cannot create bnodeid"); } $$->value=rasqal_new_simple_literal(((rasqal_query*)rq)->world, RASQAL_LITERAL_BLANK, id); if(!$$->value) { rasqal_free_formula($$); $$=NULL; YYERROR_MSG("BlankNodePropertyList: cannot create literal"); } if($2 == NULL) { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "TriplesNode\n PropertyList="); rasqal_formula_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n"); #endif } else { raptor_sequence *seq=$2->triples; /* non-empty property list, handle it */ #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "TriplesNode\n PropertyList="); raptor_sequence_print(seq, DEBUG_FH); fprintf(DEBUG_FH, "\n"); #endif for(i=0; isubject) continue; t2->subject=(rasqal_literal*)rasqal_new_literal_from_literal($$->value); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after substitution formula="); rasqal_formula_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } } ; /* SPARQL Grammar: [40] Collection (allowing empty case) */ Collection: '(' GraphNodeListNotEmpty ')' { int i; rasqal_query* rdf_query=(rasqal_query*)rq; rasqal_literal* first_identifier=NULL; rasqal_literal* rest_identifier=NULL; rasqal_literal* object=NULL; rasqal_literal* blank=NULL; #if RASQAL_DEBUG > 1 char const *errmsg; #define YYERR_MSG_GOTO(label,msg) do { errmsg = msg; goto label; } while(0) #else #define YYERR_MSG_GOTO(label,ignore) goto label #endif #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "Collection\n GraphNodeListNotEmpty="); raptor_sequence_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n"); #endif $$=rasqal_new_formula(); if(!$$) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create formula"); $$->triples=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_triple, (raptor_sequence_print_handler*)rasqal_triple_print); if(!$$->triples) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create sequence"); first_identifier=rasqal_new_uri_literal(((rasqal_query*)rq)->world, raptor_uri_copy(rdf_query->world->rdf_first_uri)); if(!first_identifier) YYERR_MSG_GOTO(err_Collection, "Collection: cannot first_identifier"); rest_identifier=rasqal_new_uri_literal(((rasqal_query*)rq)->world, raptor_uri_copy(rdf_query->world->rdf_rest_uri)); if(!rest_identifier) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create rest_identifier"); object=rasqal_new_uri_literal(((rasqal_query*)rq)->world, raptor_uri_copy(rdf_query->world->rdf_nil_uri)); if(!object) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create nil object"); for(i=raptor_sequence_size($2)-1; i>=0; i--) { rasqal_formula* f=(rasqal_formula*)raptor_sequence_get_at($2, i); rasqal_triple *t2; const unsigned char *blank_id=NULL; blank_id=rasqal_query_generate_bnodeid(rdf_query, NULL); if(!blank_id) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create bnodeid"); blank=rasqal_new_simple_literal(((rasqal_query*)rq)->world, RASQAL_LITERAL_BLANK, blank_id); if(!blank) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create bnode"); /* Move existing formula triples */ if(f->triples) if(raptor_sequence_join($$->triples, f->triples)) YYERR_MSG_GOTO(err_Collection, "Collection: sequence join failed"); /* add new triples we needed */ t2=rasqal_new_triple(rasqal_new_literal_from_literal(blank), rasqal_new_literal_from_literal(first_identifier), rasqal_new_literal_from_literal(f->value)); if(!t2) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create triple"); if(raptor_sequence_push($$->triples, t2)) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create triple"); t2=rasqal_new_triple(rasqal_new_literal_from_literal(blank), rasqal_new_literal_from_literal(rest_identifier), rasqal_new_literal_from_literal(object)); if(!t2) YYERR_MSG_GOTO(err_Collection, "Collection: cannot create triple 2"); if(raptor_sequence_push($$->triples, t2)) YYERR_MSG_GOTO(err_Collection, "Collection: sequence push 2 failed"); rasqal_free_literal(object); object=blank; blank=NULL; } $$->value=object; #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " after substitution collection="); rasqal_formula_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif rasqal_free_literal(first_identifier); rasqal_free_literal(rest_identifier); break; /* success */ err_Collection: if(blank) rasqal_free_literal(blank); if(object) rasqal_free_literal(object); if(rest_identifier) rasqal_free_literal(rest_identifier); if(first_identifier) rasqal_free_literal(first_identifier); if($2) raptor_free_sequence($2); if($$) { rasqal_free_formula($$); $$=NULL; } YYERROR_MSG(errmsg); } ; /* NEW Grammar Term pulled out of [40] Collection */ /* Sequence of formula */ GraphNodeListNotEmpty: GraphNodeListNotEmpty GraphNode { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "GraphNodeListNotEmpty 1\n"); if($2) { fprintf(DEBUG_FH, " GraphNode="); rasqal_formula_print($2, DEBUG_FH); fprintf(DEBUG_FH, "\n"); } else fprintf(DEBUG_FH, " and empty GraphNode\n"); if($1) { fprintf(DEBUG_FH, " GraphNodeListNotEmpty="); raptor_sequence_print($1, DEBUG_FH); fprintf(DEBUG_FH, "\n"); } else fprintf(DEBUG_FH, " and empty GraphNodeListNotEmpty\n"); #endif if(!$2) $$=NULL; else { /* FIXME: does not work: * $$ not initialized * $1 not freed * also could need a test case */ if(raptor_sequence_push($$, $2)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("GraphNodeListNotEmpty 1: sequence push failed"); } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " itemList is now "); raptor_sequence_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } } | GraphNode { #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, "GraphNodeListNotEmpty 2\n"); if($1) { fprintf(DEBUG_FH, " GraphNode="); rasqal_formula_print($1, DEBUG_FH); fprintf(DEBUG_FH, "\n"); } else fprintf(DEBUG_FH, " and empty GraphNode\n"); #endif if(!$1) $$=NULL; else { $$=raptor_new_sequence((raptor_sequence_free_handler*)rasqal_free_formula, (raptor_sequence_print_handler*)rasqal_formula_print); if(!$$) { rasqal_free_formula($1); YYERROR_MSG("GraphNodeListNotEmpty 2: cannot create sequence"); } if(raptor_sequence_push($$, $1)) { raptor_free_sequence($$); $$=NULL; YYERROR_MSG("GraphNodeListNotEmpty 2: sequence push failed"); } } #if RASQAL_DEBUG > 1 fprintf(DEBUG_FH, " GraphNodeListNotEmpty is now "); raptor_sequence_print($$, DEBUG_FH); fprintf(DEBUG_FH, "\n\n"); #endif } ; /* SPARQL Grammar: [41] GraphNode */ GraphNode: VarOrTerm { $$=$1; } | TriplesNode { $$=$1; } ; /* SPARQL Grammar Term: [42] VarOrTerm */ VarOrTerm: Var { $$=rasqal_new_formula(); if(!$$) YYERROR_MSG("VarOrTerm 1: cannot create formula"); $$->value=rasqal_new_variable_literal(((rasqal_query*)rq)->world, $1); if(!$$->value) { rasqal_free_formula($$); $$=NULL; YYERROR_MSG("VarOrTerm 1: cannot create literal"); } } | GraphTerm { $$=rasqal_new_formula(); if(!$$) { if($1) rasqal_free_literal($1); YYERROR_MSG("VarOrTerm 2: cannot create formula"); } $$->value=$1; } ; /* SPARQL Grammar: [43] VarOrIRIref */ VarOrIRIref: Var { $$=rasqal_new_variable_literal(((rasqal_query*)rq)->world, $1); if(!$$) YYERROR_MSG("VarOrIRIref: cannot create literal"); } | IRIref { $$=$1; } ; /* SPARQL Grammar: [44] Var */ Var: '?' VarName { $$=$2; } | '$' VarName { $$=$2; } ; /* NEW Grammar Term made from SPARQL Grammar: [44] Var */ VarName: IDENTIFIER { $$=rasqal_new_variable((rasqal_query*)rq, $1, NULL); if(!$$) YYERROR_MSG("VarName: cannot create var"); } ; /* SPARQL Grammar: [45] GraphTerm */ GraphTerm: IRIref { $$=$1; } | STRING_LITERAL { $$=$1; } | NumericLiteral { $$=$1; } | BOOLEAN_LITERAL { $$=$1; } | BlankNode { $$=$1; } | '(' ')' { $$=rasqal_new_uri_literal(((rasqal_query*)rq)->world, raptor_uri_copy(((rasqal_query*)rq)->world->rdf_nil_uri)); if(!$$) YYERROR_MSG("GraphTerm: cannot create literal"); } ; /* SPARQL Grammar: [46] Expression */ Expression: ConditionalOrExpression { $$=$1; } ; /* SPARQL Grammar: [47] ConditionalOrExpression */ ConditionalOrExpression: ConditionalOrExpression SC_OR ConditionalAndExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_OR, $1, $3); if(!$$) YYERROR_MSG("ConditionalOrExpression: cannot create expr"); } | ConditionalAndExpression { $$=$1; } ; /* SPARQL Grammar: [48] ConditionalAndExpression */ ConditionalAndExpression: ConditionalAndExpression SC_AND RelationalExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_AND, $1, $3); if(!$$) YYERROR_MSG("ConditionalAndExpression: cannot create expr"); ; } | RelationalExpression { $$=$1; } ; /* SPARQL Grammar: [49] ValueLogical - merged into RelationalExpression */ /* SPARQL Grammar: [50] RelationalExpression */ RelationalExpression: AdditiveExpression EQ AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_EQ, $1, $3); if(!$$) YYERROR_MSG("RelationalExpression 1: cannot create expr"); } | AdditiveExpression NEQ AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_NEQ, $1, $3); if(!$$) YYERROR_MSG("RelationalExpression 2: cannot create expr"); } | AdditiveExpression LT AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_LT, $1, $3); if(!$$) YYERROR_MSG("RelationalExpression 3: cannot create expr"); } | AdditiveExpression GT AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_GT, $1, $3); if(!$$) YYERROR_MSG("RelationalExpression 4: cannot create expr"); } | AdditiveExpression LE AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_LE, $1, $3); if(!$$) YYERROR_MSG("RelationalExpression 5: cannot create expr"); } | AdditiveExpression GE AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_GE, $1, $3); if(!$$) YYERROR_MSG("RelationalExpression 6: cannot create expr"); } | AdditiveExpression { $$=$1; } ; /* SPARQL Grammar: [51] NumericExpression - merged into AdditiveExpression */ /* SPARQL Grammar: [52] AdditiveExpression */ AdditiveExpression: MultiplicativeExpression '+' AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_PLUS, $1, $3); if(!$$) YYERROR_MSG("AdditiveExpression 1: cannot create expr"); } | MultiplicativeExpression '-' AdditiveExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_MINUS, $1, $3); if(!$$) YYERROR_MSG("AdditiveExpression 2: cannot create expr"); } | MultiplicativeExpression NumericLiteralPositive { rasqal_expression *e=rasqal_new_literal_expression($2); if(!e) { rasqal_free_expression($1); YYERROR_MSG("AdditiveExpression 3: cannot create expr"); } $$=rasqal_new_2op_expression(RASQAL_EXPR_PLUS, $1, e); if(!$$) YYERROR_MSG("AdditiveExpression 4: cannot create expr"); } | MultiplicativeExpression NumericLiteralNegative { rasqal_expression *e=rasqal_new_literal_expression($2); if(!e) { rasqal_free_expression($1); YYERROR_MSG("AdditiveExpression 5: cannot create expr"); } $$=rasqal_new_2op_expression(RASQAL_EXPR_PLUS, $1, e); if(!$$) YYERROR_MSG("AdditiveExpression 6: cannot create expr"); } | MultiplicativeExpression { $$=$1; } ; /* SPARQL Grammar: [53] MultiplicativeExpression */ MultiplicativeExpression: UnaryExpression '*' MultiplicativeExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_STAR, $1, $3); if(!$$) YYERROR_MSG("MultiplicativeExpression 1: cannot create expr"); } | UnaryExpression '/' MultiplicativeExpression { $$=rasqal_new_2op_expression(RASQAL_EXPR_SLASH, $1, $3); if(!$$) YYERROR_MSG("MultiplicativeExpression 2: cannot create expr"); } | UnaryExpression { $$=$1; } ; /* SPARQL Grammar: [54] UnaryExpression */ UnaryExpression: '!' PrimaryExpression { $$=rasqal_new_1op_expression(RASQAL_EXPR_BANG, $2); if(!$$) YYERROR_MSG("UnaryExpression 1: cannot create expr"); } | '+' PrimaryExpression { $$=$2; } | '-' PrimaryExpression { $$=rasqal_new_1op_expression(RASQAL_EXPR_UMINUS, $2); if(!$$) YYERROR_MSG("UnaryExpression 3: cannot create expr"); } | PrimaryExpression { $$=$1; } ; /* SPARQL Grammar: [55] PrimaryExpression * == BrackettedExpression | BuiltInCall | IRIrefOrFunction | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | Var * == BrackettedExpression | BuiltInCall | IRIref ArgList? | RDFLiteral | NumericLiteral | BooleanLiteral | BlankNode | Var * == BrackettedExpression | BuiltInCall | FunctionCall | * approximately GraphTerm | Var * */ PrimaryExpression: BrackettedExpression { $$=$1; } | BuiltInCall { $$=$1; } | FunctionCall { /* Grammar has IRIrefOrFunction here which is "IRIref ArgList?" * and essentially shorthand for FunctionCall | IRIref. The Rasqal * SPARQL lexer distinguishes these for us with IRIrefBrace. * IRIref is covered below by GraphTerm. */ $$=$1; } | GraphTerm { $$=rasqal_new_literal_expression($1); if(!$$) YYERROR_MSG("PrimaryExpression 4: cannot create expr"); } | Var { rasqal_literal *l=rasqal_new_variable_literal(((rasqal_query*)rq)->world, $1); if(!l) YYERROR_MSG("PrimaryExpression 5: cannot create literal"); $$=rasqal_new_literal_expression(l); if(!$$) YYERROR_MSG("PrimaryExpression 5: cannot create expr"); } ; /* SPARQL Grammar: [56] BrackettedExpression */ BrackettedExpression: '(' Expression ')' { $$=$2; } ; /* SPARQL Grammar: [57] BuiltInCall */ BuiltInCall: STR '(' Expression ')' { $$=rasqal_new_1op_expression(RASQAL_EXPR_STR, $3); if(!$$) YYERROR_MSG("BuiltInCall 1: cannot create expr"); } | LANG '(' Expression ')' { $$=rasqal_new_1op_expression(RASQAL_EXPR_LANG, $3); if(!$$) YYERROR_MSG("BuiltInCall 2: cannot create expr"); } | LANGMATCHES '(' Expression ',' Expression ')' { $$=rasqal_new_2op_expression(RASQAL_EXPR_LANGMATCHES, $3, $5); if(!$$) YYERROR_MSG("BuiltInCall 3: cannot create expr"); } | DATATYPE '(' Expression ')' { $$=rasqal_new_1op_expression(RASQAL_EXPR_DATATYPE, $3); if(!$$) YYERROR_MSG("BuiltInCall 4: cannot create expr"); } | BOUND '(' Var ')' { rasqal_literal *l; rasqal_expression *e; l=rasqal_new_variable_literal(((rasqal_query*)rq)->world, $3); if(!l) YYERROR_MSG("BuiltInCall 5: cannot create literal"); e=rasqal_new_literal_expression(l); if(!e) YYERROR_MSG("BuiltInCall 6: cannot create literal expr"); $$=rasqal_new_1op_expression(RASQAL_EXPR_BOUND, e); if(!$$) YYERROR_MSG("BuiltInCall 7: cannot create expr"); } | SAMETERM '(' Expression ',' Expression ')' { $$=rasqal_new_2op_expression(RASQAL_EXPR_SAMETERM, $3, $5); if(!$$) YYERROR_MSG("BuiltInCall 8: cannot create expr"); } | ISURI '(' Expression ')' { $$=rasqal_new_1op_expression(RASQAL_EXPR_ISURI, $3); if(!$$) YYERROR_MSG("BuiltInCall 9: cannot create expr"); } | ISBLANK '(' Expression ')' { $$=rasqal_new_1op_expression(RASQAL_EXPR_ISBLANK, $3); if(!$$) YYERROR_MSG("BuiltInCall 10: cannot create expr"); } | ISLITERAL '(' Expression ')' { $$=rasqal_new_1op_expression(RASQAL_EXPR_ISLITERAL, $3); if(!$$) YYERROR_MSG("BuiltInCall 11: cannot create expr"); } | RegexExpression { $$=$1; } ; /* SPARQL Grammar: [58] RegexExpression */ RegexExpression: REGEX '(' Expression ',' Expression ')' { $$=rasqal_new_3op_expression(RASQAL_EXPR_REGEX, $3, $5, NULL); if(!$$) YYERROR_MSG("RegexExpression 1: cannot create expr"); } | REGEX '(' Expression ',' Expression ',' Expression ')' { $$=rasqal_new_3op_expression(RASQAL_EXPR_REGEX, $3, $5, $7); if(!$$) YYERROR_MSG("RegexExpression 2: cannot create expr"); } ; /* SPARQL Grammar: [59] IRIrefOrFunction - not necessary in this grammar as the IRIref ambiguity is determined in lexer with the help of the IRIrefBrace token below */ /* NEW Grammar Term made from SPARQL Grammar: [64] IRIref + '(' expanded */ IRIrefBrace: URI_LITERAL_BRACE { $$=rasqal_new_uri_literal(((rasqal_query*)rq)->world, $1); if(!$$) YYERROR_MSG("IRIrefBrace 1: cannot create literal"); } | QNAME_LITERAL_BRACE { $$=rasqal_new_simple_literal(((rasqal_query*)rq)->world, RASQAL_LITERAL_QNAME, $1); if(!$$) YYERROR_MSG("IRIrefBrace 2: cannot create literal"); if(rasqal_literal_expand_qname((rasqal_query*)rq, $$)) { sparql_query_error_full((rasqal_query*)rq, "QName %s cannot be expanded", $1); rasqal_free_literal($$); $$=NULL; YYERROR_MSG("IRIrefBrace 2: cannot expand qname"); } } ; /* SPARQL Grammar: [60] RDFLiteral - merged into GraphTerm */ /* SPARQL Grammar: [61] NumericLiteral */ NumericLiteral: NumericLiteralUnsigned { $$=$1; } | NumericLiteralPositive { $$=$1; } | NumericLiteralNegative { $$=$1; } ; /* SPARQL Grammer: [62] NumericLiteralUnsigned */ NumericLiteralUnsigned: INTEGER_LITERAL { $$=$1; } | DECIMAL_LITERAL { $$=$1; } | DOUBLE_LITERAL { $$=$1; } ; /* SPARQL Grammer: [63] NumericLiteralPositive */ NumericLiteralPositive: INTEGER_POSITIVE_LITERAL { $$=$1; } | DECIMAL_POSITIVE_LITERAL { $$=$1; } | DOUBLE_POSITIVE_LITERAL { $$=$1; } ; /* SPARQL Grammar: [64] NumericLiteralNegative */ NumericLiteralNegative: INTEGER_NEGATIVE_LITERAL { $$=$1; } | DECIMAL_NEGATIVE_LITERAL { $$=$1; } | DOUBLE_NEGATIVE_LITERAL { $$=$1; } ; /* SPARQL Grammar: [62] BooleanLiteral - merged into GraphTerm */ /* SPARQL Grammar: [63] String - merged into GraphTerm */ /* SPARQL Grammar: [64] IRIref */ IRIref: URI_LITERAL { $$=rasqal_new_uri_literal(((rasqal_query*)rq)->world, $1); if(!$$) YYERROR_MSG("IRIref 1: cannot create literal"); } | QNAME_LITERAL { $$=rasqal_new_simple_literal(((rasqal_query*)rq)->world, RASQAL_LITERAL_QNAME, $1); if(!$$) YYERROR_MSG("IRIref 2: cannot create literal"); if(rasqal_literal_expand_qname((rasqal_query*)rq, $$)) { sparql_query_error_full((rasqal_query*)rq, "QName %s cannot be expanded", $1); rasqal_free_literal($$); $$=NULL; YYERROR_MSG("IRIrefBrace 2: cannot expand qname"); } } ; /* SPARQL Grammar: [65] QName - made into terminal QNAME_LITERAL */ /* SPARQL Grammar: [66] BlankNode */ BlankNode: BLANK_LITERAL { $$=rasqal_new_simple_literal(((rasqal_query*)rq)->world, RASQAL_LITERAL_BLANK, $1); if(!$$) YYERROR_MSG("BlankNode 1: cannot create literal"); } | '[' ']' { const unsigned char *id=rasqal_query_generate_bnodeid((rasqal_query*)rq, NULL); if(!id) YYERROR_MSG("BlankNode 2: cannot create bnodeid"); $$=rasqal_new_simple_literal(((rasqal_query*)rq)->world, RASQAL_LITERAL_BLANK, id); if(!$$) YYERROR_MSG("BlankNode 2: cannot create literal"); } ; /* SPARQL Grammar: [67] Q_IRI_REF onwards are all lexer items * with similar names or are inlined. */ %% /* Support functions */ /* This is declared in sparql_lexer.h but never used, so we always get * a warning unless this dummy code is here. Used once below in an error case. */ static int yy_init_globals (yyscan_t yyscanner ) { return 0; }; /** * rasqal_sparql_query_engine_init - Initialise the SPARQL query engine * * Return value: non 0 on failure **/ static int rasqal_sparql_query_engine_init(rasqal_query* rdf_query, const char *name) { rasqal_sparql_query_engine* rqe=(rasqal_sparql_query_engine*)rdf_query->context; rdf_query->compare_flags = RASQAL_COMPARE_XQUERY; rqe->extended = (strcmp(name, "laqrs") == 0); return 0; } /** * rasqal_sparql_query_engine_terminate - Free the SPARQL query engine * * Return value: non 0 on failure **/ static void rasqal_sparql_query_engine_terminate(rasqal_query* rdf_query) { rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)rdf_query->context; if(sparql && sparql->scanner_set) { sparql_lexer_lex_destroy(sparql->scanner); sparql->scanner_set=0; } } static int rasqal_sparql_query_engine_prepare(rasqal_query* rdf_query) { /* rasqal_sparql_query_engine* sparql=(rasqal_sparql_query_engine*)rdf_query->context; */ int rc; if(!rdf_query->query_string) return 1; rc=sparql_parse(rdf_query); if(rc) return rc; /* FIXME - should check remaining query parts */ if(rasqal_engine_sequence_has_qname(rdf_query->triples) || rasqal_engine_sequence_has_qname(rdf_query->constructs) || rasqal_engine_query_constraints_has_qname(rdf_query)) { sparql_query_error(rdf_query, "SPARQL query has unexpanded QNames"); return 1; } return rasqal_engine_prepare(rdf_query); } static int sparql_parse(rasqal_query* rq) { rasqal_sparql_query_engine* rqe=(rasqal_sparql_query_engine*)rq->context; raptor_locator *locator=&rq->locator; void *buffer; if(!rq->query_string) return yy_init_globals(NULL); /* 0 but a way to use yy_init_globals */ locator->line=1; locator->column= -1; /* No column info */ locator->byte= -1; /* No bytes info */ #if RASQAL_DEBUG > 2 sparql_parser_debug=1; #endif rqe->lineno=1; if(sparql_lexer_lex_init(&rqe->scanner)) return 1; rqe->scanner_set=1; sparql_lexer_set_extra(((rasqal_query*)rq), rqe->scanner); buffer= sparql_lexer__scan_buffer((char*)rq->query_string, rq->query_string_length, rqe->scanner); rqe->error_count=0; sparql_parser_parse(rq); sparql_lexer_lex_destroy(rqe->scanner); rqe->scanner_set=0; /* Parsing failed */ if(rq->failed) return 1; return 0; } static void sparql_query_error(rasqal_query *rq, const char *msg) { rasqal_sparql_query_engine* rqe=(rasqal_sparql_query_engine*)rq->context; if(rqe->error_count++) return; rq->locator.line=rqe->lineno; #ifdef RASQAL_SPARQL_USE_ERROR_COLUMNS /* rq->locator.column=sparql_lexer_get_column(yyscanner);*/ #endif rq->failed=1; rasqal_log_error_simple(((rasqal_query*)rq)->world, RAPTOR_LOG_LEVEL_ERROR, &rq->locator, "%s", msg); } static void sparql_query_error_full(rasqal_query *rq, const char *message, ...) { va_list arguments; rasqal_sparql_query_engine* rqe=(rasqal_sparql_query_engine*)rq->context; if(rqe->error_count++) return; rq->locator.line=rqe->lineno; #ifdef RASQAL_SPARQL_USE_ERROR_COLUMNS /* rq->locator.column=sparql_lexer_get_column(yyscanner);*/ #endif va_start(arguments, message); rq->failed=1; rasqal_log_error_varargs(((rasqal_query*)rq)->world, RAPTOR_LOG_LEVEL_ERROR, &rq->locator, message, arguments); va_end(arguments); } int sparql_syntax_error(rasqal_query *rq, const char *message, ...) { rasqal_sparql_query_engine *rqe=(rasqal_sparql_query_engine*)rq->context; va_list arguments; if(rqe->error_count++) return 0; rq->locator.line=rqe->lineno; #ifdef RASQAL_SPARQL_USE_ERROR_COLUMNS /* rp->locator.column=sparql_lexer_get_column(yyscanner);*/ #endif va_start(arguments, message); rq->failed=1; rasqal_log_error_varargs(((rasqal_query*)rq)->world, RAPTOR_LOG_LEVEL_ERROR, &rq->locator, message, arguments); va_end(arguments); return 0; } int sparql_syntax_warning(rasqal_query *rq, const char *message, ...) { rasqal_sparql_query_engine *rqe=(rasqal_sparql_query_engine*)rq->context; va_list arguments; rq->locator.line=rqe->lineno; #ifdef RASQAL_SPARQL_USE_ERROR_COLUMNS /* rq->locator.column=sparql_lexer_get_column(yyscanner);*/ #endif va_start(arguments, message); rasqal_log_error_varargs(((rasqal_query*)rq)->world, RAPTOR_LOG_LEVEL_WARNING, &rq->locator, message, arguments); va_end(arguments); return (0); } static int rasqal_sparql_query_engine_iostream_write_escaped_counted_string(rasqal_query* query, raptor_iostream* iostr, const unsigned char* string, size_t len) { const char delim='"'; raptor_iostream_write_byte(iostr, delim); if(raptor_iostream_write_string_ntriples(iostr, string, len, delim)) return 1; raptor_iostream_write_byte(iostr, delim); return 0; } static void rasqal_sparql_query_engine_register_factory(rasqal_query_engine_factory *factory) { factory->context_length = sizeof(rasqal_sparql_query_engine); factory->init = rasqal_sparql_query_engine_init; factory->terminate = rasqal_sparql_query_engine_terminate; factory->prepare = rasqal_sparql_query_engine_prepare; factory->iostream_write_escaped_counted_string = rasqal_sparql_query_engine_iostream_write_escaped_counted_string; } int rasqal_init_query_engine_sparql(rasqal_world* world) { return rasqal_query_engine_register_factory(world, "sparql", "SPARQL W3C DAWG RDF Query Language", NULL, (const unsigned char*)"http://www.w3.org/TR/rdf-sparql-query/", &rasqal_sparql_query_engine_register_factory); } int rasqal_init_query_engine_laqrs(rasqal_world* world) { return rasqal_query_engine_register_factory(world, "laqrs", "LAQRS adds to Querying RDF in SPARQL", NULL, NULL, &rasqal_sparql_query_engine_register_factory); } #ifdef STANDALONE #include #include #ifdef HAVE_GETOPT_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifndef HAVE_GETOPT #include #endif #ifdef NEED_OPTIND_DECLARATION extern int optind; extern char *optarg; #endif #define GETOPT_STRING "di:" #define SPARQL_FILE_BUF_SIZE 2048 int main(int argc, char *argv[]) { const char *program=rasqal_basename(argv[0]); char query_string[SPARQL_FILE_BUF_SIZE]; rasqal_query *query; FILE *fh; int rc; const char *filename=NULL; raptor_uri* base_uri=NULL; unsigned char *uri_string; const char* query_languages[2]={"sparql", "laqrs"}; const char* query_language; int usage=0; int fh_opened_here=0; rasqal_world *world; query_language=query_languages[0]; while(!usage) { int c = getopt (argc, argv, GETOPT_STRING); if (c == -1) break; switch (c) { case 0: case '?': /* getopt() - unknown option */ usage=1; break; case 'd': #if RASQAL_DEBUG > 2 sparql_parser_debug=1; #endif break; case 'i': if(optarg) { if(!strcmp(optarg, "laqrs")) { query_language=query_languages[1]; } else if(!strcmp(optarg, "sparql")) { query_language=query_languages[0]; } else { fprintf(stderr, "-i laqrs or -i sparql only\n"); usage=1; } } break; } } if((argc-optind)>1) { fprintf(stderr, "%s: Too many arguments.\n", program); usage=1; } if(usage) { fprintf(stderr, "SPARQL/LAQRS parser test for Rasqal %s\n", rasqal_version_string); fprintf(stderr, "USAGE: %s [OPTIONS] [QUERY-FILE]\n", program); fprintf(stderr, "OPTIONS:\n"); #if RASQAL_DEBUG > 2 fprintf(stderr, " -d Bison parser debugging\n"); #endif fprintf(stderr, " -i LANGUAGE Set query language\n"); exit(1); } if(optind == argc-1) { filename=argv[optind]; fh = fopen(argv[optind], "r"); if(!fh) { fprintf(stderr, "%s: Cannot open file %s - %s\n", program, filename, strerror(errno)); exit(1); } fh_opened_here=1; } else { filename=""; fh = stdin; } memset(query_string, 0, SPARQL_FILE_BUF_SIZE); rc=fread(query_string, SPARQL_FILE_BUF_SIZE, 1, fh); if(rc < SPARQL_FILE_BUF_SIZE) { if(ferror(fh)) { fprintf(stderr, "%s: file '%s' read failed - %s\n", program, filename, strerror(errno)); fclose(fh); return(1); } } if(fh_opened_here) fclose(fh); world=rasqal_new_world(); query=rasqal_new_query(world, query_language, NULL); uri_string=raptor_uri_filename_to_uri_string(filename); base_uri=raptor_new_uri(uri_string); rc=rasqal_query_prepare(query, (const unsigned char*)query_string, base_uri); rasqal_query_print(query, DEBUG_FH); rasqal_free_query(query); raptor_free_uri(base_uri); raptor_free_memory(uri_string); rasqal_free_world(world); return rc; } #endif