sparql 1.1.5 → 1.1.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -32
  3. data/VERSION +1 -1
  4. data/bin/sparql +8 -6
  5. data/lib/sparql.rb +4 -2
  6. data/lib/sparql/algebra.rb +74 -4
  7. data/lib/sparql/algebra/aggregate.rb +1 -1
  8. data/lib/sparql/algebra/evaluatable.rb +1 -1
  9. data/lib/sparql/algebra/expression.rb +24 -16
  10. data/lib/sparql/algebra/extensions.rb +37 -9
  11. data/lib/sparql/algebra/operator.rb +75 -12
  12. data/lib/sparql/algebra/operator/add.rb +41 -19
  13. data/lib/sparql/algebra/operator/and.rb +2 -2
  14. data/lib/sparql/algebra/operator/asc.rb +1 -1
  15. data/lib/sparql/algebra/operator/ask.rb +1 -1
  16. data/lib/sparql/algebra/operator/base.rb +1 -1
  17. data/lib/sparql/algebra/operator/bgp.rb +1 -1
  18. data/lib/sparql/algebra/operator/bnode.rb +1 -1
  19. data/lib/sparql/algebra/operator/clear.rb +63 -0
  20. data/lib/sparql/algebra/operator/coalesce.rb +1 -1
  21. data/lib/sparql/algebra/operator/concat.rb +3 -3
  22. data/lib/sparql/algebra/operator/construct.rb +2 -2
  23. data/lib/sparql/algebra/operator/copy.rb +64 -0
  24. data/lib/sparql/algebra/operator/create.rb +49 -0
  25. data/lib/sparql/algebra/operator/dataset.rb +6 -31
  26. data/lib/sparql/algebra/operator/delete.rb +55 -0
  27. data/lib/sparql/algebra/operator/delete_data.rb +41 -0
  28. data/lib/sparql/algebra/operator/delete_where.rb +57 -0
  29. data/lib/sparql/algebra/operator/distinct.rb +1 -1
  30. data/lib/sparql/algebra/operator/drop.rb +66 -0
  31. data/lib/sparql/algebra/operator/exists.rb +2 -2
  32. data/lib/sparql/algebra/operator/exprlist.rb +1 -1
  33. data/lib/sparql/algebra/operator/extend.rb +3 -3
  34. data/lib/sparql/algebra/operator/filter.rb +2 -2
  35. data/lib/sparql/algebra/operator/graph.rb +39 -5
  36. data/lib/sparql/algebra/operator/group.rb +5 -5
  37. data/lib/sparql/algebra/operator/group_concat.rb +1 -1
  38. data/lib/sparql/algebra/operator/if.rb +3 -3
  39. data/lib/sparql/algebra/operator/in.rb +1 -1
  40. data/lib/sparql/algebra/operator/insert.rb +54 -0
  41. data/lib/sparql/algebra/operator/insert_data.rb +41 -0
  42. data/lib/sparql/algebra/operator/join.rb +2 -2
  43. data/lib/sparql/algebra/operator/lcase.rb +1 -1
  44. data/lib/sparql/algebra/operator/left_join.rb +2 -2
  45. data/lib/sparql/algebra/operator/load.rb +48 -0
  46. data/lib/sparql/algebra/operator/minus.rb +2 -2
  47. data/lib/sparql/algebra/operator/modify.rb +53 -0
  48. data/lib/sparql/algebra/operator/move.rb +67 -0
  49. data/lib/sparql/algebra/operator/notexists.rb +1 -1
  50. data/lib/sparql/algebra/operator/notin.rb +2 -2
  51. data/lib/sparql/algebra/operator/or.rb +2 -2
  52. data/lib/sparql/algebra/operator/order.rb +3 -3
  53. data/lib/sparql/algebra/operator/plus.rb +14 -8
  54. data/lib/sparql/algebra/operator/prefix.rb +1 -1
  55. data/lib/sparql/algebra/operator/project.rb +1 -1
  56. data/lib/sparql/algebra/operator/reduced.rb +1 -1
  57. data/lib/sparql/algebra/operator/replace.rb +1 -1
  58. data/lib/sparql/algebra/operator/slice.rb +1 -1
  59. data/lib/sparql/algebra/operator/strafter.rb +1 -1
  60. data/lib/sparql/algebra/operator/strbefore.rb +2 -2
  61. data/lib/sparql/algebra/operator/strdt.rb +1 -1
  62. data/lib/sparql/algebra/operator/strlang.rb +1 -1
  63. data/lib/sparql/algebra/operator/substr.rb +2 -2
  64. data/lib/sparql/algebra/operator/ucase.rb +1 -1
  65. data/lib/sparql/algebra/operator/union.rb +1 -1
  66. data/lib/sparql/algebra/operator/update.rb +44 -0
  67. data/lib/sparql/algebra/operator/using.rb +40 -0
  68. data/lib/sparql/algebra/operator/with.rb +72 -0
  69. data/lib/sparql/algebra/update.rb +56 -0
  70. data/lib/sparql/extensions.rb +8 -8
  71. data/lib/sparql/grammar.rb +31 -8
  72. data/lib/sparql/grammar/meta.rb +3758 -3273
  73. data/lib/sparql/grammar/parser11.rb +240 -46
  74. data/lib/sparql/grammar/terminals11.rb +5 -5
  75. data/lib/sparql/results.rb +26 -26
  76. metadata +38 -30
