sparql 1.0.5 → 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,12 +20,12 @@ module SPARQL::Grammar
20
20
  FLOOR HOURS IF IRI LANGMATCHES LANG LCASE
21
21
  MD5 MINUTES MONTH NOW RAND ROUND SECONDS
22
22
  SHA1 SHA224 SHA256 SHA384 SHA512
23
- STRDT STRENDS STRLANG STRLEN STRSTARTS SUBSTR STR
24
- TIMEZONE TZ UCASE URI YEAR
23
+ STRAFTER STRBEFORE STRDT STRENDS STRLANG STRLEN STRSTARTS STRUUID STR
24
+ TIMEZONE TZ UCASE URI UUID YEAR
25
25
  isBLANK isIRI isURI isLITERAL isNUMERIC sameTerm
26
26
  }.map {|s| s.downcase.to_sym}.freeze
27
27
 
28
- BUILTIN_RULES = [:regex, :substr, :exists, :not_exists].freeze
28
+ BUILTIN_RULES = [:regex, :substr, :replace, :exists, :not_exists].freeze
29
29
 
30
30
  ##
31
31
  # Any additional options for the parser.
@@ -176,10 +176,10 @@ module SPARQL::Grammar
176
176
  ABS|BNODE|BOUND|CEIL|COALESCE|CONCAT
177
177
  |CONTAINS|DATATYPE|DAY|ENCODE_FOR_URI|EXISTS
178
178
  |FLOOR|HOURS|IF|IRI|LANGMATCHES|LANG|LCASE
179
- |MD5|MINUTES|MONTH|NOW|RAND|ROUND|SECONDS
179
+ |MD5|MINUTES|MONTH|NOW|RAND|REPLACE|ROUND|SECONDS
180
180
  |SHA1|SHA224|SHA256|SHA384|SHA512
181
- |STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|SUBSTR|STR
182
- |TIMEZONE|TZ|UCASE|URI|YEAR
181
+ |STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|STRUUID|SUBSTR|STR
182
+ |TIMEZONE|TZ|UCASE|URI|UUID|YEAR
183
183
  |isBLANK|isIRI|isURI|isLITERAL|isNUMERIC|sameTerm
184
184
  }x
185
185
  add_prod_datum(token.value.downcase.to_sym, token.value.downcase.to_sym)
@@ -190,7 +190,7 @@ module SPARQL::Grammar
190
190
 
191
191
  # Productions
192
192
  # [2] Query ::= Prologue
193
- # ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery ) BindingsClause
193
+ # ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery ) ValuesClause
194
194
  production(:Query) do |input, data, callback|
195
195
  if data[:query]
196
196
  query = data[:query].first
@@ -238,19 +238,36 @@ module SPARQL::Grammar
238
238
  add_prod_datum :query, query
239
239
  end
240
240
 
241
- # [10] ConstructQuery ::= 'CONSTRUCT'
242
- # ( ConstructTemplate DatasetClause* WhereClause SolutionModifier | DatasetClause* 'WHERE' '{' TriplesTemplate? '}' SolutionModifier )
241
+ # [8] SubSelect ::= SelectClause WhereClause SolutionModifier
242
+
243
+ # [9] SelectClause ::= 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
244
+
245
+ # [9.8] _SelectClause_8 ::= ( '(' Expression 'AS' Var ')' )
246
+ production(:_SelectClause_8) do |input, data, callback|
247
+ add_prod_datum :extend, [data[:Expression].unshift(data[:Var].first)]
248
+ add_prod_datum :Var, data[:Var]
249
+ end
250
+
251
+ # [10] ConstructQuery ::= 'CONSTRUCT'
252
+ # ( ConstructTemplate
253
+ # DatasetClause*
254
+ # WhereClause
255
+ # SolutionModifier | DatasetClause*
256
+ # 'WHERE' '{' TriplesTemplate? '}'
257
+ # SolutionModifier
258
+ # )
243
259
  production(:ConstructQuery) do |input, data, callback|
260
+ data[:query] ||= [SPARQL::Algebra::Operator::BGP.new(*data[:pattern])]
244
261
  query = merge_modifiers(data)
245
- template = data[:ConstructTemplate] || []
262
+ template = data[:ConstructTemplate] || data[:pattern] || []
246
263
  add_prod_datum :query, SPARQL::Algebra::Expression[:construct, template, query]
247
264
  end
248
265
 
249
- # [11] DescribeQuery ::= 'DESCRIBE' ( VarOrIRIref+ | '*' )
266
+ # [11] DescribeQuery ::= 'DESCRIBE' ( VarOrIri+ | '*' )
250
267
  # DatasetClause* WhereClause? SolutionModifier
