sparql 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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)