sparql 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|