251
268
  production(:DescribeQuery) do |input, data, callback|
252
269
  query = merge_modifiers(data)
253
- to_describe = data[:VarOrIRIref] || []
270
+ to_describe = data[:VarOrIri] || []
254
271
  add_prod_datum :query, SPARQL::Algebra::Expression[:describe, to_describe, query]
255
272
  end
256
273
 
@@ -262,12 +279,12 @@ module SPARQL::Grammar
262
279
 
263
280
  # [14] DefaultGraphClause ::= SourceSelector
264
281
  production(:DefaultGraphClause) do |input, data, callback|
265
- add_prod_datum :dataset, data[:IRIref]
282
+ add_prod_datum :dataset, data[:iri]
266
283
  end
267
284
 
268
285
  # [15] NamedGraphClause ::= 'NAMED' SourceSelector
269
286
  production(:NamedGraphClause) do |input, data, callback|
270
- add_prod_data :dataset, data[:IRIref].unshift(:named)
287
+ add_prod_data :dataset, data[:iri].unshift(:named)
271
288
  end
272
289
 
273
290
  # [18] SolutionModifier ::= GroupClause? HavingClause? OrderClause? LimitOffsetClauses?
@@ -324,7 +341,7 @@ module SPARQL::Grammar
324
341
  add_prod_datum(:offset, data[:literal])
325
342
  end
326
343
 
327
- # [54] [55] GroupGraphPatternSub ::= TriplesBlock?
344
+ # [54] GroupGraphPatternSub ::= TriplesBlock?
328
345
  # ( GraphPatternNotTriples '.'? TriplesBlock? )*
329
346
  production(:GroupGraphPatternSub) do |input, data, callback|
330
347
  query_list = data[:query_list]
@@ -333,6 +350,14 @@ module SPARQL::Grammar
333
350
 
334
351
  if query_list
335
352
  lhs = data[:query].to_a.first
353
+
354
+ # Bind terminates the TriplesBlock?
355
+ if data[:extend]
356
+ lhs ||= SPARQL::Algebra::Operator::BGP.new
357
+ # query should be nil
358
+ lhs = SPARQL::Algebra::Operator::Extend.new(data.delete(:extend), lhs)
359
+ end
360
+
336
361
  while !query_list.empty?
337
362
  rhs = query_list.shift
338
363
  # Make the right-hand-side a Join with only a single operand, if it's not already and Operator
@@ -363,7 +388,15 @@ module SPARQL::Grammar
363
388
  elsif data[:query]
364
389
  res = data[:query].first
365
390
  end
366
-
391
+
392
+ debug("GroupGraphPatternSub(pre-extend)") {"res: #{res.inspect}"}
393
+
394
+ if data[:extend]
395
+ res ||= SPARQL::Algebra::Operator::BGP.new
396
+ # query should be nil
397
+ res = SPARQL::Algebra::Operator::Extend.new(data[:extend], res)
398
+ end
399
+
367
400
  debug("GroupGraphPatternSub(pre-filter)") {"res: #{res.inspect}"}
368
401
 
369
402
  if data[:filter]
@@ -383,41 +416,41 @@ module SPARQL::Grammar
383
416
  rhs = SPARQL::Algebra::Expression.for(:join, :placeholder, rhs) if rhs.is_a?(RDF::Query)
384
417
  add_prod_data(:query_list, rhs)
385
418
  end
386
- add_prod_datum(:query_list, lhs) if lhs
419
+ add_prod_datum(:query_list, lhs)
420
+ add_prod_datum(:extend, data[:extend])
387
421
  add_prod_datum(:filter, data[:filter])
388
422
  end
389
423
 
390
424
  # _GroupGraphPatternSub_3
391
425
 
392
- # [56] TriplesBlock ::= TriplesSameSubjectPath
426
+ # [55] TriplesBlock ::= TriplesSameSubjectPath
393
427
  # ( '.' TriplesBlock? )?
394
428
  production(:TriplesBlock) do |input, data, callback|
395
429
  query = SPARQL::Algebra::Operator::BGP.new
396
- data[:pattern].each {|p| query << p}
430
+ data[:pattern].to_a.each {|p| query << p}
397
431
 
398
432
  # Append triples from ('.' TriplesBlock? )?
399
433
  data[:query].to_a.each {|q| query += q}
400
434
  add_prod_datum(:query, query)
401
435
  end
402
436
 
403
- # [57] GraphPatternNotTriples ::= GroupOrUnionGraphPattern
437
+ # [56] GraphPatternNotTriples ::= GroupOrUnionGraphPattern
404
438
  # | OptionalGraphPattern
405
439
  # | MinusGraphPattern