@@ -63,7 +63,7 @@ module SPARQL::Grammar
63
63
  terminal(:BLANK_NODE_LABEL, BLANK_NODE_LABEL) do |prod, token, input|
64
64
  add_prod_datum(:BlankNode, bnode(token.value[2..-1]))
65
65
  end
66
- terminal(:IRIREF, IRIREF, :unescape => true) do |prod, token, input|
66
+ terminal(:IRIREF, IRIREF, unescape: true) do |prod, token, input|
67
67
  begin
68
68
  add_prod_datum(:iri, iri(token.value[1..-2]))
69
69
  rescue ArgumentError => e
@@ -74,54 +74,54 @@ module SPARQL::Grammar
74
74
  # Note that a Turtle Double may begin with a '.[eE]', so tack on a leading
75
75
  # zero if necessary
76
76
  value = token.value.sub(/\.([eE])/, '.0\1')
77
- add_prod_datum(:literal, literal(value, :datatype => RDF::XSD.double))
77
+ add_prod_datum(:literal, literal(value, datatype: RDF::XSD.double))
78
78
  end
79
79
  terminal(:DECIMAL_POSITIVE, DECIMAL_POSITIVE) do |prod, token, input|
80
80
  # Note that a Turtle Decimal may begin with a '.', so tack on a leading
81
81
  # zero if necessary
82
82
  value = token.value
83
83
  value = "0#{token.value}" if token.value[0,1] == "."
84
- add_prod_datum(:literal, literal(value, :datatype => RDF::XSD.decimal))
84
+ add_prod_datum(:literal, literal(value, datatype: RDF::XSD.decimal))
85
85
  end
86
86
  terminal(:INTEGER_POSITIVE, INTEGER_POSITIVE) do |prod, token, input|
87
- add_prod_datum(:literal, literal(token.value, :datatype => RDF::XSD.integer))
87
+ add_prod_datum(:literal, literal(token.value, datatype: RDF::XSD.integer))
88
88
  end
89
89
  terminal(:DOUBLE_NEGATIVE, DOUBLE_NEGATIVE) do |prod, token, input|
90
90
  # Note that a Turtle Double may begin with a '.[eE]', so tack on a leading
91
91
  # zero if necessary
92
92
  value = token.value.sub(/\.([eE])/, '.0\1')
93
- add_prod_datum(:literal, literal(value, :datatype => RDF::XSD.double))
93
+ add_prod_datum(:literal, literal(value, datatype: RDF::XSD.double))
94
94
  end
95
95
  terminal(:DECIMAL_NEGATIVE, DECIMAL_NEGATIVE) do |prod, token, input|
96
96
  # Note that a Turtle Decimal may begin with a '.', so tack on a leading
97
97
  # zero if necessary
98
98
  value = token.value
99
99
  value = "0#{token.value}" if token.value[0,1] == "."
100
- add_prod_datum(:literal, literal(value, :datatype => RDF::XSD.decimal))
100
+ add_prod_datum(:literal, literal(value, datatype: RDF::XSD.decimal))
101
101
  end
102
102
  terminal(:INTEGER_NEGATIVE, INTEGER_NEGATIVE) do |prod, token, input|
103
- add_prod_datum(:resource, literal(token.value, :datatype => RDF::XSD.integer))
103
+ add_prod_datum(:resource, literal(token.value, datatype: RDF::XSD.integer))
104
104
  end
