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.
- checksums.yaml +4 -4
- data/README.md +36 -32
- data/VERSION +1 -1
- data/bin/sparql +8 -6
- data/lib/sparql.rb +4 -2
- data/lib/sparql/algebra.rb +74 -4
- data/lib/sparql/algebra/aggregate.rb +1 -1
- data/lib/sparql/algebra/evaluatable.rb +1 -1
- data/lib/sparql/algebra/expression.rb +24 -16
- data/lib/sparql/algebra/extensions.rb +37 -9
- data/lib/sparql/algebra/operator.rb +75 -12
- data/lib/sparql/algebra/operator/add.rb +41 -19
- data/lib/sparql/algebra/operator/and.rb +2 -2
- data/lib/sparql/algebra/operator/asc.rb +1 -1
- data/lib/sparql/algebra/operator/ask.rb +1 -1
- data/lib/sparql/algebra/operator/base.rb +1 -1
- data/lib/sparql/algebra/operator/bgp.rb +1 -1
- data/lib/sparql/algebra/operator/bnode.rb +1 -1
- data/lib/sparql/algebra/operator/clear.rb +63 -0
- data/lib/sparql/algebra/operator/coalesce.rb +1 -1
- data/lib/sparql/algebra/operator/concat.rb +3 -3
- data/lib/sparql/algebra/operator/construct.rb +2 -2
- data/lib/sparql/algebra/operator/copy.rb +64 -0
- data/lib/sparql/algebra/operator/create.rb +49 -0
- data/lib/sparql/algebra/operator/dataset.rb +6 -31
- data/lib/sparql/algebra/operator/delete.rb +55 -0
- data/lib/sparql/algebra/operator/delete_data.rb +41 -0
- data/lib/sparql/algebra/operator/delete_where.rb +57 -0
- data/lib/sparql/algebra/operator/distinct.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +66 -0
- data/lib/sparql/algebra/operator/exists.rb +2 -2
- data/lib/sparql/algebra/operator/exprlist.rb +1 -1
- data/lib/sparql/algebra/operator/extend.rb +3 -3
- data/lib/sparql/algebra/operator/filter.rb +2 -2
- data/lib/sparql/algebra/operator/graph.rb +39 -5
- data/lib/sparql/algebra/operator/group.rb +5 -5
- data/lib/sparql/algebra/operator/group_concat.rb +1 -1
- data/lib/sparql/algebra/operator/if.rb +3 -3
- data/lib/sparql/algebra/operator/in.rb +1 -1
- data/lib/sparql/algebra/operator/insert.rb +54 -0
- data/lib/sparql/algebra/operator/insert_data.rb +41 -0
- data/lib/sparql/algebra/operator/join.rb +2 -2
- data/lib/sparql/algebra/operator/lcase.rb +1 -1
- data/lib/sparql/algebra/operator/left_join.rb +2 -2
- data/lib/sparql/algebra/operator/load.rb +48 -0
- data/lib/sparql/algebra/operator/minus.rb +2 -2
- data/lib/sparql/algebra/operator/modify.rb +53 -0
- data/lib/sparql/algebra/operator/move.rb +67 -0
- data/lib/sparql/algebra/operator/notexists.rb +1 -1
- data/lib/sparql/algebra/operator/notin.rb +2 -2
- data/lib/sparql/algebra/operator/or.rb +2 -2
- data/lib/sparql/algebra/operator/order.rb +3 -3
- data/lib/sparql/algebra/operator/plus.rb +14 -8
- data/lib/sparql/algebra/operator/prefix.rb +1 -1
- data/lib/sparql/algebra/operator/project.rb +1 -1
- data/lib/sparql/algebra/operator/reduced.rb +1 -1
- data/lib/sparql/algebra/operator/replace.rb +1 -1
- data/lib/sparql/algebra/operator/slice.rb +1 -1
- data/lib/sparql/algebra/operator/strafter.rb +1 -1
- data/lib/sparql/algebra/operator/strbefore.rb +2 -2
- data/lib/sparql/algebra/operator/strdt.rb +1 -1
- data/lib/sparql/algebra/operator/strlang.rb +1 -1
- data/lib/sparql/algebra/operator/substr.rb +2 -2
- data/lib/sparql/algebra/operator/ucase.rb +1 -1
- data/lib/sparql/algebra/operator/union.rb +1 -1
- data/lib/sparql/algebra/operator/update.rb +44 -0
- data/lib/sparql/algebra/operator/using.rb +40 -0
- data/lib/sparql/algebra/operator/with.rb +72 -0
- data/lib/sparql/algebra/update.rb +56 -0
- data/lib/sparql/extensions.rb +8 -8
- data/lib/sparql/grammar.rb +31 -8
- data/lib/sparql/grammar/meta.rb +3758 -3273
- data/lib/sparql/grammar/parser11.rb +240 -46
- data/lib/sparql/grammar/terminals11.rb +5 -5
- data/lib/sparql/results.rb +26 -26
- 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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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, :
|
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
|
-
# [
|
381
|
-
|
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.
|
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", :
|
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", :
|
620
|
-
error(nil, "Expected Verb", :
|
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, :
|
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", :
|
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 = {:
|
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(:
|
1126
|
-
:
|
1127
|
-
:
|
1128
|
-
:
|
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
|
-
# :
|
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(:
|
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, :
|
1546
|
+
add_pattern(:Collection, subject: first, predicate: RDF["first"], object: r)
|
1353
1547
|
rest = bnode()
|
1354
|
-
add_pattern(:Collection, :
|
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, :
|
1553
|
+
add_pattern(:Collection, subject: first, predicate: RDF["first"], object: last)
|
1360
1554
|
end
|
1361
|
-
add_pattern(:Collection, :
|
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
|
-
:
|
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 :
|
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)
|