406
440
  # | GraphGraphPattern
407
441
  # | ServiceGraphPattern
408
442
  # | Filter | Bind
409
443
  production(:GraphPatternNotTriples) do |input, data, callback|
444
+ add_prod_datum(:extend, data[:extend])
410
445
  add_prod_datum(:filter, data[:filter])
411
446
 
412
447
  if data[:query]
413
448
  res = data[:query].to_a.first
414
- # FIXME?
415
- #res = SPARQL::Algebra::Expression.for(:join, :placeholder, res) unless res.is_a?(SPARQL::Algebra::Operator)
416
449
  add_prod_data(:query, res)
417
450
  end
418
451
  end
419
452
 
420
- # [58] OptionalGraphPattern ::= 'OPTIONAL' GroupGraphPattern
453
+ # [57] OptionalGraphPattern ::= 'OPTIONAL' GroupGraphPattern
421
454
  production(:OptionalGraphPattern) do |input, data, callback|
422
455
  if data[:query]
423
456
  expr = nil
@@ -432,9 +465,9 @@ module SPARQL::Grammar
432
465
  end
433
466
  end
434
467
 
435
- # [59] GraphGraphPattern ::= 'GRAPH' VarOrIRIref GroupGraphPattern
468
+ # [58] GraphGraphPattern ::= 'GRAPH' VarOrIri GroupGraphPattern
436
469
  production(:GraphGraphPattern) do |input, data, callback|
437
- name = (data[:VarOrIRIref]).last
470
+ name = (data[:VarOrIri]).last
438
471
  bgp = data[:query] ? data[:query].first : SPARQL::Algebra::Operator::BGP.new
439
472
  if name
440
473
  add_prod_data(:query, SPARQL::Algebra::Expression.for(:graph, name, bgp))
@@ -443,7 +476,12 @@ module SPARQL::Grammar
443
476
  end
444
477
  end
445
478
 
446
- # [63] GroupOrUnionGraphPattern ::= GroupGraphPattern
479
+ # [60] Bind ::= 'BIND' '(' Expression 'AS' Var ')'
480
+ production(:Bind) do |input, data, callback|
481
+ add_prod_datum :extend, [data[:Expression].unshift(data[:Var].first)]
482
+ end
483
+
484
+ # [67] GroupOrUnionGraphPattern ::= GroupGraphPattern
447
485
  # ( 'UNION' GroupGraphPattern )*
448
486
  production(:GroupOrUnionGraphPattern) do |input, data, callback|
449
487
  res = data[:query].to_a.first
@@ -461,17 +499,15 @@ module SPARQL::Grammar
461
499
 
462
500
  # ( 'UNION' GroupGraphPattern )*
463
501
  production(:_GroupOrUnionGraphPattern_1) do |input, data, callback|
464
- # Add [:union rhs] to stack based on ":union"
465
- add_prod_data(:union, data[:query].to_a.first)
466
- add_prod_data(:union, data[:union].first) if data[:union]
502
+ input[:union] = data[:union].to_a.unshift(data[:query].first)
467
503
  end
468
504
 
469
- # [64] Filter ::= 'FILTER' Constraint
505
+ # [68] Filter ::= 'FILTER' Constraint
470
506
  production(:Filter) do |input, data, callback|
471
507
  add_prod_datum(:filter, data[:Constraint])
472
508
  end
473
509
 
474
- # [65] Constraint ::= BrackettedExpression | BuiltInCall
510
+ # [69] Constraint ::= BrackettedExpression | BuiltInCall
475
511
  # | FunctionCall
476
512
  production(:Constraint) do |input, data, callback|
477
513
  if data[:Expression]
@@ -484,24 +520,24 @@ module SPARQL::Grammar
484
520
  end
485
521
  end
486
522
 
487
- # [66] FunctionCall ::= IRIref ArgList
523
+ # [70] FunctionCall ::= iri ArgList
488
524
  production(:FunctionCall) do |input, data, callback|
489
- add_prod_data(:Function, data[:IRIref] + data[:ArgList])
525
+ add_prod_data(:Function, data[:iri] + data[:ArgList])
490
526
  end
491
527
 
492
- # [67] ArgList ::= NIL
528
+ # [71] ArgList ::= NIL
493
529
  # | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
494
530
  production(:ArgList) do |input, data, callback|
495
531
  data.values.each {|v| add_prod_datum(:ArgList, v)}
496
532
  end
497
533
 
498
- # [68] ExpressionList ::= NIL
534
+ # [72] ExpressionList ::= NIL
499
535
  # | '(' Expression ( ',' Expression )* ')'
500
536
  production(:ExpressionList) do |input, data, callback|