105
105
  terminal(:DOUBLE, DOUBLE) do |prod, token, input|
106
106
  # Note that a Turtle Double may begin with a '.[eE]', so tack on a leading
107
107
  # zero if necessary
108
108
  value = token.value.sub(/\.([eE])/, '.0\1')
109
- add_prod_datum(:literal, literal(value, :datatype => RDF::XSD.double))
109
+ add_prod_datum(:literal, literal(value, datatype: RDF::XSD.double))
110
110
  end
111
111
  terminal(:DECIMAL, DECIMAL) do |prod, token, input|
112
112
  # Note that a Turtle Decimal may begin with a '.', so tack on a leading
113
113
  # zero if necessary
114
114
  value = token.value
115
115
  #value = "0#{token.value}" if token.value[0,1] == "."
116
- add_prod_datum(:literal, literal(value, :datatype => RDF::XSD.decimal))
116
+ add_prod_datum(:literal, literal(value, datatype: RDF::XSD.decimal))
117
117
  end
118
118
  terminal(:INTEGER, INTEGER) do |prod, token, input|
119
- add_prod_datum(:literal, literal(token.value, :datatype => RDF::XSD.integer))
119
+ add_prod_datum(:literal, literal(token.value, datatype: RDF::XSD.integer))
120
120
  end
121
121
  terminal(:LANGTAG, LANGTAG) do |prod, token, input|
122
122
  add_prod_datum(:language, token.value[1..-1])
123
123
  end
124
- terminal(:PNAME_LN, PNAME_LN, :unescape => true) do |prod, token, input|
124
+ terminal(:PNAME_LN, PNAME_LN, unescape: true) do |prod, token, input|
125
125
  prefix, suffix = token.value.split(":", 2)
126
126
  add_prod_datum(:PrefixedName, ns(prefix, suffix))
127
127
  end
@@ -132,16 +132,16 @@ module SPARQL::Grammar
132
132
  # [4] PrefixDecl := 'PREFIX' PNAME_NS IRI_REF";
133
133
  add_prod_datum(:prefix, prefix && prefix.to_sym)
134
134
  end
135
- terminal(:STRING_LITERAL_LONG1, STRING_LITERAL_LONG1, :unescape => true) do |prod, token, input|
135
+ terminal(:STRING_LITERAL_LONG1, STRING_LITERAL_LONG1, unescape: true) do |prod, token, input|
136
136
  add_prod_datum(:string, token.value[3..-4])
137
137
  end
138
- terminal(:STRING_LITERAL_LONG2, STRING_LITERAL_LONG2, :unescape => true) do |prod, token, input|
138
+ terminal(:STRING_LITERAL_LONG2, STRING_LITERAL_LONG2, unescape: true) do |prod, token, input|
139
139
  add_prod_datum(:string, token.value[3..-4])
140
140
  end
141
- terminal(:STRING_LITERAL1, STRING_LITERAL1, :unescape => true) do |prod, token, input|
141
+ terminal(:STRING_LITERAL1, STRING_LITERAL1, unescape: true) do |prod, token, input|
142
142
  add_prod_datum(:string, token.value[1..-2])
143
143
  end
144
- terminal(:STRING_LITERAL2, STRING_LITERAL2, :unescape => true) do |prod, token, input|
144
+ terminal(:STRING_LITERAL2, STRING_LITERAL2, unescape: true) do |prod, token, input|
145
145
  add_prod_datum(:string, token.value[1..-2])
146
146
  end
147
147
  terminal(:VAR1, VAR1) do |prod, token, input|
@@ -152,7 +152,7 @@ module SPARQL::Grammar
152
152
  end
153
153
 
154
154
  # Keyword terminals
155
- terminal(nil, STR_EXPR, :map => STR_MAP) do |prod, token, input|
155
+ terminal(nil, STR_EXPR, map: STR_MAP) do |prod, token, input|
156
156
  case token.value
157
157
  when '+', '-'
158
158
  case prod
@@ -174,11 +174,11 @@ module SPARQL::Grammar
174
174
  when /ASC|DESC/ then add_prod_datum(:OrderDirection, token.value.downcase.to_sym)
175
175
  when /DISTINCT|REDUCED/ then add_prod_datum(:DISTINCT_REDUCED, token.value.downcase.to_sym)