501
537
  data.values.each {|v| add_prod_datum(:ExpressionList, v)}
502
538
  end
503
539
 
504
- # [69] ConstructTemplate ::= '{' ConstructTriples? '}'
540
+ # [73] ConstructTemplate ::= '{' ConstructTriples? '}'
505
541
  start_production(:ConstructTemplate) do |input, data, callback|
506
542
  # Generate BNodes instead of non-distinguished variables
507
543
  self.nd_var_gen = false
@@ -513,13 +549,13 @@ module SPARQL::Grammar
513
549
  add_prod_datum(:ConstructTemplate, data[:ConstructTemplate])
514
550
  end
515
551
 
516
- # [71] TriplesSameSubject ::= VarOrTerm PropertyListNotEmpty
552
+ # [75] TriplesSameSubject ::= VarOrTerm PropertyListNotEmpty
517
553
  # | TriplesNode PropertyList
518
554
  production(:TriplesSameSubject) do |input, data, callback|
519
555
  add_prod_datum(:pattern, data[:pattern])
520
556
  end
521
557
 
522
- # [72] PropertyListNotEmpty ::= Verb ObjectList
558
+ # [77] PropertyListNotEmpty ::= Verb ObjectList
523
559
  # ( ';' ( Verb ObjectList )? )*
524
560
  start_production(:PropertyListNotEmpty) do |input, data, callback|
525
561
  subject = input[:VarOrTerm] || input[:TriplesNode] || input[:GraphNode]
@@ -530,7 +566,7 @@ module SPARQL::Grammar
530
566
  add_prod_datum(:pattern, data[:pattern])
531
567
  end
532
568
 
533
- # [74] ObjectList ::= Object ( ',' Object )*
569
+ # [79] ObjectList ::= Object ( ',' Object )*
534
570
  start_production(:ObjectList) do |input, data, callback|
535
571
  # Called after Verb. The prod_data stack should have Subject and Verb elements
536
572
  data[:Subject] = prod_data[:Subject]
@@ -543,7 +579,7 @@ module SPARQL::Grammar
543
579
  add_prod_datum(:pattern, data[:pattern])
544
580
  end
545
581
 
546
- # [75] Object ::= GraphNode
582
+ # [80] Object ::= GraphNode
547
583
  production(:Object) do |input, data, callback|
548
584
  object = data[:VarOrTerm] || data[:TriplesNode] || data[:GraphNode]
549
585
  if object
@@ -552,12 +588,12 @@ module SPARQL::Grammar
552
588
  end
553
589
  end
554
590
 
555
- # [76] Verb ::= VarOrIRIref | 'a'
591
+ # [78] Verb ::= VarOrIri | 'a'
556
592
  production(:Verb) do |input, data, callback|
557
593
  data.values.each {|v| add_prod_datum(:Verb, v)}
558
594
  end
559
595
 
560
- # [78] PropertyListNotEmptyPath ::= ( VerbPath | VerbSimple ) ObjectList ( ';' ( ( VerbPath | VerbSimple ) ObjectList )? )*
596
+ # [83] PropertyListNotEmptyPath ::= ( VerbPath | VerbSimple ) ObjectList ( ';' ( ( VerbPath | VerbSimple ) ObjectList )? )*
561
597
  start_production(:PropertyListNotEmptyPath) do |input, data, callback|
562
598
  subject = input[:VarOrTerm]
563
599
  error(nil, "Expected VarOrTerm", :production => ::PropertyListNotEmptyPath) if validate? && !subject
@@ -567,17 +603,17 @@ module SPARQL::Grammar
567
603
  add_prod_datum(:pattern, data[:pattern])
568
604
  end
569
605
 
570
- # [80] VerbPath ::= Path
606
+ # [84] VerbPath ::= Path
571
607
  production(:VerbPath) do |input, data, callback|
572
608
  data.values.each {|v| add_prod_datum(:Verb, v)}
573
609
  end
574
610
 
575
- # [81] VerbSimple ::= Var
611
+ # [85] VerbSimple ::= Var
576
612
  production(:VerbSimple) do |input, data, callback|
577
613
  data.values.each {|v| add_prod_datum(:Verb, v)}
578
614
  end
579
615
 
580
- # [92] TriplesNode ::= Collection | BlankNodePropertyList
616
+ # [98] TriplesNode ::= Collection | BlankNodePropertyList
581
617
  start_production(:TriplesNode) do |input, data, callback|
582
618
  # Called after Verb. The prod_data stack should have Subject and Verb elements
583
619
  data[:TriplesNode] = bnode
@@ -587,7 +623,7 @@ module SPARQL::Grammar
587
623
  add_prod_datum(:TriplesNode, data[:TriplesNode])
588
624
  end
589
625
 
590
- # [94] Collection ::= '(' GraphNode+ ')'
626
+ # [102] Collection ::= '(' GraphNode+ ')'
591
627
  start_production(:Collection) do |input, data, callback|
592
628
  # Tells the TriplesNode production to collect and not generate statements
593
629
  data[:Collection] = prod_data[:TriplesNode]
@@ -596,39 +632,39 @@ module SPARQL::Grammar
596
632
  expand_collection(data)
597
633
  end
598
634
 
599
- # [95] GraphNode ::= VarOrTerm | TriplesNode
635
+ # [104] GraphNode ::= VarOrTerm | TriplesNode
600
636
  production(:GraphNode) do |input, data, callback|
601
637
  term = data[:VarOrTerm] || data[:TriplesNode]
602
638
  add_prod_datum(:pattern, data[:pattern])
603
639
  add_prod_datum(:GraphNode, term)
604
640
  end
605
641
 
606
- # [96] VarOrTerm ::= Var | GraphTerm
642
+ # [106] VarOrTerm ::= Var | GraphTerm
607
643
  production(:VarOrTerm) do |input, data, callback|
608
644
  data.values.each {|v| add_prod_datum(:VarOrTerm, v)}
609
645
  end
610
646
 
611
- # [97] VarOrIRIref ::= Var | IRIref
612
- production(:VarOrIRIref) do |input, data, callback|
613
- data.values.each {|v| add_prod_datum(:VarOrIRIref, v)}
647
+ # [107] VarOrIri ::= Var | iri
648
+ production(:VarOrIri) do |input, data, callback|
649
+ data.values.each {|v| add_prod_datum(:VarOrIri, v)}
614
650
  end
615
651
 
616
- # [99] GraphTerm ::= IRIref | RDFLiteral | NumericLiteral
652
+ # [109] GraphTerm ::= iri | RDFLiteral | NumericLiteral
617
653
  # | BooleanLiteral | BlankNode | NIL
618
654
  production(:GraphTerm) do |input, data, callback|
619
655
  add_prod_datum(:GraphTerm,
620
- data[:IRIref] ||
656
+ data[:iri] ||
621
657
  data[:literal] ||
622
658
  data[:BlankNode] ||
623
659
  data[:NIL])
624
660
  end
625
661
 
626
- # [100] Expression ::= ConditionalOrExpression
662
+ # [110] Expression ::= ConditionalOrExpression
627
663
  production(:Expression) do |input, data, callback|
628
664
  add_prod_datum(:Expression, data[:Expression])
629
665
  end
630
666
 
631
- # [101] ConditionalOrExpression ::= ConditionalAndExpression
667
+ # [111] ConditionalOrExpression ::= ConditionalAndExpression
632
668
  # ( '||' ConditionalAndExpression )*
633
669
  production(:ConditionalOrExpression) do |input, data, callback|
634
670
  add_operator_expressions(:_OR, data)
@@ -639,7 +675,7 @@ module SPARQL::Grammar
639
675
  accumulate_operator_expressions(:ConditionalOrExpression, :_OR, data)
640
676
  end
641
677
 
642
- # [102] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )*
678
+ # [112] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )*
643
679
  production(:ConditionalAndExpression) do |input, data, callback|
644
680
  add_operator_expressions(:_AND, data)
645
681
  end
@@ -649,7 +685,7 @@ module SPARQL::Grammar
649
685
  accumulate_operator_expressions(:ConditionalAndExpression, :_AND, data)
650
686
  end
651
687
 
652
- # [104] RelationalExpression ::= NumericExpression
688
+ # [114] RelationalExpression ::= NumericExpression
653
689
  # ( '=' NumericExpression
654
690
  # | '!=' NumericExpression
655
691
  # | '<' NumericExpression
@@ -662,6 +698,12 @@ module SPARQL::Grammar
662
698
  production(:RelationalExpression) do |input, data, callback|
663
699
  if data[:_Compare_Numeric]
664
700
  add_prod_datum(:Expression, SPARQL::Algebra::Expression.for(data[:_Compare_Numeric].insert(1, *data[:Expression])))
701
+ elsif data[:in]
702
+ expr = (data[:Expression] + data[:in]).reject {|v| v == RDF.nil}
703
+ add_prod_datum(:Expression, SPARQL::Algebra::Expression.for(expr.unshift(:in)))
704
+ elsif data[:notin]
705
+ expr = (data[:Expression] + data[:notin]).reject {|v| v == RDF.nil}
706
+ add_prod_datum(:Expression, SPARQL::Algebra::Expression.for(expr.unshift(:notin)))
665
707
  else