176
176
  when %r{
177
- ABS|AVG|BNODE|BOUND|CEIL|COALESCE|CONCAT
178
- |CONTAINS|COUNT|DATATYPE|DAY|ENCODE_FOR_URI|EXISTS
179
- |FLOOR|HOURS|IF|GROUP_CONCAT|IRI|LANGMATCHES|LANG|LCASE
180
- |MAX|MD5|MINUTES|MIN|MONTH|NOW|RAND|REPLACE|ROUND|SAMPLE|SECONDS|SEPARATOR
181
- |SHA1|SHA224|SHA256|SHA384|SHA512
177
+ ABS|ALL|AVG|BNODE|BOUND|CEIL|COALESCE|CONCAT
178
+ |CONTAINS|COUNT|DATATYPE|DAY|DEFAULT|ENCODE_FOR_URI|EXISTS
179
+ |FLOOR|HOURS|IF|GRAPH|GROUP_CONCAT|IRI|LANGMATCHES|LANG|LCASE
180
+ |MAX|MD5|MINUTES|MIN|MONTH|NAMED|NOW|RAND|REPLACE|ROUND|SAMPLE|SECONDS|SEPARATOR
181
+ |SHA1|SHA224|SHA256|SHA384|SHA512|SILENT
182
182
  |STRAFTER|STRBEFORE|STRDT|STRENDS|STRLANG|STRLEN|STRSTARTS|STRUUID|SUBSTR|STR|SUM
183
183
  |TIMEZONE|TZ|UCASE|UNDEF|URI|UUID|YEAR
184
184
  |isBLANK|isIRI|isURI|isLITERAL|isNUMERIC|sameTerm
@@ -193,8 +193,6 @@ module SPARQL::Grammar
193
193
  # [2] Query ::= Prologue
194
194
  # ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery )
195
195
  production(:Query) do |input, data, callback|
196
- return unless data[:query]
197
-
198
196
  query = data[:query].first
199
197
 
200
198
  # Add prefix
@@ -377,8 +375,197 @@ module SPARQL::Grammar
377
375
  end
378
376
  end
379
377
 
380
- # [54] GroupGraphPatternSub ::= TriplesBlock?
381
- # ( GraphPatternNotTriples '.'? TriplesBlock? )*
378
+ # [29] Update ::= Prologue (Update1 (";" Update)? )?
379
+ production(:Update) do |input, data, callback|
380
+ update = data[:update] || SPARQL::Algebra::Expression(:update)
381
+
382
+ # Add prefix
383
+ if data[:PrefixDecl]
384
+ pfx = data[:PrefixDecl].shift
385
+ data[:PrefixDecl].each {|p| pfx.merge!(p)}
386
+ pfx.operands[1] = update
387
+ update = pfx
388
+ end
389
+
390
+ # Add base
391
+ update = SPARQL::Algebra::Expression[:base, data[:BaseDecl].first, update] if data[:BaseDecl]
392
+
393
+ # Don't use update operator twice, if we can help it
394
+ input[:update] = update
395
+ end
396
+ production(:_Update_3) do |input, data, callback|
397
+ if data[:update]
398
+ if input[:update].is_a?(SPARQL::Algebra::Operator::Update)
399
+ # Append operands
400
+ input[:update] = SPARQL::Algebra::Expression(:update, *(input[:update].operands + data[:update].operands))
401
+ else
402
+ add_prod_datum(:update, data[:update])
403
+ end
404
+ end
405
+ end
406
+
407
+ # [30] Update1 ::= Load | Clear | Drop | Add | Move | Copy | Create | InsertData | DeleteData | DeleteWhere | Modify
408
+ production(:Update1) do |input, data, callback|
409
+ input[:update] = SPARQL::Algebra::Expression.for(:update, data[:update_op])
410
+ end
411
+
412
+ # [31] Load ::= "LOAD" "SILENT"? iri ("INTO" GraphRef)?
413
+ production(:Load) do |input, data, callback|
414
+ args = []
415
+ args << :silent if data[:silent]
416
+ args += Array(data[:iri])
417
+ input[:update_op] = SPARQL::Algebra::Expression(:load, *args)
418
+ end
419
+
420
+ # [32] Clear ::= "CLEAR" "SILENT"? GraphRefAll
421
+ production(:Clear) do |input, data, callback|
422
+ args = []
423
+ %w(silent default named all).map(&:to_sym).each do |s|
424
+ args << s if data[s]
425
+ end
426
+ args += Array(data[:iri])
427
+ input[:update_op] = SPARQL::Algebra::Expression(:clear, *args)
428
+ end
429
+
430
+ # [33] Drop ::= "DROP" "SILENT"? GraphRefAll
431
+ production(:Drop) do |input, data, callback|
432
+ args = []
433
+ %w(silent default named all).map(&:to_sym).each do |s|
434
+ args << s if data[s]
435
+ end
436
+ args += Array(data[:iri])
437
+ input[:update_op] = SPARQL::Algebra::Expression(:drop, *args)
438
+ end
439
+
440
+ # [34] Create ::= "CREATE" "SILENT"? GraphRef
441
+ production(:Create) do |input, data, callback|
442
+ args = []
443
+ args << :silent if data[:silent]
444
+ args += Array(data[:iri])
445
+ input[:update_op] = SPARQL::Algebra::Expression(:create, *args)
446
+ end
447
+
448
+ # [35] Add ::= "ADD" "SILENT"? GraphOrDefault "TO" GraphOrDefault
449
+ production(:Add) do |input, data, callback|
450
+ args = []
451
+ args << :silent if data[:silent]
452
+ args += data[:GraphOrDefault]
453
+ input[:update_op] = SPARQL::Algebra::Expression(:add, *args)
454
+ end
455
+
456
+ # [36] Move ::= "MOVE" "SILENT"? GraphOrDefault "TO" GraphOrDefault
457
+ production(:Move) do |input, data, callback|
458
+ args = []
459
+ args << :silent if data[:silent]
460
+ args += data[:GraphOrDefault]
461
+ input[:update_op] = SPARQL::Algebra::Expression(:move, *args)
462
+ end
463
+
464
+ # [37] Copy ::= "COPY" "SILENT"? GraphOrDefault "TO" GraphOrDefault
465
+ production(:Copy) do |input, data, callback|
466
+ args = []
467
+ args << :silent if data[:silent]
468
+ args += data[:GraphOrDefault]
469
+ input[:update_op] = SPARQL::Algebra::Expression(:copy, *args)
470
+ end
471
+
472
+ # [38] InsertData ::= "INSERT DATA" QuadData
473
+ production(:InsertData) do |input, data, callback|
474
+ input[:update_op] = SPARQL::Algebra::Expression(:insertData, data[:pattern])
475
+ end
476
+
477
+ # [39] DeleteData ::= "DELETE DATA" QuadData
478
+ production(:DeleteData) do |input, data, callback|
479
+ raise Error, "DeleteData contains BNode operands: #{data[:pattern].to_sse}" if data[:pattern].first.has_blank_nodes?
480
+ input[:update_op] = SPARQL::Algebra::Expression(:deleteData, data[:pattern])
481
+ end
482
+
483
+ # [40] DeleteWhere ::= "DELETE WHERE" QuadPattern
484
+ start_production(:DeleteWhere) do |input, data, callback|
485
+ # Generate BNodes instead of non-distinguished variables. BNodes are not legal, but this will generate them rather than non-distinguished variables so they can be detected.
486
+ self.clear_bnode_cache
487
+ end
488
+ production(:DeleteWhere) do |input, data, callback|
489
+ raise Error, "DeleteWhere contains BNode operands: #{data[:pattern].to_sse}" if data[:pattern].first.has_blank_nodes?
490
+ self.nd_var_gen = "0"
491
+ input[:update_op] = SPARQL::Algebra::Expression(:deleteWhere, data[:pattern])
492
+ end
493
+
494
+ # [41] Modify ::= ("WITH" iri)? ( DeleteClause InsertClause? | InsertClause) UsingClause* "WHERE" GroupGraphPattern
495
+ production(:Modify) do |input, data, callback|
496
+ query = data[:query].first if data[:query]
497
+ query = SPARQL::Algebra::Expression.for(:using, data[:using], query) if data[:using]
498
+ operands = [query, data[:delete], data[:insert]].compact
499
+ operands = [SPARQL::Algebra::Expression.for(:with, data[:iri].first, *operands)] if data[:iri]
500
+ input[:update_op] = SPARQL::Algebra::Expression(:modify, *operands)
501
+ end
502
+
503
+ # [42] DeleteClause ::= "DELETE" QuadPattern
504
+ start_production(:DeleteClause) do |input, data, callback|
505
+ # Generate BNodes instead of non-distinguished variables. BNodes are not legal, but this will generate them rather than non-distinguished variables so they can be detected.
506
+ self.clear_bnode_cache
507
+ end
508
+ production(:DeleteClause) do |input, data, callback|
509
+ raise Error, "DeleteClause contains BNode operands: #{data[:pattern].to_sse}" if data[:pattern].first.has_blank_nodes?
510
+ self.nd_var_gen = "0"
511
+ input[:delete] = SPARQL::Algebra::Expression(:delete, data[:pattern])
512
+ end
513
+
514
+ # [43] InsertClause ::= "INSERT" QuadPattern
515
+ production(:InsertClause) do |input, data, callback|
516
+ input[:insert] = SPARQL::Algebra::Expression(:insert, data[:pattern])
517
+ end
518
+
519
+ # [44] UsingClause ::= "USING" ( iri | "NAMED" iri)
520
+ production(:UsingClause) do |input, data, callback|
521
+ add_prod_data(:using, data[:iri].first)
522
+ end
523
+ production(:_UsingClause_2) do |input, data, callback|
524
+ add_prod_data(:iri, [:named, data[:iri].first])
525
+ end
526
+
527
+ # [45] GraphOrDefault ::= "DEFAULT" | "GRAPH"? iri
528
+ production(:GraphOrDefault) do |input, data, callback|
529
+ if data[:default]
530
+ add_prod_datum(:GraphOrDefault, :default)
531
+ else
532
+ add_prod_data(:GraphOrDefault, data[:iri].first)
533
+ end
534
+ end
535
+
536
+ # [46] GraphRef ::= "GRAPH" iri
537
+ production(:GraphRef) do |input, data, callback|
538
+ add_prod_data(:iri, data[:iri].first)
539
+ end
540
+ # [47] GraphRefAll ::= GraphRef | "DEFAULT" | "NAMED" | "ALL"
541
+ #production(:GraphRefAll) do |input, data, callback|
542
+ # add_prod_datum(:GraphRefAll, data)
543
+ #end
544
+
545
+ # [49] QuadData ::= "{" Quads "}"
546
+ # QuadData is like QuadPattern, except without BNodes
547
+ start_production(:QuadData) do |input, data, callback|
548
+ # Generate BNodes instead of non-distinguished variables
549
+ self.clear_bnode_cache
550
+ end
551
+ production(:QuadData) do |input, data, callback|
552
+ # Transform using statements instead of patterns, and verify there are no variables
553
+ raise Error, "QuadData contains variable operands: #{data[:pattern].to_sse}" if data[:pattern].first.variable?
554
+ self.nd_var_gen = "0"
555
+ input[:pattern] = data[:pattern]
556
+ end
557
+
558
+ # [51] QuadsNotTriples ::= "GRAPH" VarOrIri "{" TriplesTemplate? "}"
559
+ production(:QuadsNotTriples) do |input, data, callback|
560
+ add_prod_datum(:pattern, [SPARQL::Algebra::Expression.for(:graph, data[:VarOrIri].last, data[:pattern])])
561
+ end
562
+
563
+ # [52] TriplesTemplate ::= TriplesSameSubject ("." TriplesTemplate? )?
564
+ production(:TriplesTemplate) do |input, data, callback|
565
+ add_prod_datum(:pattern, data[:pattern])
566
+ end
567
+
568
+ # [54] GroupGraphPatternSub ::= TriplesBlock? (GraphPatternNotTriples "."? TriplesBlock? )*
382
569
  production(:GroupGraphPatternSub) do |input, data, callback|
383
570
  debug("GroupGraphPatternSub") {"q #{data[:query].inspect}"}
384
571
 
@@ -522,7 +709,6 @@ module SPARQL::Grammar
522
709
 
523
710
  # [66] MinusGraphPattern ::= 'MINUS' GroupGraphPattern
524
711
  production(:MinusGraphPattern) do |input, data, callback|
525
- expr = nil
526
712
  query = data[:query] ? data[:query].first : SPARQL::Algebra::Operator::BGP.new
527
713
  add_prod_data(:minus, query)
528
714
  end
@@ -586,7 +772,7 @@ module SPARQL::Grammar
586
772
  # [73] ConstructTemplate ::= '{' ConstructTriples? '}'
587
773
  start_production(:ConstructTemplate) do |input, data, callback|
588
774
  # Generate BNodes instead of non-distinguished variables
589
- self.nd_var_gen = false
775
+ self.clear_bnode_cache
590
776
  end
591
777
  production(:ConstructTemplate) do |input, data, callback|
592
778
  # Generate BNodes instead of non-distinguished variables
@@ -605,7 +791,7 @@ module SPARQL::Grammar
605
791
  # ( ';' ( Verb ObjectList )? )*
606
792
  start_production(:PropertyListNotEmpty) do |input, data, callback|
607
793
  subject = input[:VarOrTerm] || input[:TriplesNode] || input[:GraphNode]
608
- error(nil, "Expected VarOrTerm or TriplesNode or GraphNode", :production => :PropertyListNotEmpty) if validate? && !subject
794
+ error(nil, "Expected VarOrTerm or TriplesNode or GraphNode", production: :PropertyListNotEmpty) if validate? && !subject
609
795
  data[:Subject] = subject
610
796
  end
611
797
  production(:PropertyListNotEmpty) do |input, data, callback|
@@ -616,8 +802,8 @@ module SPARQL::Grammar
616
802
  start_production(:ObjectList) do |input, data, callback|
617
803
  # Called after Verb. The prod_data stack should have Subject and Verb elements
618
804
  data[:Subject] = prod_data[:Subject]
619
- error(nil, "Expected Subject", :production => :ObjectList) if !prod_data[:Subject] && validate?
620
- error(nil, "Expected Verb", :production => :ObjectList) if !prod_data[:Verb] && validate?
805
+ error(nil, "Expected Subject", production: :ObjectList) if !prod_data[:Subject] && validate?
806
+ error(nil, "Expected Verb", production: :ObjectList) if !prod_data[:Verb] && validate?
621
807
  data[:Subject] = prod_data[:Subject]
622
808
  data[:Verb] = prod_data[:Verb].to_a.last
623
809
  end
@@ -629,7 +815,7 @@ module SPARQL::Grammar
629
815
  production(:Object) do |input, data, callback|
630
816
  object = data[:VarOrTerm] || data[:TriplesNode] || data[:GraphNode]
631
817
  if object
632
- add_pattern(:Object, :subject => prod_data[:Subject], :predicate => prod_data[:Verb], :object => object)
818
+ add_pattern(:Object, subject: prod_data[:Subject], predicate: prod_data[:Verb], object: object)
633
819
  add_prod_datum(:pattern, data[:pattern])
634
820
  end
635
821
  end
@@ -642,7 +828,7 @@ module SPARQL::Grammar
642
828
  # [83] PropertyListNotEmptyPath ::= ( VerbPath | VerbSimple ) ObjectList ( ';' ( ( VerbPath | VerbSimple ) ObjectList )? )*
643
829
  start_production(:PropertyListNotEmptyPath) do |input, data, callback|
644
830
  subject = input[:VarOrTerm]
645
- error(nil, "Expected VarOrTerm", :production => ::PropertyListNotEmptyPath) if validate? && !subject
831
+ error(nil, "Expected VarOrTerm", production: ::PropertyListNotEmptyPath) if validate? && !subject
646
832
  data[:Subject] = subject
647
833
  end
648
834
  production(:PropertyListNotEmptyPath) do |input, data, callback|
@@ -1064,7 +1250,7 @@ module SPARQL::Grammar
1064
1250
  else input.to_s.dup
1065
1251
  end
1066
1252
  @input.encode!(Encoding::UTF_8) if @input.respond_to?(:encode!)
1067
- @options = {:anon_base => "b0", :validate => false}.merge(options)
1253
+ @options = {anon_base: "b0", validate: false}.merge(options)
1068
1254
  @options[:debug] ||= case
1069
1255
  when options[:progress] then 2
1070
1256
  when options[:validate] then 1
@@ -1122,10 +1308,10 @@ module SPARQL::Grammar
1122
1308
  # @see http://www.w3.org/TR/sparql11-query/#sparqlAlgebra
1123
1309
  # @see http://axel.deri.ie/sparqltutorial/ESWC2007_SPARQL_Tutorial_unit2b.pdf
1124
1310
  def parse(prod = START)
1125
- ll1_parse(@input, prod.to_sym, @options.merge(:branch => BRANCH,
1126
- :first => FIRST,
1127
- :follow => FOLLOW,
1128
- :whitespace => WS)
1311
+ ll1_parse(@input, prod.to_sym, @options.merge(branch: BRANCH,
1312
+ first: FIRST,
1313
+ follow: FOLLOW,
1314
+ whitespace: WS)
1129
1315
  ) do |context, *data|
1130
1316
  case context
1131
1317
  when :trace
@@ -1152,9 +1338,11 @@ module SPARQL::Grammar
1152
1338
  nil
1153
1339
  when prod_data[:query]
1154
1340
  prod_data[:query].to_a.length == 1 ? prod_data[:query].first : prod_data[:query]
1341
+ when prod_data[:update]
1342
+ prod_data[:update]
1155
1343
  else
1156
1344
  key = prod_data.keys.first
1157
- [key] + prod_data[key] # Creates [:key, [:triple], ...]
1345
+ [key] + Array(prod_data[key]) # Creates [:key, [:triple], ...]
1158
1346
  end
1159
1347
  end
1160
1348
 
@@ -1176,7 +1364,7 @@ module SPARQL::Grammar
1176
1364
  #
1177
1365
  # @example
1178
1366
  # prefixes = {
1179
- # :dc => RDF::URI('http://purl.org/dc/terms/'),
1367
+ # dc: RDF::URI('http://purl.org/dc/terms/'),
1180
1368
  # }
1181
1369
  #
1182
1370
  # @param [Hash{Symbol => RDF::URI}] prefixes
@@ -1254,6 +1442,12 @@ module SPARQL::Grammar
1254
1442
  # Used for generating BNode labels
1255
1443
  attr_accessor :nd_var_gen
1256
1444
 
1445
+ # Reset the bnode cache, always generating new nodes, and start generating BNodes instead of non-distinguished variables
1446
+ def clear_bnode_cache
1447
+ @nd_var_gen = false
1448
+ @bnode_cache = {}
1449
+ end
1450
+
1257
1451
  # Generate a BNode identifier
1258
1452
  def bnode(id = nil)
1259
1453
  if @nd_var_gen
@@ -1334,7 +1528,7 @@ module SPARQL::Grammar
1334
1528
  "options: #{options.inspect}, " +
1335
1529
  "validate: #{validate?.inspect}, "
1336
1530
  end
1337
- RDF::Literal.new(value, options.merge(:validate => validate?))
1531
+ RDF::Literal.new(value, options.merge(validate: validate?))
1338
1532
  end
1339
1533
 
1340
1534
  # Take collection of objects and create RDF Collection using rdf:first, rdf:rest and rdf:nil
@@ -1349,16 +1543,16 @@ module SPARQL::Grammar
1349
1543
  last = list.pop
1350
1544
 
1351
1545
  list.each do |r|
1352
- add_pattern(:Collection, :subject => first, :predicate => RDF["first"], :object => r)
1546
+ add_pattern(:Collection, subject: first, predicate: RDF["first"], object: r)
1353
1547
  rest = bnode()
1354
- add_pattern(:Collection, :subject => first, :predicate => RDF["rest"], :object => rest)
1548
+ add_pattern(:Collection, subject: first, predicate: RDF["rest"], object: rest)
1355
1549
  first = rest
1356
1550
  end
1357
1551
 
1358
1552
  if last
1359
- add_pattern(:Collection, :subject => first, :predicate => RDF["first"], :object => last)
1553
+ add_pattern(:Collection, subject: first, predicate: RDF["first"], object: last)
1360
1554
  end
1361
- add_pattern(:Collection, :subject => first, :predicate => RDF["rest"], :object => RDF["nil"])
1555
+ add_pattern(:Collection, subject: first, predicate: RDF["rest"], object: RDF["nil"])
1362
1556
  end
1363
1557
 
1364
1558
  # add a pattern
@@ -1375,14 +1569,14 @@ module SPARQL::Grammar
1375
1569
  end
1376
1570
  if validate? && !v.is_a?(RDF::Term)
1377
1571
  error("add_pattern", "Expected #{r} to be a resource, but it was #{v.inspect}",
1378
- :production => production)
1572
+ production: production)
1379
1573
  end
1380
1574
  triple[r] = v
1381
1575
  end
1382
1576
  add_prod_datum(:pattern, RDF::Query::Pattern.new(triple))
1383
1577
  end
1384
1578
 
1385
- # Flatten a Data in form of :filter => [op+ bgp?], without a query into filter and query creating exprlist, if necessary
1579
+ # Flatten a Data in form of filter: [op+ bgp?], without a query into filter and query creating exprlist, if necessary
1386
1580
  # @return [Array[:expr, query]]
1387
1581
  def flatten_filter(data)
1388
1582
  query = data.pop if data.last.is_a?(SPARQL::Algebra::Query)