666
708
  # NumericExpression with no comparitor
667
709
  add_prod_datum(:Expression, data[:Expression])
@@ -672,16 +714,30 @@ module SPARQL::Grammar
672
714
  production(:_RelationalExpression_1) do |input, data, callback|
673
715
  if data[:RelationalExpression]
674
716
  add_prod_datum(:_Compare_Numeric, data[:RelationalExpression] + data[:Expression])
717
+ elsif data[:in]
718
+ add_prod_datum(:in, data[:in])
719
+ elsif data[:notin]
720
+ add_prod_datum(:notin, data[:notin])
675
721
  end
676
722
  end
677
723
 
678
- # [106] AdditiveExpression ::= MultiplicativeExpression
679
- # ( '+' MultiplicativeExpression
680
- # | '-' MultiplicativeExpression
681
- # | ( NumericLiteralPositive | NumericLiteralNegative )
682
- # ( ( '*' UnaryExpression )
683
- # | ( '/' UnaryExpression ) )?
684
- # )*
724
+ # 'IN' ExpressionList
725
+ production(:_RelationalExpression_9) do |input, data, callback|
726
+ add_prod_datum(:in, data[:ExpressionList])
727
+ end
728
+
729
+ # 'NOT' 'IN' ExpressionList
730
+ production(:_RelationalExpression_10) do |input, data, callback|
731
+ add_prod_datum(:notin, data[:ExpressionList])
732
+ end
733
+
734
+ # [116] AdditiveExpression ::= MultiplicativeExpression
735
+ # ( '+' MultiplicativeExpression
736
+ # | '-' MultiplicativeExpression
737
+ # | ( NumericLiteralPositive | NumericLiteralNegative )
738
+ # ( ( '*' UnaryExpression )
739
+ # | ( '/' UnaryExpression ) )?
740
+ # )*
685
741
  production(:AdditiveExpression) do |input, data, callback|
686
742
  add_operator_expressions(:_Add_Sub, data)
687
743
  end
@@ -698,13 +754,14 @@ module SPARQL::Grammar
698
754
 
699
755
  # | ( NumericLiteralPositive | NumericLiteralNegative )
700
756
  production(:_AdditiveExpression_7) do |input, data, callback|
701
- val = data[:literal].first.to_s
757
+ lit = data[:literal].first
758
+ val = lit.to_s
702
759
  op, val = val[0,1], val[1..-1]
703
760
  add_prod_datum(:AdditiveExpression, op)
704
- add_prod_datum(:Expression, data[:literal])
761
+ add_prod_datum(:Expression, [lit.class.new(val)])
705
762
  end
706
763
 
707
- # [107] MultiplicativeExpression ::= UnaryExpression
764
+ # [117] MultiplicativeExpression ::= UnaryExpression
708
765
  # ( '*' UnaryExpression
709
766
  # | '/' UnaryExpression )*
710
767
  production(:MultiplicativeExpression) do |input, data, callback|
@@ -717,7 +774,7 @@ module SPARQL::Grammar
717
774
  accumulate_operator_expressions(:MultiplicativeExpression, :_Mul_Div, data)
718
775
  end
719
776
 
720
- # [108] UnaryExpression ::= '!' PrimaryExpression
777
+ # [118] UnaryExpression ::= '!' PrimaryExpression
721
778
  # | '+' PrimaryExpression
722
779
  # | '-' PrimaryExpression
723
780
  # | PrimaryExpression
@@ -737,8 +794,8 @@ module SPARQL::Grammar
737
794
  end
738
795
  end
739
796
 
740
- # [109] PrimaryExpression ::= BrackettedExpression | BuiltInCall
741
- # | IRIrefOrFunction | RDFLiteral
797
+ # [119] PrimaryExpression ::= BrackettedExpression | BuiltInCall
798
+ # | iriOrFunction | RDFLiteral
742
799
  # | NumericLiteral | BooleanLiteral
743
800
  # | Var | Aggregate
744
801
  production(:PrimaryExpression) do |input, data, callback|
@@ -746,8 +803,8 @@ module SPARQL::Grammar
746
803
  add_prod_datum(:Expression, data[:Expression])
747
804
  elsif data[:BuiltInCall]
748
805
  add_prod_datum(:Expression, data[:BuiltInCall])
749
- elsif data[:IRIref]
750
- add_prod_datum(:Expression, data[:IRIref])
806
+ elsif data[:iri]
807
+ add_prod_datum(:Expression, data[:iri])
751
808
  elsif data[:Function]
752
809
  add_prod_datum(:Expression, data[:Function]) # Maintain array representation
753
810
  elsif data[:literal]
@@ -760,7 +817,7 @@ module SPARQL::Grammar
760
817
  add_prod_datum(:UnaryExpression, data[:UnaryExpression])
761
818
  end
762
819
 
763
- # [111] BuiltInCall ::= 'STR' '(' Expression ')'
820
+ # [122] BuiltInCall ::= 'STR' '(' Expression ')'
764
821
  # | 'LANG' '(' Expression ')'
765
822
  # | 'LANGMATCHES' '(' Expression ',' Expression ')'
766
823
  # | 'DATATYPE' '(' Expression ')'
@@ -812,7 +869,10 @@ module SPARQL::Grammar
812
869
  # | NotExistsFunc
813
870
  production(:BuiltInCall) do |input, data, callback|
814
871
  if builtin = data.keys.detect {|k| BUILTINS.include?(k)}
815
- add_prod_datum(:BuiltInCall, SPARQL::Algebra::Expression.for(data[:Expression].unshift(builtin)))
872
+ add_prod_datum(:BuiltInCall,
873
+ SPARQL::Algebra::Expression.for(
874
+ (data[:ExpressionList] || data[:Expression] || []).
875
+ unshift(builtin)))
816
876
  elsif builtin_rule = data.keys.detect {|k| BUILTIN_RULES.include?(k)}
817
877
  add_prod_datum(:BuiltInCall, SPARQL::Algebra::Expression.for(data[builtin_rule].unshift(builtin_rule)))
818
878
  elsif data[:bound]
@@ -822,51 +882,59 @@ module SPARQL::Grammar
822
882
  end
823
883
  end
824
884
 
825
- # [112] RegexExpression ::= 'REGEX' '(' Expression ',' Expression
885
+ # [122] RegexExpression ::= 'REGEX' '(' Expression ',' Expression
826
886
  # ( ',' Expression )? ')'
827
887
  production(:RegexExpression) do |input, data, callback|
828
888
  add_prod_datum(:regex, data[:Expression])
829
889
  end
830
890
 
831
- # [113] SubstringExpression ::= 'SUBSTR'
891
+ # [123] SubstringExpression ::= 'SUBSTR'
832
892
  # '(' Expression ',' Expression
833
893
  # ( ',' Expression )? ')'
834
894
  production(:SubstringExpression) do |input, data, callback|
835
895
  add_prod_datum(:substr, data[:Expression])
836
896
  end
837
897
 
838
- # [114] ExistsFunc ::= 'EXISTS' GroupGraphPattern
898
+ # [124] StrReplaceExpression ::= 'REPLACE'
899
+ # '(' Expression ','
900
+ # Expression ',' Expression
901
+ # ( ',' Expression )? ')'
902
+ production(:StrReplaceExpression) do |input, data, callback|
903
+ add_prod_datum(:replace, data[:Expression])
904
+ end
905
+
906
+ # [125] ExistsFunc ::= 'EXISTS' GroupGraphPattern
839
907
  production(:ExistsFunc) do |input, data, callback|
840
908
  add_prod_datum(:exists, data[:query])
841
909
  end
842
910
 
843
- # [115] NotExistsFunc ::= 'NOT' 'EXISTS' GroupGraphPattern
911
+ # [126] NotExistsFunc ::= 'NOT' 'EXISTS' GroupGraphPattern
844
912
  production(:NotExistsFunc) do |input, data, callback|
845
913
  add_prod_datum(:not_exists, data[:query])
846
914
  end
847
915
 
848
- # [117] IRIrefOrFunction ::= IRIref ArgList?
849
- production(:IRIrefOrFunction) do |input, data, callback|
916
+ # [128] iriOrFunction ::= iri ArgList?
917
+ production(:iriOrFunction) do |input, data, callback|
850
918
  if data.has_key?(:ArgList)
851
919
  # Function is (func arg1 arg2 ...)
852
- add_prod_data(:Function, data[:IRIref] + data[:ArgList])
920
+ add_prod_data(:Function, data[:iri] + data[:ArgList])
853
921
  else
854
- add_prod_datum(:IRIref, data[:IRIref])
922
+ add_prod_datum(:iri, data[:iri])
855
923
  end
856
924
  end
857
925
 
858
- # [118] RDFLiteral ::= String ( LANGTAG | ( '^^' IRIref ) )?
926
+ # [129] RDFLiteral ::= String ( LANGTAG | ( '^^' iri ) )?
859
927
  production(:RDFLiteral) do |input, data, callback|
860
928
  if data[:string]
861
929
  lit = data.dup
862
930
  str = lit.delete(:string).last
863
- lit[:datatype] = lit.delete(:IRIref).last if lit[:IRIref]
931
+ lit[:datatype] = lit.delete(:iri).last if lit[:iri]
864
932
  lit[:language] = lit.delete(:language).last.downcase if lit[:language]
865
933
  add_prod_datum(:literal, RDF::Literal.new(str, lit)) if str
866
934
  end
867
935
  end
868
936
 
869
- # [121] NumericLiteralPositive ::= INTEGER_POSITIVE
937
+ # [132] NumericLiteralPositive ::= INTEGER_POSITIVE
870
938
  # | DECIMAL_POSITIVE
871
939
  # | DOUBLE_POSITIVE
872
940
  production(:NumericLiteralPositive) do |input, data, callback|
@@ -877,7 +945,7 @@ module SPARQL::Grammar
877
945
  add_prod_datum(:UnaryExpression, data[:UnaryExpression])
878
946
  end
879
947
 
880
- # [122] NumericLiteralNegative ::= INTEGER_NEGATIVE
948
+ # [133] NumericLiteralNegative ::= INTEGER_NEGATIVE
881
949
  # | DECIMAL_NEGATIVE
882
950
  # | DOUBLE_NEGATIVE
883
951
  production(:NumericLiteralNegative) do |input, data, callback|
@@ -888,12 +956,7 @@ module SPARQL::Grammar
888
956
  add_prod_datum(:UnaryExpression, data[:UnaryExpression])
889
957
  end
890
958
 
891
- # [125] IRIref ::= IRI_REF | PrefixedName
892
- production(:IRIref) do |input, data, callback|
893
- add_prod_datum(:IRIref, data[:iri])
894
- end
895
-
896
- # [126] PrefixedName ::= PNAME_LN | PNAME_NS
959
+ # [137] PrefixedName ::= PNAME_LN | PNAME_NS
897
960
  production(:PrefixedName) do |input, data, callback|
898
961
  add_prod_datum(:iri, data[:PrefixedName])
899
962
  end
@@ -922,8 +985,12 @@ module SPARQL::Grammar
922
985
  # @return [SPARQL::Grammar::Parser]
923
986
  def initialize(input = nil, options = {})
924
987
  @input = input.to_s.dup
925
- @input.force_encoding(Encoding::UTF_8) if @input.respond_to?(:force_encoding)
988
+ @input.force_encoding(Encoding::UTF_8)
926
989
  @options = {:anon_base => "b0", :validate => false}.merge(options)
990
+ @options[:debug] ||= case
991
+ when @options[:progress] then 2
992
+ when @options[:validate] then 1
993
+ end
927
994
 
928
995
  debug("base IRI") {base_uri.inspect}
929
996
  debug("validate") {validate?.inspect}
@@ -1197,7 +1264,7 @@ module SPARQL::Grammar
1197
1264
  add_prod_datum(:pattern, data[:pattern])
1198
1265
 
1199
1266
  # Create list items for each element in data[:GraphNode]
1200
- first = col = data[:Collection]
1267
+ first = data[:Collection]
1201
1268
  list = data[:GraphNode].to_a.flatten.compact
1202
1269
  last = list.pop
1203
1270
 
@@ -1248,6 +1315,8 @@ module SPARQL::Grammar
1248
1315
  query = data[:query] ? data[:query].first : SPARQL::Algebra::Operator::BGP.new
1249
1316
 
1250
1317
  # Add datasets and modifiers in order
1318
+ query = SPARQL::Algebra::Expression[:extend, data[:extend], query] if data[:extend]
1319
+
1251
1320
  query = SPARQL::Algebra::Expression[:order, data[:order].first, query] if data[:order]
1252
1321
 
1253
1322
  query = SPARQL::Algebra::Expression[:project, data[:Var], query] if data[:Var]
@@ -1264,11 +1333,12 @@ module SPARQL::Grammar
1264
1333
  # Add joined expressions in for prod1 (op prod2)* to form (op (op 1 2) 3)
1265
1334
  def add_operator_expressions(production, data)
1266
1335
  # Iterate through expression to create binary operations
1267
- res = data[:Expression]
1336
+ lhs = data[:Expression]
1268
1337
  while data[production] && !data[production].empty?
1269
- res = SPARQL::Algebra::Expression[data[production].shift + res + data[production].shift]
1338
+ op, rhs = data[production].shift, data[production].shift
1339
+ lhs = SPARQL::Algebra::Expression[op + lhs + rhs]
1270
1340
  end
1271
- add_prod_datum(:Expression, res)
1341
+ add_prod_datum(:Expression, lhs)
1272
1342
  end
1273
1343
 
1274
1344
  # Accumulate joined expressions in for prod1 (op prod2)* to form (op (op 1 2) 3)