sparql 3.2.0 → 3.2.4
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 +59 -38
- data/VERSION +1 -1
- data/bin/sparql +2 -31
- data/lib/rack/sparql/conneg.rb +22 -1
- data/lib/sinatra/sparql/extensions.rb +1 -1
- data/lib/sinatra/sparql.rb +57 -12
- data/lib/sparql/algebra/expression.rb +63 -10
- data/lib/sparql/algebra/extensions.rb +39 -35
- data/lib/sparql/algebra/operator/abs.rb +1 -1
- data/lib/sparql/algebra/operator/adjust.rb +69 -0
- data/lib/sparql/algebra/operator/alt.rb +1 -1
- data/lib/sparql/algebra/operator/avg.rb +3 -1
- data/lib/sparql/algebra/operator/bgp.rb +9 -1
- data/lib/sparql/algebra/operator/clear.rb +13 -3
- data/lib/sparql/algebra/operator/construct.rb +1 -1
- data/lib/sparql/algebra/operator/count.rb +36 -6
- data/lib/sparql/algebra/operator/create.rb +5 -4
- data/lib/sparql/algebra/operator/dataset.rb +29 -11
- data/lib/sparql/algebra/operator/day.rb +2 -2
- data/lib/sparql/algebra/operator/delete.rb +3 -1
- data/lib/sparql/algebra/operator/delete_data.rb +1 -1
- data/lib/sparql/algebra/operator/delete_where.rb +1 -1
- data/lib/sparql/algebra/operator/distinct.rb +2 -2
- data/lib/sparql/algebra/operator/divide.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +15 -6
- data/lib/sparql/algebra/operator/encode_for_uri.rb +2 -4
- data/lib/sparql/algebra/operator/exprlist.rb +3 -1
- data/lib/sparql/algebra/operator/extend.rb +73 -5
- data/lib/sparql/algebra/operator/filter.rb +6 -1
- data/lib/sparql/algebra/operator/function_call.rb +64 -0
- data/lib/sparql/algebra/operator/graph.rb +57 -7
- data/lib/sparql/algebra/operator/group.rb +105 -6
- data/lib/sparql/algebra/operator/group_concat.rb +25 -1
- data/lib/sparql/algebra/operator/hours.rb +2 -2
- data/lib/sparql/algebra/operator/if.rb +10 -10
- data/lib/sparql/algebra/operator/insert.rb +3 -1
- data/lib/sparql/algebra/operator/insert_data.rb +1 -1
- data/lib/sparql/algebra/operator/is_blank.rb +1 -2
- data/lib/sparql/algebra/operator/is_iri.rb +1 -2
- data/lib/sparql/algebra/operator/is_literal.rb +1 -2
- data/lib/sparql/algebra/operator/is_numeric.rb +1 -2
- data/lib/sparql/algebra/operator/join.rb +39 -5
- data/lib/sparql/algebra/operator/lcase.rb +2 -3
- data/lib/sparql/algebra/operator/left_join.rb +27 -9
- data/lib/sparql/algebra/operator/max.rb +3 -1
- data/lib/sparql/algebra/operator/min.rb +4 -2
- data/lib/sparql/algebra/operator/minus.rb +46 -6
- data/lib/sparql/algebra/operator/minutes.rb +2 -2
- data/lib/sparql/algebra/operator/modify.rb +21 -0
- data/lib/sparql/algebra/operator/month.rb +2 -2
- data/lib/sparql/algebra/operator/multiply.rb +1 -1
- data/lib/sparql/algebra/operator/notoneof.rb +12 -3
- data/lib/sparql/algebra/operator/order.rb +44 -0
- data/lib/sparql/algebra/operator/path_opt.rb +9 -65
- data/lib/sparql/algebra/operator/path_plus.rb +18 -10
- data/lib/sparql/algebra/operator/path_range.rb +178 -0
- data/lib/sparql/algebra/operator/path_star.rb +7 -4
- data/lib/sparql/algebra/operator/path_zero.rb +110 -0
- data/lib/sparql/algebra/operator/plus.rb +8 -6
- data/lib/sparql/algebra/operator/project.rb +64 -5
- data/lib/sparql/algebra/operator/reduced.rb +3 -3
- data/lib/sparql/algebra/operator/regex.rb +1 -1
- data/lib/sparql/algebra/operator/reverse.rb +12 -1
- data/lib/sparql/algebra/operator/sample.rb +3 -1
- data/lib/sparql/algebra/operator/seconds.rb +2 -2
- data/lib/sparql/algebra/operator/seq.rb +4 -4
- data/lib/sparql/algebra/operator/sequence.rb +14 -1
- data/lib/sparql/algebra/operator/service.rb +86 -0
- data/lib/sparql/algebra/operator/strlang.rb +1 -2
- data/lib/sparql/algebra/operator/subtract.rb +10 -6
- data/lib/sparql/algebra/operator/sum.rb +9 -7
- data/lib/sparql/algebra/operator/table.rb +50 -7
- data/lib/sparql/algebra/operator/timezone.rb +2 -2
- data/lib/sparql/algebra/operator/triple.rb +51 -0
- data/lib/sparql/algebra/operator/tz.rb +2 -2
- data/lib/sparql/algebra/operator/ucase.rb +1 -1
- data/lib/sparql/algebra/operator/update.rb +22 -1
- data/lib/sparql/algebra/operator/using.rb +18 -1
- data/lib/sparql/algebra/operator/with.rb +1 -1
- data/lib/sparql/algebra/operator/year.rb +2 -2
- data/lib/sparql/algebra/operator.rb +69 -22
- data/lib/sparql/algebra/query.rb +5 -3
- data/lib/sparql/algebra.rb +42 -6
- data/lib/sparql/grammar/meta.rb +1367 -267
- data/lib/sparql/grammar/parser11.rb +842 -331
- data/lib/sparql/grammar/terminals11.rb +2 -2
- data/lib/sparql/grammar.rb +6 -4
- data/lib/sparql/results.rb +3 -2
- data/lib/sparql/server.rb +93 -0
- data/lib/sparql.rb +8 -5
- metadata +49 -13
@@ -15,7 +15,7 @@ module SPARQL::Grammar
|
|
15
15
|
|
16
16
|
# Builtin functions
|
17
17
|
BUILTINS = %w{
|
18
|
-
ABS
|
18
|
+
ABS ADJUST BNODE CEIL COALESCE CONCAT
|
19
19
|
CONTAINS DATATYPE DAY ENCODE_FOR_URI
|
20
20
|
FLOOR HOURS IF IRI LANGMATCHES LANG LCASE
|
21
21
|
MD5 MINUTES MONTH NOW RAND ROUND SECONDS
|
@@ -119,7 +119,7 @@ module SPARQL::Grammar
|
|
119
119
|
input[:literal] = literal(token.value, datatype: RDF::XSD.integer)
|
120
120
|
end
|
121
121
|
terminal(:LANGTAG, LANGTAG) do |prod, token, input|
|
122
|
-
|
122
|
+
input[:language] = token.value[1..-1]
|
123
123
|
end
|
124
124
|
terminal(:PNAME_LN, PNAME_LN, unescape: true) do |prod, token, input|
|
125
125
|
prefix, suffix = token.value.split(":", 2)
|
@@ -177,7 +177,7 @@ module SPARQL::Grammar
|
|
177
177
|
when /ASC|DESC/ then input[:OrderDirection] = token.value.downcase.to_sym
|
178
178
|
when /DISTINCT|REDUCED/ then input[:DISTINCT_REDUCED] = token.value.downcase.to_sym
|
179
179
|
when %r{
|
180
|
-
ABS|ALL|AVG|BNODE|BOUND|CEIL|COALESCE|CONCAT
|
180
|
+
ABS|ADJUST|ALL|AVG|BNODE|BOUND|CEIL|COALESCE|CONCAT
|
181
181
|
|CONTAINS|COUNT|DATATYPE|DAY|DEFAULT|ENCODE_FOR_URI|EXISTS
|
182
182
|
|FLOOR|HOURS|IF|GRAPH|GROUP_CONCAT|IRI|LANGMATCHES|LANG|LCASE
|
183
183
|
|MAX|MD5|MINUTES|MIN|MONTH|NAMED|NOW|RAND|REPLACE|ROUND|SAMPLE|SECONDS|SEPARATOR
|
@@ -194,10 +194,13 @@ module SPARQL::Grammar
|
|
194
194
|
end
|
195
195
|
|
196
196
|
# Productions
|
197
|
-
|
198
|
-
#
|
197
|
+
|
198
|
+
# [2] Query ::= Prologue ( SelectQuery | ConstructQuery | DescribeQuery | AskQuery )
|
199
|
+
#
|
200
|
+
# Inputs from `data` are `:query` and potentially `:PrefixDecl`.
|
201
|
+
# Output to prod_data is the Queryable object.
|
199
202
|
production(:Query) do |input, data, callback|
|
200
|
-
query = data[:query].first
|
203
|
+
query = data[:query].first if data[:query]
|
201
204
|
|
202
205
|
# Add prefix
|
203
206
|
if data[:PrefixDecl]
|
@@ -213,7 +216,10 @@ module SPARQL::Grammar
|
|
213
216
|
add_prod_datum(:query, query)
|
214
217
|
end
|
215
218
|
|
216
|
-
# [4]
|
219
|
+
# [4] Prologue ::= ( BaseDecl | PrefixDecl )*
|
220
|
+
#
|
221
|
+
# Inputs from `data` are `:PrefixDecl` and `:BaseDecl`.
|
222
|
+
# Output to prod_data is the same, if `#resolve_iris?` is `false`.
|
217
223
|
production(:Prologue) do |input, data, callback|
|
218
224
|
unless resolve_iris?
|
219
225
|
# Only output if we're not resolving URIs internally
|
@@ -222,7 +228,10 @@ module SPARQL::Grammar
|
|
222
228
|
end
|
223
229
|
end
|
224
230
|
|
225
|
-
# [5]
|
231
|
+
# [5] BaseDecl ::= 'BASE' IRI_REF
|
232
|
+
#
|
233
|
+
# Input from `data` is `:BaseDecl`.
|
234
|
+
# Output to prod_data is the same, if `#resolve_iris?` is `false`.
|
226
235
|
production(:BaseDecl) do |input, data, callback|
|
227
236
|
iri = data[:iri]
|
228
237
|
debug("BaseDecl") {"Defined base as #{iri}"}
|
@@ -230,7 +239,10 @@ module SPARQL::Grammar
|
|
230
239
|
add_prod_datum(:BaseDecl, iri) unless resolve_iris?
|
231
240
|
end
|
232
241
|
|
233
|
-
# [6] PrefixDecl
|
242
|
+
# [6] PrefixDecl ::= 'PREFIX' PNAME_NS IRI_REF
|
243
|
+
#
|
244
|
+
# Inputs from `data` are `:iri`, and `:prefix`.
|
245
|
+
# Output to prod_data is the `:PrefixDecl`, and `Operator::Prefix`, unless there is no `:iri`.
|
234
246
|
production(:PrefixDecl) do |input, data, callback|
|
235
247
|
if data[:iri]
|
236
248
|
pfx = data[:prefix]
|
@@ -240,21 +252,41 @@ module SPARQL::Grammar
|
|
240
252
|
end
|
241
253
|
end
|
242
254
|
|
243
|
-
# [7]
|
255
|
+
# [7] SelectQuery ::= SelectClause DatasetClause* WhereClause SolutionModifier
|
256
|
+
#
|
257
|
+
# Inputs from `data` are merged into a Queryable object.
|
258
|
+
# Output to prod_data is `:query`.
|
244
259
|
production(:SelectQuery) do |input, data, callback|
|
245
260
|
query = merge_modifiers(data)
|
246
261
|
add_prod_datum :query, query
|
247
262
|
end
|
248
263
|
|
249
|
-
# [8]
|
264
|
+
# [8] SubSelect ::= SelectClause WhereClause SolutionModifier
|
265
|
+
#
|
266
|
+
# Inputs from `data` are merged into a Queryable object.
|
267
|
+
# Output to prod_data is `:query`.
|
250
268
|
production(:SubSelect) do |input, data, callback|
|
251
269
|
query = merge_modifiers(data)
|
252
270
|
add_prod_datum :query, query
|
253
271
|
end
|
254
272
|
|
255
|
-
# [9]
|
256
|
-
|
273
|
+
# [9] SelectClause ::= 'SELECT' ( 'DISTINCT' | 'REDUCED' )? ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
|
274
|
+
# [9.2] _SelectClause_2 ::= ( ( Var | ( '(' Expression 'AS' Var ')' ) )+ | '*' )
|
275
|
+
#
|
276
|
+
# Inputs from `data` are `:Expression` and `:Var`.
|
277
|
+
# Output to prod_data is `:Var`.
|
278
|
+
production(:_SelectClause_2) do |input, data, callback|
|
279
|
+
if data[:MultiplicativeExpression]
|
280
|
+
add_prod_datum :Var, %i(*)
|
281
|
+
else
|
282
|
+
add_prod_datum :extend, data[:extend]
|
283
|
+
add_prod_datum :Var, data[:Var]
|
284
|
+
end
|
285
|
+
end
|
257
286
|
# [9.8] _SelectClause_8 ::= ( '(' Expression 'AS' Var ')' )
|
287
|
+
#
|
288
|
+
# Inputs from `data` are `:Expression` and `:Var`.
|
289
|
+
# Output to prod_data is `:extend`.
|
258
290
|
production(:_SelectClause_8) do |input, data, callback|
|
259
291
|
add_prod_datum :extend, [data[:Expression].unshift(data[:Var].first)]
|
260
292
|
end
|
@@ -267,6 +299,10 @@ module SPARQL::Grammar
|
|
267
299
|
# 'WHERE' '{' TriplesTemplate? '}'
|
268
300
|
# SolutionModifier
|
269
301
|
# )
|
302
|
+
#
|
303
|
+
# Inputs from `data` are `:pattern` and optionally `:ConstructTemplate`.
|
304
|
+
# If there is no `:query` in data, one is constructed by creating a BGP from all values of `:pattern`.
|
305
|
+
# Output to prod_data is `:query` made by creating a Operator::Construct using any `:ConstructTemplate` or `:pattern` and the query with merged modifiers.
|
270
306
|
production(:ConstructQuery) do |input, data, callback|
|
271
307
|
data[:query] ||= [SPARQL::Algebra::Operator::BGP.new(*data[:pattern])]
|
272
308
|
query = merge_modifiers(data)
|
@@ -274,44 +310,64 @@ module SPARQL::Grammar
|
|
274
310
|
add_prod_datum :query, SPARQL::Algebra::Expression[:construct, template, query]
|
275
311
|
end
|
276
312
|
|
277
|
-
# [11]
|
278
|
-
#
|
313
|
+
# [11] DescribeQuery ::= 'DESCRIBE' ( VarOrIri+ | '*' )
|
314
|
+
# DatasetClause* WhereClause? SolutionModifier
|
315
|
+
#
|
316
|
+
# Inputs from `data` are merged into a Queryable object.
|
317
|
+
# Outputs are created using any `:VarOrIri` in data is used as an argument, along with the Queryable object to create an `Operator::Describe` object, which is added to `:query` in prod datea.
|
279
318
|
production(:DescribeQuery) do |input, data, callback|
|
280
319
|
query = merge_modifiers(data)
|
281
320
|
to_describe = Array(data[:VarOrIri])
|
282
321
|
add_prod_datum :query, SPARQL::Algebra::Expression[:describe, to_describe, query]
|
283
322
|
end
|
284
323
|
|
285
|
-
# [12]
|
324
|
+
# [12] AskQuery ::= 'ASK' DatasetClause* WhereClause
|
325
|
+
#
|
326
|
+
# Inputs from `data` are merged into a Queryable object.
|
327
|
+
# Output to prod_data is `:query` made by creating a Operator::Ask using the query with merged modifiers.
|
286
328
|
production(:AskQuery) do |input, data, callback|
|
287
329
|
query = merge_modifiers(data)
|
288
330
|
add_prod_datum :query, SPARQL::Algebra::Expression[:ask, query]
|
289
331
|
end
|
290
332
|
|
291
|
-
# [14]
|
333
|
+
# [14] DefaultGraphClause ::= SourceSelector
|
334
|
+
#
|
335
|
+
# Input from `data` is `:iri`.
|
336
|
+
# Output to prod_data is `:dataset` taken from `:iri`.
|
292
337
|
production(:DefaultGraphClause) do |input, data, callback|
|
293
338
|
add_prod_datum :dataset, data[:iri]
|
294
339
|
end
|
295
340
|
|
296
|
-
# [15]
|
341
|
+
# [15] NamedGraphClause ::= 'NAMED' SourceSelector
|
342
|
+
#
|
343
|
+
# Input from `data` is `:iri`.
|
344
|
+
# Output to prod_data is `:dataset` taken from `:iri`.
|
297
345
|
production(:NamedGraphClause) do |input, data, callback|
|
298
346
|
add_prod_data :dataset, [:named, data[:iri]]
|
299
347
|
end
|
300
348
|
|
301
|
-
# [18]
|
349
|
+
# [18] SolutionModifier ::= GroupClause? HavingClause? OrderClause? LimitOffsetClauses?
|
302
350
|
|
303
|
-
# [19]
|
351
|
+
# [19] GroupClause ::= 'GROUP' 'BY' GroupCondition+
|
352
|
+
#
|
353
|
+
# Input from `data` is `:GroupCondition`.
|
354
|
+
# Output to prod_data is `:group` taken from `:GroupCondition`.
|
304
355
|
production(:GroupClause) do |input, data, callback|
|
305
356
|
add_prod_data :group, data[:GroupCondition]
|
306
357
|
end
|
307
358
|
|
308
|
-
# [20]
|
309
|
-
#
|
359
|
+
# [20] GroupCondition ::= BuiltInCall | FunctionCall
|
360
|
+
# | '(' Expression ( 'AS' Var )? ')' | Var
|
361
|
+
#
|
362
|
+
# Output to prod_data is `:GroupCondition` taken from first value in data.
|
310
363
|
production(:GroupCondition) do |input, data, callback|
|
311
364
|
add_prod_datum :GroupCondition, data.values.first
|
312
365
|
end
|
313
366
|
|
314
367
|
# _GroupCondition_1 ::= '(' Expression ( 'AS' Var )? ')'
|
368
|
+
#
|
369
|
+
# Input from `data` is `:Expression` and optionally `:Var`.
|
370
|
+
# Output to prod_data is `:GroupCondition` taken from `:Expression` prepended by any value of `:Var`.
|
315
371
|
production(:_GroupCondition_1) do |input, data, callback|
|
316
372
|
cond = if data[:Var]
|
317
373
|
[data[:Expression].unshift(data[:Var].first)]
|
@@ -321,12 +377,18 @@ module SPARQL::Grammar
|
|
321
377
|
add_prod_datum(:GroupCondition, cond)
|
322
378
|
end
|
323
379
|
|
324
|
-
# [21]
|
380
|
+
# [21] HavingClause ::= 'HAVING' HavingCondition+
|
381
|
+
#
|
382
|
+
# Input from `data` is TODO.
|
383
|
+
# Output to prod_data is TODO.
|
325
384
|
production(:HavingClause) do |input, data, callback|
|
326
385
|
add_prod_datum(:having, data[:Constraint])
|
327
386
|
end
|
328
387
|
|
329
|
-
# [23]
|
388
|
+
# [23] OrderClause ::= 'ORDER' 'BY' OrderCondition+
|
389
|
+
#
|
390
|
+
# Input from `data` is TODO.
|
391
|
+
# Output to prod_data is TODO.
|
330
392
|
production(:OrderClause) do |input, data, callback|
|
331
393
|
if res = data[:OrderCondition]
|
332
394
|
res = [res] if [:asc, :desc].include?(res[0]) # Special case when there's only one condition and it's ASC (x) or DESC (x)
|
@@ -334,9 +396,12 @@ module SPARQL::Grammar
|
|
334
396
|
end
|
335
397
|
end
|
336
398
|
|
337
|
-
# [24]
|
338
|
-
#
|
339
|
-
#
|
399
|
+
# [24] OrderCondition ::= ( ( 'ASC' | 'DESC' )
|
400
|
+
# BrackettedExpression )
|
401
|
+
# | ( Constraint | Var )
|
402
|
+
#
|
403
|
+
# Input from `data` is TODO.
|
404
|
+
# Output to prod_data is TODO.
|
340
405
|
production(:OrderCondition) do |input, data, callback|
|
341
406
|
if data[:OrderDirection]
|
342
407
|
add_prod_datum(:OrderCondition, SPARQL::Algebra::Expression(data[:OrderDirection], *data[:Expression]))
|
@@ -345,8 +410,11 @@ module SPARQL::Grammar
|
|
345
410
|
end
|
346
411
|
end
|
347
412
|
|
348
|
-
# [25]
|
349
|
-
#
|
413
|
+
# [25] LimitOffsetClauses ::= LimitClause OffsetClause?
|
414
|
+
# | OffsetClause LimitClause?
|
415
|
+
#
|
416
|
+
# Input from `data` is TODO.
|
417
|
+
# Output to prod_data is TODO.
|
350
418
|
production(:LimitOffsetClauses) do |input, data, callback|
|
351
419
|
if data[:limit] || data[:offset]
|
352
420
|
limit = data[:limit] ? data[:limit].last : :_
|
@@ -355,17 +423,26 @@ module SPARQL::Grammar
|
|
355
423
|
end
|
356
424
|
end
|
357
425
|
|
358
|
-
# [26]
|
426
|
+
# [26] LimitClause ::= 'LIMIT' INTEGER
|
427
|
+
#
|
428
|
+
# Input from `data` is TODO.
|
429
|
+
# Output to prod_data is TODO.
|
359
430
|
production(:LimitClause) do |input, data, callback|
|
360
431
|
add_prod_datum(:limit, data[:literal])
|
361
432
|
end
|
362
433
|
|
363
|
-
# [27]
|
434
|
+
# [27] OffsetClause ::= 'OFFSET' INTEGER
|
435
|
+
#
|
436
|
+
# Input from `data` is TODO.
|
437
|
+
# Output to prod_data is TODO.
|
364
438
|
production(:OffsetClause) do |input, data, callback|
|
365
439
|
add_prod_datum(:offset, data[:literal])
|
366
440
|
end
|
367
441
|
|
368
|
-
# [28] ValuesClause
|
442
|
+
# [28] ValuesClause ::= ( 'VALUES' DataBlock )?
|
443
|
+
#
|
444
|
+
# Input from `data` is TODO.
|
445
|
+
# Output to prod_data is TODO.
|
369
446
|
production(:ValuesClause) do |input, data, callback|
|
370
447
|
debug("ValuesClause") {"vars: #{data[:Var].inspect}, row: #{data[:row].inspect}"}
|
371
448
|
if data[:row]
|
@@ -378,7 +455,10 @@ module SPARQL::Grammar
|
|
378
455
|
end
|
379
456
|
end
|
380
457
|
|
381
|
-
# [29]
|
458
|
+
# [29] Update ::= Prologue (Update1 (";" Update)? )?
|
459
|
+
#
|
460
|
+
# Input from `data` is TODO.
|
461
|
+
# Output to prod_data is TODO.
|
382
462
|
production(:Update) do |input, data, callback|
|
383
463
|
update = data[:update] || SPARQL::Algebra::Expression(:update)
|
384
464
|
|
@@ -396,6 +476,10 @@ module SPARQL::Grammar
|
|
396
476
|
# Don't use update operator twice, if we can help it
|
397
477
|
input[:update] = update
|
398
478
|
end
|
479
|
+
|
480
|
+
#
|
481
|
+
# Input from `data` is TODO.
|
482
|
+
# Output to prod_data is TODO.
|
399
483
|
production(:_Update_3) do |input, data, callback|
|
400
484
|
if data[:update]
|
401
485
|
if input[:update].is_a?(SPARQL::Algebra::Operator::Update)
|
@@ -407,12 +491,19 @@ module SPARQL::Grammar
|
|
407
491
|
end
|
408
492
|
end
|
409
493
|
|
410
|
-
# [30]
|
494
|
+
# [30] Update1 ::= Load | Clear | Drop | Add | Move | Copy
|
495
|
+
# | Create | InsertData | DeleteData | DeleteWhere | Modify
|
496
|
+
#
|
497
|
+
# Input from `data` is TODO.
|
498
|
+
# Output to prod_data is TODO.
|
411
499
|
production(:Update1) do |input, data, callback|
|
412
500
|
input[:update] = SPARQL::Algebra::Expression.for(:update, data[:update_op])
|
413
501
|
end
|
414
502
|
|
415
|
-
# [31]
|
503
|
+
# [31] Load ::= "LOAD" "SILENT"? iri ("INTO" GraphRef)?
|
504
|
+
#
|
505
|
+
# Input from `data` is TODO.
|
506
|
+
# Output to prod_data is TODO.
|
416
507
|
production(:Load) do |input, data, callback|
|
417
508
|
args = []
|
418
509
|
args << :silent if data[:silent]
|
@@ -420,11 +511,18 @@ module SPARQL::Grammar
|
|
420
511
|
args << data[:into] if data[:into]
|
421
512
|
input[:update_op] = SPARQL::Algebra::Expression(:load, *args)
|
422
513
|
end
|
514
|
+
|
515
|
+
#
|
516
|
+
# Input from `data` is TODO.
|
517
|
+
# Output to prod_data is TODO.
|
423
518
|
production(:_Load_2) do |input, data, callback|
|
424
519
|
input[:into] = data[:iri]
|
425
520
|
end
|
426
521
|
|
427
|
-
# [32]
|
522
|
+
# [32] Clear ::= "CLEAR" "SILENT"? GraphRefAll
|
523
|
+
#
|
524
|
+
# Input from `data` is TODO.
|
525
|
+
# Output to prod_data is TODO.
|
428
526
|
production(:Clear) do |input, data, callback|
|
429
527
|
args = []
|
430
528
|
%w(silent default named all).map(&:to_sym).each do |s|
|
@@ -434,7 +532,10 @@ module SPARQL::Grammar
|
|
434
532
|
input[:update_op] = SPARQL::Algebra::Expression(:clear, *args)
|
435
533
|
end
|
436
534
|
|
437
|
-
# [33]
|
535
|
+
# [33] Drop ::= "DROP" "SILENT"? GraphRefAll
|
536
|
+
#
|
537
|
+
# Input from `data` is TODO.
|
538
|
+
# Output to prod_data is TODO.
|
438
539
|
production(:Drop) do |input, data, callback|
|
439
540
|
args = []
|
440
541
|
%w(silent default named all).map(&:to_sym).each do |s|
|
@@ -444,7 +545,10 @@ module SPARQL::Grammar
|
|
444
545
|
input[:update_op] = SPARQL::Algebra::Expression(:drop, *args)
|
445
546
|
end
|
446
547
|
|
447
|
-
# [34]
|
548
|
+
# [34] Create ::= "CREATE" "SILENT"? GraphRef
|
549
|
+
#
|
550
|
+
# Input from `data` is TODO.
|
551
|
+
# Output to prod_data is TODO.
|
448
552
|
production(:Create) do |input, data, callback|
|
449
553
|
args = []
|
450
554
|
args << :silent if data[:silent]
|
@@ -452,7 +556,10 @@ module SPARQL::Grammar
|
|
452
556
|
input[:update_op] = SPARQL::Algebra::Expression(:create, *args)
|
453
557
|
end
|
454
558
|
|
455
|
-
# [35]
|
559
|
+
# [35] Add ::= "ADD" "SILENT"? GraphOrDefault "TO" GraphOrDefault
|
560
|
+
#
|
561
|
+
# Input from `data` are `GraphOrDefault` and optionally `:silent`.
|
562
|
+
# Output to input is `:update_op` with an `Operator::Add` object.
|
456
563
|
production(:Add) do |input, data, callback|
|
457
564
|
args = []
|
458
565
|
args << :silent if data[:silent]
|
@@ -460,7 +567,10 @@ module SPARQL::Grammar
|
|
460
567
|
input[:update_op] = SPARQL::Algebra::Expression(:add, *args)
|
461
568
|
end
|
462
569
|
|
463
|
-
# [36]
|
570
|
+
# [36] Move ::= "MOVE" "SILENT"? GraphOrDefault "TO" GraphOrDefault
|
571
|
+
#
|
572
|
+
# Input from `data` is TODO.
|
573
|
+
# Output to prod_data is TODO.
|
464
574
|
production(:Move) do |input, data, callback|
|
465
575
|
args = []
|
466
576
|
args << :silent if data[:silent]
|
@@ -468,7 +578,10 @@ module SPARQL::Grammar
|
|
468
578
|
input[:update_op] = SPARQL::Algebra::Expression(:move, *args)
|
469
579
|
end
|
470
580
|
|
471
|
-
# [37]
|
581
|
+
# [37] Copy ::= "COPY" "SILENT"? GraphOrDefault "TO" GraphOrDefault
|
582
|
+
#
|
583
|
+
# Input from `data` is TODO.
|
584
|
+
# Output to prod_data is TODO.
|
472
585
|
production(:Copy) do |input, data, callback|
|
473
586
|
args = []
|
474
587
|
args << :silent if data[:silent]
|
@@ -476,40 +589,59 @@ module SPARQL::Grammar
|
|
476
589
|
input[:update_op] = SPARQL::Algebra::Expression(:copy, *args)
|
477
590
|
end
|
478
591
|
|
479
|
-
# [38]
|
592
|
+
# [38] InsertData ::= "INSERT DATA" QuadData
|
480
593
|
start_production(:InsertData) do |input, data, callback|
|
481
594
|
# Freeze existing bnodes, so that if an attempt is made to re-use such a node, and error is raised
|
482
595
|
self.freeze_bnodes
|
483
596
|
end
|
597
|
+
|
598
|
+
#
|
599
|
+
# Input from `data` is TODO.
|
600
|
+
# Output to prod_data is TODO.
|
484
601
|
production(:InsertData) do |input, data, callback|
|
485
602
|
input[:update_op] = SPARQL::Algebra::Expression(:insertData, data[:pattern])
|
486
603
|
end
|
487
604
|
|
488
|
-
# [39]
|
605
|
+
# [39] DeleteData ::= "DELETE DATA" QuadData
|
489
606
|
start_production(:DeleteData) do |input, data, callback|
|
490
607
|
# 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.
|
491
608
|
self.gen_bnodes
|
492
609
|
end
|
610
|
+
#
|
611
|
+
# Input from `data` is TODO.
|
612
|
+
# Output to prod_data is TODO.
|
493
613
|
production(:DeleteData) do |input, data, callback|
|
494
614
|
raise Error, "DeleteData contains BNode operands: #{data[:pattern].to_sse}" if Array(data[:pattern]).any?(&:node?)
|
495
615
|
input[:update_op] = SPARQL::Algebra::Expression(:deleteData, Array(data[:pattern]))
|
496
616
|
end
|
497
617
|
|
498
|
-
# [40]
|
618
|
+
# [40] DeleteWhere ::= "DELETE WHERE" QuadPattern
|
499
619
|
start_production(:DeleteWhere) do |input, data, callback|
|
500
620
|
# 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.
|
501
621
|
self.gen_bnodes
|
502
622
|
end
|
623
|
+
|
624
|
+
#
|
625
|
+
# Input from `data` is TODO.
|
626
|
+
# Output to prod_data is TODO.
|
503
627
|
production(:DeleteWhere) do |input, data, callback|
|
504
628
|
raise Error, "DeleteWhere contains BNode operands: #{data[:pattern].to_sse}" if Array(data[:pattern]).any?(&:node?)
|
505
629
|
self.gen_bnodes(false)
|
506
630
|
input[:update_op] = SPARQL::Algebra::Expression(:deleteWhere, Array(data[:pattern]))
|
507
631
|
end
|
508
632
|
|
509
|
-
# [41]
|
633
|
+
# [41] Modify ::= ("WITH" iri)? ( DeleteClause InsertClause? | InsertClause) UsingClause* "WHERE" GroupGraphPattern
|
510
634
|
start_production(:Modify) do |input, data, callback|
|
511
635
|
self.clear_bnode_cache
|
512
636
|
end
|
637
|
+
|
638
|
+
#
|
639
|
+
# Input from `data` are:
|
640
|
+
# * `:query` from `GroupGraphPattern`,
|
641
|
+
# * optionally `:using` from `UsingClause`,
|
642
|
+
# * either `:delete` or `:insert` or both from `DeleteClause` and `InsertClause`, and
|
643
|
+
# * optionally `:iri` from `WITH`
|
644
|
+
# Output to input is `:update_op`.
|
513
645
|
production(:Modify) do |input, data, callback|
|
514
646
|
query = data[:query].first if data[:query]
|
515
647
|
query = SPARQL::Algebra::Expression.for(:using, data[:using], query) if data[:using]
|
@@ -518,36 +650,53 @@ module SPARQL::Grammar
|
|
518
650
|
input[:update_op] = SPARQL::Algebra::Expression(:modify, *operands)
|
519
651
|
end
|
520
652
|
|
521
|
-
# [42]
|
653
|
+
# [42] DeleteClause ::= "DELETE" QuadPattern
|
654
|
+
#
|
655
|
+
# 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.
|
522
656
|
start_production(:DeleteClause) do |input, data, callback|
|
523
|
-
# 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.
|
524
657
|
self.gen_bnodes
|
525
658
|
end
|
659
|
+
|
660
|
+
#
|
661
|
+
# Input from `data` is TODO.
|
662
|
+
# Output to prod_data is TODO.
|
526
663
|
production(:DeleteClause) do |input, data, callback|
|
527
664
|
raise Error, "DeleteClause contains BNode operands: #{Array(data[:pattern]).to_sse}" if Array(data[:pattern]).any?(&:node?)
|
528
665
|
self.gen_bnodes(false)
|
529
666
|
input[:delete] = SPARQL::Algebra::Expression(:delete, Array(data[:pattern]))
|
530
667
|
end
|
531
668
|
|
532
|
-
# [43]
|
669
|
+
# [43] InsertClause ::= "INSERT" QuadPattern
|
670
|
+
#
|
671
|
+
# Generate BNodes instead of non-distinguished variables.
|
533
672
|
start_production(:InsertClause) do |input, data, callback|
|
534
|
-
# Generate BNodes instead of non-distinguished variables.
|
535
673
|
self.gen_bnodes
|
536
674
|
end
|
675
|
+
|
676
|
+
#
|
677
|
+
# Input from `data` is TODO.
|
678
|
+
# Output to prod_data is TODO.
|
537
679
|
production(:InsertClause) do |input, data, callback|
|
538
680
|
self.gen_bnodes(false)
|
539
681
|
input[:insert] = SPARQL::Algebra::Expression(:insert, Array(data[:pattern]))
|
540
682
|
end
|
541
683
|
|
542
|
-
# [44]
|
684
|
+
# [44] UsingClause ::= "USING" ( iri | "NAMED" iri)
|
543
685
|
production(:UsingClause) do |input, data, callback|
|
544
686
|
add_prod_data(:using, data[:iri])
|
545
687
|
end
|
688
|
+
|
689
|
+
#
|
690
|
+
# Input from `data` is TODO.
|
691
|
+
# Output to prod_data is TODO.
|
546
692
|
production(:_UsingClause_2) do |input, data, callback|
|
547
693
|
input[:iri] = [:named, data[:iri]]
|
548
694
|
end
|
549
695
|
|
550
|
-
# [45]
|
696
|
+
# [45] GraphOrDefault ::= "DEFAULT" | "GRAPH"? iri
|
697
|
+
#
|
698
|
+
# Input from `data` is TODO.
|
699
|
+
# Output to prod_data is TODO.
|
551
700
|
production(:GraphOrDefault) do |input, data, callback|
|
552
701
|
if data[:default]
|
553
702
|
add_prod_datum(:GraphOrDefault, :default)
|
@@ -556,17 +705,24 @@ module SPARQL::Grammar
|
|
556
705
|
end
|
557
706
|
end
|
558
707
|
|
559
|
-
# [46]
|
708
|
+
# [46] GraphRef ::= "GRAPH" iri
|
709
|
+
#
|
710
|
+
# Input from `data` is TODO.
|
711
|
+
# Output to prod_data is TODO.
|
560
712
|
production(:GraphRef) do |input, data, callback|
|
561
713
|
input[:iri] = data[:iri]
|
562
714
|
end
|
563
715
|
|
564
|
-
# [49]
|
716
|
+
# [49] QuadData ::= "{" Quads "}"
|
565
717
|
# QuadData is like QuadPattern, except without BNodes
|
566
718
|
start_production(:QuadData) do |input, data, callback|
|
567
719
|
# Generate BNodes instead of non-distinguished variables
|
568
720
|
self.gen_bnodes
|
569
721
|
end
|
722
|
+
|
723
|
+
#
|
724
|
+
# Input from `data` is TODO.
|
725
|
+
# Output to prod_data is TODO.
|
570
726
|
production(:QuadData) do |input, data, callback|
|
571
727
|
# Transform using statements instead of patterns, and verify there are no variables
|
572
728
|
raise Error, "QuadData contains variable operands: #{Array(data[:pattern]).to_sse}" if Array(data[:pattern]).any?(&:variable?)
|
@@ -574,17 +730,26 @@ module SPARQL::Grammar
|
|
574
730
|
input[:pattern] = Array(data[:pattern])
|
575
731
|
end
|
576
732
|
|
577
|
-
# [51] QuadsNotTriples
|
733
|
+
# [51] QuadsNotTriples ::= "GRAPH" VarOrIri "{" TriplesTemplate? "}"
|
734
|
+
#
|
735
|
+
# Input from `data` is TODO.
|
736
|
+
# Output to prod_data is TODO.
|
578
737
|
production(:QuadsNotTriples) do |input, data, callback|
|
579
738
|
add_prod_datum(:pattern, [SPARQL::Algebra::Expression.for(:graph, data[:VarOrIri].last, Array(data[:pattern]))])
|
580
739
|
end
|
581
740
|
|
582
|
-
# [52]
|
741
|
+
# [52] TriplesTemplate ::= TriplesSameSubject ("." TriplesTemplate? )?
|
742
|
+
#
|
743
|
+
# Input from `data` is TODO.
|
744
|
+
# Output to prod_data is TODO.
|
583
745
|
production(:TriplesTemplate) do |input, data, callback|
|
584
746
|
add_prod_datum(:pattern, Array(data[:pattern]))
|
585
747
|
end
|
586
748
|
|
587
|
-
# [54]
|
749
|
+
# [54] GroupGraphPatternSub ::= TriplesBlock? (GraphPatternNotTriples "."? TriplesBlock? )*
|
750
|
+
#
|
751
|
+
# Input from `data` is TODO.
|
752
|
+
# Output to prod_data is TODO.
|
588
753
|
production(:GroupGraphPatternSub) do |input, data, callback|
|
589
754
|
debug("GroupGraphPatternSub") {"q #{data[:query].inspect}"}
|
590
755
|
|
@@ -608,48 +773,90 @@ module SPARQL::Grammar
|
|
608
773
|
add_prod_datum(:query, res)
|
609
774
|
end
|
610
775
|
|
611
|
-
# [55]
|
612
|
-
#
|
776
|
+
# [55] TriplesBlock ::= TriplesSameSubjectPath
|
777
|
+
# ( '.' TriplesBlock? )?
|
778
|
+
#
|
779
|
+
# Input from `data` is `:pattern` and `:query`. Input from input is also `:pattern`
|
780
|
+
# Patterns are sequenced and segmented into RDF::Query::Pattern and Operator::Path.
|
781
|
+
# Output to prod_data is `:query` either a BGP, a Join, a Sequence, or a combination of any of these. Any path element results in a Sequence.
|
613
782
|
production(:TriplesBlock) do |input, data, callback|
|
614
|
-
if
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
783
|
+
raise "TriplesBlock without pattern" if Array(data[:pattern]).empty?
|
784
|
+
|
785
|
+
lhs = Array(input.delete(:query)).first
|
786
|
+
|
787
|
+
# Sequence is existing patterns, plus new patterns, plus patterns from TriplesBlock?
|
788
|
+
sequence = []
|
789
|
+
unless lhs.nil? || lhs.empty?
|
790
|
+
if lhs.is_a?(SPARQL::Algebra::Operator::Sequence)
|
791
|
+
sequence += lhs.operands
|
792
|
+
else
|
793
|
+
sequence << lhs
|
794
|
+
end
|
795
|
+
end
|
796
|
+
|
797
|
+
sequence += data[:pattern]
|
798
|
+
|
799
|
+
# Append triples from ('.' TriplesBlock? )?
|
800
|
+
Array(data[:query]).each do |q|
|
801
|
+
if q.is_a?(SPARQL::Algebra::Operator::Sequence)
|
802
|
+
q.operands.each do |op|
|
803
|
+
sequence += op.respond_to?(:patterns) ? op.patterns : [op]
|
624
804
|
end
|
805
|
+
elsif q.respond_to?(:patterns)
|
806
|
+
sequence += q.patterns
|
807
|
+
else
|
808
|
+
sequence << q
|
625
809
|
end
|
626
|
-
|
627
|
-
|
810
|
+
end
|
811
|
+
|
812
|
+
# Merge runs of patterns into BGPs
|
813
|
+
patterns = []
|
814
|
+
new_seq = []
|
815
|
+
sequence.each do |element|
|
816
|
+
case element
|
817
|
+
when RDF::Query::Pattern
|
818
|
+
patterns << element
|
819
|
+
when RDF::Queryable
|
820
|
+
patterns += element.patterns
|
821
|
+
else
|
822
|
+
new_seq << SPARQL::Algebra::Expression.for(:bgp, *patterns) unless patterns.empty?
|
823
|
+
patterns = []
|
824
|
+
new_seq << element
|
628
825
|
end
|
629
|
-
|
630
|
-
|
826
|
+
end
|
827
|
+
new_seq << SPARQL::Algebra::Expression.for(:bgp, *patterns) unless patterns.empty?
|
828
|
+
|
829
|
+
# Optionally create a sequence, if there are enough gathered.
|
830
|
+
# FIXME: Join?
|
831
|
+
query = if new_seq.length > 1
|
832
|
+
if new_seq.any? {|e| e.is_a?(SPARQL::Algebra::Operator::Path)}
|
833
|
+
SPARQL::Algebra::Expression.for(:sequence, *new_seq)
|
834
|
+
else
|
835
|
+
SPARQL::Algebra::Expression.for(:join, *new_seq)
|
631
836
|
end
|
632
|
-
|
633
|
-
|
634
|
-
# Join query and path
|
635
|
-
add_prod_datum(:query, SPARQL::Algebra::Operator::Join.new(data[:path].first, data[:query].first))
|
636
|
-
elsif data[:path]
|
637
|
-
add_prod_datum(:query, data[:path])
|
837
|
+
else
|
838
|
+
new_seq.first
|
638
839
|
end
|
840
|
+
|
841
|
+
add_prod_datum(:query, query)
|
639
842
|
end
|
640
843
|
|
641
|
-
# [56]
|
642
|
-
#
|
643
|
-
#
|
644
|
-
#
|
645
|
-
#
|
646
|
-
#
|
844
|
+
# [56] GraphPatternNotTriples ::= GroupOrUnionGraphPattern
|
845
|
+
# | OptionalGraphPattern
|
846
|
+
# | MinusGraphPattern
|
847
|
+
# | GraphGraphPattern
|
848
|
+
# | ServiceGraphPattern
|
849
|
+
# | Filter | Bind
|
647
850
|
start_production(:GraphPatternNotTriples) do |input, data, callback|
|
648
851
|
# Modifies previous graph
|
649
|
-
data[:input_query] = input.delete(:query)
|
852
|
+
data[:input_query] = input.delete(:query)
|
650
853
|
end
|
854
|
+
|
855
|
+
#
|
856
|
+
# Input from `data` is TODO.
|
857
|
+
# Output to prod_data is TODO.
|
651
858
|
production(:GraphPatternNotTriples) do |input, data, callback|
|
652
|
-
lhs = Array(data[:input_query]).first
|
859
|
+
lhs = Array(data[:input_query]).first || SPARQL::Algebra::Operator::BGP.new
|
653
860
|
|
654
861
|
# Filter trickls up to GroupGraphPatternSub
|
655
862
|
add_prod_datum(:filter, data[:filter])
|
@@ -679,7 +886,10 @@ module SPARQL::Grammar
|
|
679
886
|
end
|
680
887
|
end
|
681
888
|
|
682
|
-
# [57]
|
889
|
+
# [57] OptionalGraphPattern ::= 'OPTIONAL' GroupGraphPattern
|
890
|
+
#
|
891
|
+
# Input from `data` is TODO.
|
892
|
+
# Output to prod_data is TODO.
|
683
893
|
production(:OptionalGraphPattern) do |input, data, callback|
|
684
894
|
expr = nil
|
685
895
|
query = data[:query] ? data[:query].first : SPARQL::Algebra::Operator::BGP.new
|
@@ -692,7 +902,10 @@ module SPARQL::Grammar
|
|
692
902
|
end
|
693
903
|
end
|
694
904
|
|
695
|
-
# [58]
|
905
|
+
# [58] GraphGraphPattern ::= 'GRAPH' VarOrIri GroupGraphPattern
|
906
|
+
#
|
907
|
+
# Input from `data` is TODO.
|
908
|
+
# Output to prod_data is TODO.
|
696
909
|
production(:GraphGraphPattern) do |input, data, callback|
|
697
910
|
name = (data[:VarOrIri]).last
|
698
911
|
bgp = data[:query] ? data[:query].first : SPARQL::Algebra::Operator::BGP.new
|
@@ -703,21 +916,43 @@ module SPARQL::Grammar
|
|
703
916
|
end
|
704
917
|
end
|
705
918
|
|
706
|
-
# [
|
919
|
+
# [59] ServiceGraphPattern ::= 'SERVICE' 'SILENT'? VarOrIri GroupGraphPattern
|
920
|
+
#
|
921
|
+
# Input from `data` is TODO.
|
922
|
+
# Output to prod_data is TODO.
|
923
|
+
production(:ServiceGraphPattern) do |input, data, callback|
|
924
|
+
args = []
|
925
|
+
args << :silent if data[:silent]
|
926
|
+
args << (data[:VarOrIri]).last
|
927
|
+
args << data.fetch(:query, [SPARQL::Algebra::Operator::BGP.new]).first
|
928
|
+
service = SPARQL::Algebra::Expression.for(:service, *args)
|
929
|
+
add_prod_data(:query, service)
|
930
|
+
end
|
931
|
+
|
932
|
+
# [60] Bind ::= 'BIND' '(' Expression 'AS' Var ')'
|
933
|
+
#
|
934
|
+
# Input from `data` is TODO.
|
935
|
+
# Output to prod_data is TODO.
|
707
936
|
production(:Bind) do |input, data, callback|
|
708
937
|
add_prod_datum :extend, [data[:Expression].unshift(data[:Var].first)]
|
709
938
|
end
|
710
939
|
|
711
|
-
# [61] InlineData
|
940
|
+
# [61] InlineData ::= 'VALUES' DataBlock
|
941
|
+
#
|
942
|
+
# Input from `data` is TODO.
|
943
|
+
# Output to prod_data is TODO.
|
712
944
|
production(:InlineData) do |input, data, callback|
|
713
945
|
debug("InlineData") {"vars: #{data[:Var].inspect}, row: #{data[:row].inspect}"}
|
714
946
|
add_prod_datum :query, SPARQL::Algebra::Expression.for(:table,
|
715
|
-
data[:Var].unshift(:vars),
|
947
|
+
Array(data[:Var]).unshift(:vars),
|
716
948
|
*data[:row]
|
717
949
|
)
|
718
950
|
end
|
719
951
|
|
720
|
-
# [63] InlineDataOneVar
|
952
|
+
# [63] InlineDataOneVar ::= Var '{' DataBlockValue* '}'
|
953
|
+
#
|
954
|
+
# Input from `data` is TODO.
|
955
|
+
# Output to prod_data is TODO.
|
721
956
|
production(:InlineDataOneVar) do |input, data, callback|
|
722
957
|
add_prod_datum :Var, data[:Var]
|
723
958
|
|
@@ -726,8 +961,11 @@ module SPARQL::Grammar
|
|
726
961
|
end
|
727
962
|
end
|
728
963
|
|
729
|
-
# [64] InlineDataFull
|
730
|
-
#
|
964
|
+
# [64] InlineDataFull ::= ( NIL | '(' Var* ')' )
|
965
|
+
# '{' ( '(' DataBlockValue* ')' | NIL )* '}'
|
966
|
+
#
|
967
|
+
# Input from `data` is TODO.
|
968
|
+
# Output to prod_data is TODO.
|
731
969
|
production(:InlineDataFull) do |input, data, callback|
|
732
970
|
vars = data[:Var]
|
733
971
|
add_prod_datum :Var, vars
|
@@ -745,7 +983,10 @@ module SPARQL::Grammar
|
|
745
983
|
end
|
746
984
|
end
|
747
985
|
|
748
|
-
# _InlineDataFull_6
|
986
|
+
# _InlineDataFull_6 ::= '(' '(' DataBlockValue* ')' | NIL ')'
|
987
|
+
#
|
988
|
+
# Input from `data` is TODO.
|
989
|
+
# Output to prod_data is TODO.
|
749
990
|
production(:_InlineDataFull_6) do |input, data, callback|
|
750
991
|
if data[:DataBlockValue]
|
751
992
|
add_prod_data :rowdata, data[:DataBlockValue].map {|v| v unless v == :undef}
|
@@ -754,19 +995,28 @@ module SPARQL::Grammar
|
|
754
995
|
end
|
755
996
|
end
|
756
997
|
|
757
|
-
# [65] DataBlockValue
|
998
|
+
# [65] DataBlockValue ::= QuotedTriple | iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF'
|
999
|
+
#
|
1000
|
+
# Input from `data` is TODO.
|
1001
|
+
# Output to prod_data is TODO.
|
758
1002
|
production(:DataBlockValue) do |input, data, callback|
|
759
1003
|
add_prod_datum :DataBlockValue, data.values.first
|
760
1004
|
end
|
761
1005
|
|
762
|
-
# [66] MinusGraphPattern
|
1006
|
+
# [66] MinusGraphPattern ::= 'MINUS' GroupGraphPattern
|
1007
|
+
#
|
1008
|
+
# Input from `data` is TODO.
|
1009
|
+
# Output to prod_data is TODO.
|
763
1010
|
production(:MinusGraphPattern) do |input, data, callback|
|
764
1011
|
query = data[:query] ? data[:query].first : SPARQL::Algebra::Operator::BGP.new
|
765
1012
|
add_prod_data(:minus, query)
|
766
1013
|
end
|
767
1014
|
|
768
|
-
# [67]
|
1015
|
+
# [67] GroupOrUnionGraphPattern ::= GroupGraphPattern
|
769
1016
|
# ( 'UNION' GroupGraphPattern )*
|
1017
|
+
#
|
1018
|
+
# Input from `data` is TODO.
|
1019
|
+
# Output to prod_data is TODO.
|
770
1020
|
production(:GroupOrUnionGraphPattern) do |input, data, callback|
|
771
1021
|
res = Array(data[:query]).first
|
772
1022
|
if data[:union]
|
@@ -782,17 +1032,26 @@ module SPARQL::Grammar
|
|
782
1032
|
end
|
783
1033
|
|
784
1034
|
# ( 'UNION' GroupGraphPattern )*
|
1035
|
+
#
|
1036
|
+
# Input from `data` is TODO.
|
1037
|
+
# Output to prod_data is TODO.
|
785
1038
|
production(:_GroupOrUnionGraphPattern_1) do |input, data, callback|
|
786
1039
|
input[:union] = Array(data[:union]).unshift(data[:query].first)
|
787
1040
|
end
|
788
1041
|
|
789
|
-
# [68]
|
1042
|
+
# [68] Filter ::= 'FILTER' Constraint
|
1043
|
+
#
|
1044
|
+
# Input from `data` is TODO.
|
1045
|
+
# Output to prod_data is TODO.
|
790
1046
|
production(:Filter) do |input, data, callback|
|
791
1047
|
add_prod_datum(:filter, data[:Constraint])
|
792
1048
|
end
|
793
1049
|
|
794
|
-
# [69]
|
1050
|
+
# [69] Constraint ::= BrackettedExpression | BuiltInCall
|
795
1051
|
# | FunctionCall
|
1052
|
+
#
|
1053
|
+
# Input from `data` is TODO.
|
1054
|
+
# Output to prod_data is TODO.
|
796
1055
|
production(:Constraint) do |input, data, callback|
|
797
1056
|
if data[:Expression]
|
798
1057
|
# Resolve expression to the point it is either an atom or an s-exp
|
@@ -804,28 +1063,41 @@ module SPARQL::Grammar
|
|
804
1063
|
end
|
805
1064
|
end
|
806
1065
|
|
807
|
-
# [70]
|
1066
|
+
# [70] FunctionCall ::= iri ArgList
|
1067
|
+
#
|
1068
|
+
# Input from `data` is TODO.
|
1069
|
+
# Output to prod_data is TODO.
|
808
1070
|
production(:FunctionCall) do |input, data, callback|
|
809
|
-
add_prod_data(:Function,
|
1071
|
+
add_prod_data(:Function, SPARQL::Algebra::Operator::FunctionCall.new(data[:iri], *data[:ArgList]))
|
810
1072
|
end
|
811
1073
|
|
812
|
-
# [71]
|
1074
|
+
# [71] ArgList ::= NIL
|
813
1075
|
# | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
|
1076
|
+
#
|
1077
|
+
# Input from `data` is TODO.
|
1078
|
+
# Output to prod_data is TODO.
|
814
1079
|
production(:ArgList) do |input, data, callback|
|
815
1080
|
data.values.each {|v| add_prod_datum(:ArgList, v)}
|
816
1081
|
end
|
817
1082
|
|
818
|
-
# [72]
|
1083
|
+
# [72] ExpressionList ::= NIL
|
819
1084
|
# | '(' Expression ( ',' Expression )* ')'
|
1085
|
+
#
|
1086
|
+
# Input from `data` is TODO.
|
1087
|
+
# Output to prod_data is TODO.
|
820
1088
|
production(:ExpressionList) do |input, data, callback|
|
821
1089
|
data.values.each {|v| add_prod_datum(:ExpressionList, v)}
|
822
1090
|
end
|
823
1091
|
|
824
|
-
# [73]
|
1092
|
+
# [73] ConstructTemplate ::= '{' ConstructTriples? '}'
|
825
1093
|
start_production(:ConstructTemplate) do |input, data, callback|
|
826
1094
|
# Generate BNodes instead of non-distinguished variables
|
827
1095
|
self.gen_bnodes
|
828
1096
|
end
|
1097
|
+
|
1098
|
+
#
|
1099
|
+
# Input from `data` is TODO.
|
1100
|
+
# Output to prod_data is TODO.
|
829
1101
|
production(:ConstructTemplate) do |input, data, callback|
|
830
1102
|
# Generate BNodes instead of non-distinguished variables
|
831
1103
|
self.gen_bnodes(false)
|
@@ -833,13 +1105,13 @@ module SPARQL::Grammar
|
|
833
1105
|
add_prod_datum(:ConstructTemplate, data[:ConstructTemplate])
|
834
1106
|
end
|
835
1107
|
|
836
|
-
# [75]
|
837
|
-
# |
|
1108
|
+
# [75] TriplesSameSubject ::= VarOrTermOrQuotedTP PropertyListNotEmpty
|
1109
|
+
# | TriplesNode PropertyList
|
838
1110
|
production(:TriplesSameSubject) do |input, data, callback|
|
839
1111
|
add_prod_datum(:pattern, data[:pattern])
|
840
1112
|
end
|
841
1113
|
|
842
|
-
# [77]
|
1114
|
+
# [77] PropertyListNotEmpty ::= Verb ObjectList
|
843
1115
|
# ( ';' ( Verb ObjectList )? )*
|
844
1116
|
start_production(:PropertyListNotEmpty) do |input, data, callback|
|
845
1117
|
subject = input[:VarOrTermOrQuotedTP] || input[:TriplesNode] || input[:GraphNode]
|
@@ -850,47 +1122,58 @@ module SPARQL::Grammar
|
|
850
1122
|
add_prod_datum(:pattern, data[:pattern])
|
851
1123
|
end
|
852
1124
|
|
853
|
-
# [78]
|
1125
|
+
# [78] Verb ::= VarOrIri | 'a'
|
1126
|
+
#
|
1127
|
+
# Output to input is `:Verb`.
|
854
1128
|
production(:Verb) do |input, data, callback|
|
855
1129
|
input[:Verb] = data.values.first
|
856
1130
|
end
|
857
1131
|
|
858
|
-
# [79]
|
1132
|
+
# [79] ObjectList ::= Object ( ',' Object )*
|
1133
|
+
#
|
1134
|
+
# Adds `:Subject`, `:Verb`, and `:VerbPath` from input to data with error checking.
|
859
1135
|
start_production(:ObjectList) do |input, data, callback|
|
860
1136
|
# Called after Verb. The prod_data stack should have Subject and Verb elements
|
861
|
-
data[:Subject] =
|
862
|
-
error(nil, "Expected Subject", production: :ObjectList) if !
|
863
|
-
error(nil, "Expected Verb", production: :ObjectList) if !(
|
864
|
-
data[:Verb] =
|
865
|
-
data[:VerbPath] =
|
1137
|
+
data[:Subject] = input[:Subject]
|
1138
|
+
error(nil, "Expected Subject", production: :ObjectList) if !input[:Subject] && validate?
|
1139
|
+
error(nil, "Expected Verb", production: :ObjectList) if !(input[:Verb] || input[:VerbPath]) && validate?
|
1140
|
+
data[:Verb] = input[:Verb] if input[:Verb]
|
1141
|
+
data[:VerbPath] = input[:VerbPath] if input[:VerbPath]
|
866
1142
|
end
|
867
1143
|
production(:ObjectList) do |input, data, callback|
|
868
1144
|
add_prod_datum(:pattern, data[:pattern])
|
869
|
-
add_prod_datum(:path, data[:path])
|
870
1145
|
end
|
871
1146
|
|
872
|
-
# [80]
|
1147
|
+
# [80] Object ::= GraphNode AnnotationPattern?
|
1148
|
+
#
|
1149
|
+
# Sets `:Subject` and `:Verb` in data from input.
|
873
1150
|
start_production(:Object) do |input, data, callback|
|
874
1151
|
data[:Subject] = Array(input[:Subject]).first
|
875
1152
|
data[:Verb] = Array(input[:Verb]).first
|
876
1153
|
end
|
1154
|
+
|
1155
|
+
#
|
1156
|
+
# Input from `data` is `:Subject`, `:Verb` or `:VerbPath`, and `GraphNode`.
|
1157
|
+
# Output to prod_data is `:pattern`, either from `:Subject`, `:Verb`, and `GraphNode` or a new path if `VerbPath` is present instead of `Verb`.
|
877
1158
|
production(:Object) do |input, data, callback|
|
878
1159
|
object = data[:GraphNode]
|
879
1160
|
add_prod_datum(:pattern, data[:pattern])
|
880
1161
|
if object
|
881
|
-
if
|
882
|
-
add_pattern(:Object, subject:
|
883
|
-
elsif
|
884
|
-
add_prod_datum(:
|
1162
|
+
if input[:Verb]
|
1163
|
+
add_pattern(:Object, subject: input[:Subject], predicate: input[:Verb], object: object)
|
1164
|
+
elsif input[:VerbPath]
|
1165
|
+
add_prod_datum(:pattern,
|
885
1166
|
SPARQL::Algebra::Expression(:path,
|
886
|
-
|
887
|
-
|
1167
|
+
input[:Subject].first,
|
1168
|
+
input[:VerbPath],
|
888
1169
|
object.first))
|
889
1170
|
end
|
890
1171
|
end
|
891
1172
|
end
|
1173
|
+
|
1174
|
+
# AnnotationPattern?
|
892
1175
|
start_production(:_Object_1) do |input, data, callback|
|
893
|
-
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first)
|
1176
|
+
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first, quoted: true)
|
894
1177
|
error("ObjectPath", "Expected Verb",
|
895
1178
|
production: :_Object_1) unless input[:Verb]
|
896
1179
|
data[:TriplesNode] = [pattern]
|
@@ -899,13 +1182,17 @@ module SPARQL::Grammar
|
|
899
1182
|
add_prod_datum(:pattern, data[:pattern])
|
900
1183
|
end
|
901
1184
|
|
902
|
-
# [81]
|
1185
|
+
# [81] TriplesSameSubjectPath ::= VarOrTermOrQuotedTP PropertyListPathNotEmpty | TriplesNode PropertyListPath
|
903
1186
|
production(:TriplesSameSubjectPath) do |input, data, callback|
|
904
1187
|
add_prod_datum(:pattern, data[:pattern])
|
905
|
-
add_prod_datum(:path, data[:path])
|
906
1188
|
end
|
907
1189
|
|
908
|
-
# [83]
|
1190
|
+
# [83] PropertyListPathNotEmpty ::= ( VerbPath | VerbSimple ) ObjectList
|
1191
|
+
# ( ';' ( ( VerbPath | VerbSimple )
|
1192
|
+
# ObjectList )? )*
|
1193
|
+
#
|
1194
|
+
# Sets `:Subject` in data from either `:VarOrTermOrQuotedTP`,
|
1195
|
+
# `:TriplesNode`, or `:GraphNode` in input with error checking.
|
909
1196
|
start_production(:PropertyListPathNotEmpty) do |input, data, callback|
|
910
1197
|
subject = input[:VarOrTermOrQuotedTP] || input[:TriplesNode] || input[:GraphNode]
|
911
1198
|
error(nil, "Expected VarOrTermOrQuotedTP, got nothing", production: :PropertyListPathNotEmpty) if validate? && !subject
|
@@ -913,10 +1200,13 @@ module SPARQL::Grammar
|
|
913
1200
|
end
|
914
1201
|
production(:PropertyListPathNotEmpty) do |input, data, callback|
|
915
1202
|
add_prod_datum(:pattern, data[:pattern])
|
916
|
-
add_prod_datum(:path, data[:path])
|
917
1203
|
end
|
918
1204
|
|
919
|
-
# [84]
|
1205
|
+
# [84] VerbPath ::= Path
|
1206
|
+
#
|
1207
|
+
# Input from `data` is `:Path` or `:iri`.
|
1208
|
+
# Output to prod_data is either `:VerbPath` or `:Verb`.
|
1209
|
+
# If `:VerbPath` is added, then any existing `:Verb` is removed.
|
920
1210
|
production(:VerbPath) do |input, data, callback|
|
921
1211
|
if data[:Path]
|
922
1212
|
input.delete(:Verb)
|
@@ -926,70 +1216,80 @@ module SPARQL::Grammar
|
|
926
1216
|
end
|
927
1217
|
end
|
928
1218
|
|
929
|
-
# [85]
|
1219
|
+
# [85] VerbSimple ::= Var
|
930
1220
|
production(:VerbSimple) do |input, data, callback|
|
931
1221
|
input[:Verb] = data.values.flatten.first
|
932
1222
|
end
|
933
1223
|
|
934
|
-
# [86]
|
1224
|
+
# [86] ObjectListPath ::= ObjectPath ("," ObjectPath)*
|
1225
|
+
#
|
1226
|
+
# Addes `:Subject` from input to data with error checking.
|
1227
|
+
# Also adds either `:Verb` or `:VerbPath`
|
935
1228
|
start_production(:ObjectListPath) do |input, data, callback|
|
936
1229
|
# Called after Verb. The prod_data stack should have Subject and Verb elements
|
937
|
-
data[:Subject] =
|
938
|
-
error(nil, "Expected Subject", production: :ObjectListPath) if !
|
939
|
-
error(nil, "Expected Verb", production: :ObjectListPath) if !(
|
940
|
-
if
|
941
|
-
data[:Verb] = Array(
|
1230
|
+
data[:Subject] = input[:Subject]
|
1231
|
+
error(nil, "Expected Subject", production: :ObjectListPath) if !input[:Subject] && validate?
|
1232
|
+
error(nil, "Expected Verb", production: :ObjectListPath) if !(input[:Verb] || input[:VerbPath]) && validate?
|
1233
|
+
if input[:Verb]
|
1234
|
+
data[:Verb] = Array(input[:Verb]).last
|
942
1235
|
else
|
943
|
-
data[:VerbPath] =
|
1236
|
+
data[:VerbPath] = input[:VerbPath]
|
944
1237
|
end
|
945
1238
|
end
|
1239
|
+
|
1240
|
+
#
|
1241
|
+
# Input from `data` is TODO.
|
1242
|
+
# Output to prod_data is TODO.
|
946
1243
|
production(:ObjectListPath) do |input, data, callback|
|
947
1244
|
add_prod_datum(:pattern, data[:pattern])
|
948
|
-
add_prod_datum(:path, data[:path])
|
949
1245
|
end
|
950
1246
|
|
951
|
-
# [87]
|
1247
|
+
# [87] ObjectPath ::= GraphNodePath AnnotationPatternPath?
|
1248
|
+
#
|
1249
|
+
# Adds `:Subject` and `:Verb` to data from input.
|
952
1250
|
start_production(:ObjectPath) do |input, data, callback|
|
953
1251
|
data[:Subject] = Array(input[:Subject]).first
|
954
1252
|
data[:Verb] = Array(input[:Verb]).first
|
955
1253
|
end
|
1254
|
+
|
1255
|
+
# Input from `data` `:Subject`, either `:Verb` or `:VerbPath`, `:GraphNode` from GraphNodePath is used as the object, and `:pattern`.
|
1256
|
+
# Output to prod_data is either a pattern including `:Subject`, `:Verb` and `:GraphNode`, or an `Object::Path` using `:VerbPath` instead of `:Verb`. Also, any `:pattern` from data is sent to prod_ddata
|
956
1257
|
production(:ObjectPath) do |input, data, callback|
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
add_prod_datum(:path, data[:path])
|
968
|
-
else
|
969
|
-
add_pattern(:Object, subject: prod_data[:Subject], predicate: prod_data[:Verb], object: object)
|
970
|
-
add_prod_datum(:pattern, data[:pattern])
|
971
|
-
end
|
972
|
-
else
|
973
|
-
add_prod_datum(:path,
|
974
|
-
SPARQL::Algebra::Expression(:path,
|
975
|
-
Array(prod_data[:Subject]).first,
|
976
|
-
prod_data[:VerbPath],
|
977
|
-
object.first))
|
978
|
-
end
|
1258
|
+
subject = data[:Subject]
|
1259
|
+
verb = data[:Verb]
|
1260
|
+
object = Array(data[:GraphNode]).first
|
1261
|
+
if verb
|
1262
|
+
add_prod_datum(:pattern, RDF::Query::Pattern.new(subject, verb, object))
|
1263
|
+
else
|
1264
|
+
add_prod_datum(:pattern, SPARQL::Algebra::Expression(:path,
|
1265
|
+
subject,
|
1266
|
+
input[:VerbPath],
|
1267
|
+
object))
|
979
1268
|
end
|
1269
|
+
add_prod_datum(:pattern, data[:pattern])
|
980
1270
|
end
|
1271
|
+
|
1272
|
+
# AnnotationPatternPath?
|
1273
|
+
#
|
1274
|
+
# Create `:TriplesNode` in data used as the subject of annotations
|
981
1275
|
start_production(:_ObjectPath_1) do |input, data, callback|
|
982
|
-
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first)
|
983
1276
|
error("ObjectPath", "Expected Verb",
|
984
1277
|
production: :_ObjectPath_1) unless input[:Verb]
|
1278
|
+
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first, quoted: true)
|
985
1279
|
data[:TriplesNode] = [pattern]
|
986
1280
|
end
|
1281
|
+
|
1282
|
+
#
|
1283
|
+
# Input from `data` is `:pattern`.
|
1284
|
+
# Output to prod_data is `:pattern`.
|
987
1285
|
production(:_ObjectPath_1) do |input, data, callback|
|
988
1286
|
add_prod_datum(:pattern, data[:pattern])
|
989
1287
|
end
|
990
1288
|
|
991
|
-
# [88]
|
992
|
-
#
|
1289
|
+
# [88] Path ::= PathAlternative
|
1290
|
+
#
|
1291
|
+
# Input from data is `:Path`
|
1292
|
+
# Output to input is either `:iri` or `:Path`, depending on if `:Path` is an IRI or not.
|
993
1293
|
production(:Path) do |input, data, callback|
|
994
1294
|
if data[:Path].is_a?(RDF::URI)
|
995
1295
|
input[:iri] = data[:Path]
|
@@ -998,7 +1298,10 @@ module SPARQL::Grammar
|
|
998
1298
|
end
|
999
1299
|
end
|
1000
1300
|
|
1001
|
-
# [89]
|
1301
|
+
# [89] PathAlternative ::= PathSequence ( '|' PathSequence )*
|
1302
|
+
#
|
1303
|
+
# Input from `data` is `:PathSequence` containing one or more path objects.
|
1304
|
+
# Output to prod_data is `:Path`, containing a nested sequence of `Algebra::Alt` connecting the elements from `:PathSequence`, unless there is only one such element, in which case it is added directly.
|
1002
1305
|
production(:PathAlternative) do |input, data, callback|
|
1003
1306
|
lhs = Array(data[:PathSequence]).shift
|
1004
1307
|
while data[:PathSequence] && !data[:PathSequence].empty?
|
@@ -1009,11 +1312,17 @@ module SPARQL::Grammar
|
|
1009
1312
|
end
|
1010
1313
|
|
1011
1314
|
# ( '|' PathSequence )*
|
1315
|
+
#
|
1316
|
+
# Input from `data` is `:PathSequence`.
|
1317
|
+
# Output to prod_data is `:PathSequence` which is accumulated.
|
1012
1318
|
production(:_PathAlternative_1) do |input, data, callback|
|
1013
1319
|
input[:PathSequence] += data[:PathSequence]
|
1014
1320
|
end
|
1015
1321
|
|
1016
|
-
# [90]
|
1322
|
+
# [90] PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )*
|
1323
|
+
#
|
1324
|
+
# Input from `data` is `:PathSequence` containing one or more path objects.
|
1325
|
+
# Output to prod_data is `:Path`, containing a nested sequence of `Algebra::Seq` connecting the elements from `:PathSequence`, unless there is only one such element, in which case it is added directly.
|
1017
1326
|
production(:PathSequence) do |input, data, callback|
|
1018
1327
|
lhs = data[:PathEltOrInverse].shift
|
1019
1328
|
while data[:PathEltOrInverse] && !data[:PathEltOrInverse].empty?
|
@@ -1024,22 +1333,39 @@ module SPARQL::Grammar
|
|
1024
1333
|
end
|
1025
1334
|
|
1026
1335
|
# ( '/' PathEltOrInverse )*
|
1336
|
+
#
|
1337
|
+
# Input from `data` is `:PathSequence`.
|
1338
|
+
# Output to prod_data is `:PathSequence` which is accumulated.
|
1027
1339
|
production(:_PathSequence_1) do |input, data, callback|
|
1028
1340
|
input[:PathEltOrInverse] += data[:PathEltOrInverse]
|
1029
1341
|
end
|
1030
1342
|
|
1031
|
-
# [91]
|
1343
|
+
# [91] PathElt ::= PathPrimary PathMod?
|
1344
|
+
#
|
1345
|
+
# Input from `data` is `:PathMod` and `:PathPrimary`.
|
1346
|
+
# Output to prod_data is `:Path` a possibly modified `:PathPrimary`.
|
1032
1347
|
production(:PathElt) do |input, data, callback|
|
1033
1348
|
path_mod = data.delete(:PathMod) if data.has_key?(:PathMod)
|
1034
1349
|
path_mod ||= data.delete(:MultiplicativeExpression) if data.has_key?(:MultiplicativeExpression)
|
1035
1350
|
path_mod = path_mod.first if path_mod
|
1036
1351
|
|
1037
|
-
res =
|
1038
|
-
|
1352
|
+
res = case path_mod
|
1353
|
+
when SPARQL::Algebra::Expression
|
1354
|
+
# Path range :p{m,n}
|
1355
|
+
path_mod.operands[2] = data[:PathPrimary]
|
1356
|
+
path_mod
|
1357
|
+
when nil
|
1358
|
+
data[:PathPrimary]
|
1359
|
+
else
|
1360
|
+
SPARQL::Algebra::Expression("path#{path_mod}", data[:PathPrimary])
|
1361
|
+
end
|
1039
1362
|
input[:Path] = res
|
1040
1363
|
end
|
1041
1364
|
|
1042
|
-
# [92]
|
1365
|
+
# [92] PathEltOrInverse ::= PathElt | '^' PathElt
|
1366
|
+
#
|
1367
|
+
# Input from `data` is `:reverse` and `:Path`.
|
1368
|
+
# Output to prod_data is `:Path` a possibly reversed `:Path`.
|
1043
1369
|
production(:PathEltOrInverse) do |input, data, callback|
|
1044
1370
|
res = if data[:reverse]
|
1045
1371
|
SPARQL::Algebra::Expression(:reverse, data[:Path])
|
@@ -1049,7 +1375,44 @@ module SPARQL::Grammar
|
|
1049
1375
|
input[:PathEltOrInverse] = [res]
|
1050
1376
|
end
|
1051
1377
|
|
1052
|
-
# [
|
1378
|
+
# [93] PathMod ::= '*' | '?' | '+' | '{' INTEGER? (',' INTEGER?)? '}'
|
1379
|
+
# '{' INTEGER? (',' INTEGER?)? '}'
|
1380
|
+
start_production(:_PathMod_1) do |input, data, callback|
|
1381
|
+
data[:pathRange] = [nil]
|
1382
|
+
end
|
1383
|
+
production(:_PathMod_1) do |input, data, callback|
|
1384
|
+
raise Error, "expect property range to have integral elements" if data[:pathRange].all?(&:nil?)
|
1385
|
+
min, max = data[:pathRange]
|
1386
|
+
min ||= 0
|
1387
|
+
max = min if data[:pathRange].length == 1
|
1388
|
+
max ||= :*
|
1389
|
+
|
1390
|
+
# Last operand added in :PathElt
|
1391
|
+
add_prod_data(:PathMod, SPARQL::Algebra::Expression(:pathRange, min, max, RDF.nil))
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
# INTEGER?
|
1395
|
+
production(:_PathMod_2) do |input, data, callback|
|
1396
|
+
input[:pathRange][0] = data[:literal].object
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
# (',' INTEGER?)
|
1400
|
+
start_production(:_PathMod_4) do |input, data, callback|
|
1401
|
+
data[:pathRange] = [nil, nil]
|
1402
|
+
end
|
1403
|
+
production(:_PathMod_4) do |input, data, callback|
|
1404
|
+
input[:pathRange][1] ||= data.fetch(:pathRange, [0, nil])[1]
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
# INTEGER?
|
1408
|
+
production(:_PathMod_5) do |input, data, callback|
|
1409
|
+
input[:pathRange][1] = data[:literal].object
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
# [94] PathPrimary ::= iri | 'a' | '!' PathNegatedPropertySet | '(' Path ')'
|
1413
|
+
#
|
1414
|
+
# Input from `data` is one of `:Verb`, `:iri`, `:PathNegatedPropertySet`, or `:Path`.
|
1415
|
+
# Output to prod_data is `:PathPrimary`.
|
1053
1416
|
production(:PathPrimary) do |input, data, callback|
|
1054
1417
|
input[:PathPrimary] = case
|
1055
1418
|
when data[:Verb] then data[:Verb]
|
@@ -1059,90 +1422,128 @@ module SPARQL::Grammar
|
|
1059
1422
|
end
|
1060
1423
|
end
|
1061
1424
|
|
1062
|
-
# [95]
|
1425
|
+
# [95] PathNegatedPropertySet ::= PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')'
|
1426
|
+
#
|
1427
|
+
# Input from `data` is TODO.
|
1428
|
+
# Output to prod_data is TODO.
|
1063
1429
|
production(:PathNegatedPropertySet) do |input, data, callback|
|
1064
1430
|
input[:Path] = SPARQL::Algebra::Expression(:notoneof, *Array(data[:Path]))
|
1065
1431
|
end
|
1066
1432
|
|
1067
1433
|
# ( '|' PathOneInPropertySet )* )?
|
1434
|
+
#
|
1435
|
+
# Input from `data` is TODO.
|
1436
|
+
# Output to prod_data is TODO.
|
1068
1437
|
production(:_PathNegatedPropertySet_4) do |input, data, callback|
|
1069
1438
|
add_prod_datum(:Path, data[:Path])
|
1070
1439
|
end
|
1071
1440
|
|
1072
|
-
# [96]
|
1441
|
+
# [96] PathOneInPropertySet ::= iri | 'a' | '^' ( iri | 'a' )
|
1442
|
+
#
|
1443
|
+
# Input from `data` is TODO.
|
1444
|
+
# Output to prod_data is TODO.
|
1073
1445
|
production(:PathOneInPropertySet) do |input, data, callback|
|
1074
1446
|
term = (Array(data[:iri]) || data[:Verb]).first
|
1075
1447
|
term = SPARQL::Algebra::Expression(:reverse, term) if data[:reverse]
|
1076
1448
|
input[:Path] = [term]
|
1077
1449
|
end
|
1078
1450
|
|
1079
|
-
# [98]
|
1451
|
+
# [98] TriplesNode ::= Collection | BlankNodePropertyList
|
1080
1452
|
start_production(:TriplesNode) do |input, data, callback|
|
1081
1453
|
# Called after Verb. The prod_data stack should have Subject and Verb elements
|
1082
1454
|
data[:TriplesNode] = bnode
|
1083
1455
|
end
|
1456
|
+
|
1457
|
+
#
|
1458
|
+
# Input from `data` is TODO.
|
1459
|
+
# Output to prod_data is TODO.
|
1084
1460
|
production(:TriplesNode) do |input, data, callback|
|
1085
1461
|
add_prod_datum(:pattern, data[:pattern])
|
1086
1462
|
add_prod_datum(:TriplesNode, data[:TriplesNode])
|
1087
1463
|
end
|
1088
1464
|
|
1089
|
-
# [100]
|
1465
|
+
# [100] TriplesNodePath ::= CollectionPath | BlankNodePropertyListPath
|
1090
1466
|
start_production(:TriplesNodePath) do |input, data, callback|
|
1091
1467
|
# Called after Verb. The prod_data stack should have Subject and Verb elements
|
1092
1468
|
data[:TriplesNode] = bnode
|
1093
1469
|
end
|
1470
|
+
|
1471
|
+
#
|
1472
|
+
# Input from `data` is TODO.
|
1473
|
+
# Output to prod_data is TODO.
|
1094
1474
|
production(:TriplesNodePath) do |input, data, callback|
|
1095
1475
|
add_prod_datum(:pattern, data[:pattern])
|
1096
|
-
add_prod_datum(:path, data[:path])
|
1097
1476
|
add_prod_datum(:TriplesNode, data[:TriplesNode])
|
1098
1477
|
end
|
1099
1478
|
|
1100
|
-
# [102]
|
1479
|
+
# [102] Collection ::= '(' GraphNode+ ')'
|
1101
1480
|
start_production(:Collection) do |input, data, callback|
|
1102
1481
|
# Tells the TriplesNode production to collect and not generate statements
|
1103
|
-
data[:Collection] =
|
1482
|
+
data[:Collection] = input[:TriplesNode]
|
1104
1483
|
end
|
1484
|
+
|
1485
|
+
#
|
1486
|
+
# Input from `data` is TODO.
|
1487
|
+
# Output to prod_data is TODO.
|
1105
1488
|
production(:Collection) do |input, data, callback|
|
1106
1489
|
expand_collection(data)
|
1107
1490
|
end
|
1108
1491
|
|
1109
|
-
# [103]
|
1492
|
+
# [103] CollectionPath ::= "(" GraphNodePath+ ")"
|
1110
1493
|
start_production(:CollectionPath) do |input, data, callback|
|
1111
1494
|
# Tells the TriplesNode production to collect and not generate statements
|
1112
|
-
data[:Collection] =
|
1495
|
+
data[:Collection] = input[:TriplesNode]
|
1113
1496
|
end
|
1497
|
+
|
1498
|
+
#
|
1499
|
+
# Input from `data` is TODO.
|
1500
|
+
# Output to prod_data is TODO.
|
1114
1501
|
production(:CollectionPath) do |input, data, callback|
|
1115
1502
|
expand_collection(data)
|
1116
|
-
add_prod_datum(:path, data[:path])
|
1117
1503
|
end
|
1118
1504
|
|
1119
|
-
# [104]
|
1505
|
+
# [104] GraphNode ::= VarOrTermOrQuotedTP | TriplesNode
|
1506
|
+
#
|
1507
|
+
# Input from `data` is TODO.
|
1508
|
+
# Output to prod_data is TODO.
|
1120
1509
|
production(:GraphNode) do |input, data, callback|
|
1121
1510
|
term = data[:VarOrTermOrQuotedTP] || data[:TriplesNode]
|
1122
1511
|
add_prod_datum(:pattern, data[:pattern])
|
1123
1512
|
add_prod_datum(:GraphNode, term)
|
1124
1513
|
end
|
1125
1514
|
|
1126
|
-
# [105]
|
1515
|
+
# [105] GraphNodePath ::= VarOrTermOrQuotedTP | TriplesNodePath
|
1516
|
+
#
|
1517
|
+
# Input from `data` is either `:VarOrTermOrQUotedTP` or `:TriplesNode`.
|
1518
|
+
# Additionally, `:pattern`. Also, `:pattern` and `:path`.
|
1519
|
+
# Output to prod_data is `:GraphNode`, along with any `:path` and `:pattern`.
|
1127
1520
|
production(:GraphNodePath) do |input, data, callback|
|
1128
1521
|
term = data[:VarOrTermOrQuotedTP] || data[:TriplesNode]
|
1129
1522
|
add_prod_datum(:pattern, data[:pattern])
|
1130
|
-
add_prod_datum(:path, data[:path])
|
1131
1523
|
add_prod_datum(:GraphNode, term)
|
1132
1524
|
end
|
1133
1525
|
|
1134
|
-
# [106s]
|
1526
|
+
# [106s] VarOrTermOrQuotedTP ::= Var | GraphTerm | QuotedTP
|
1527
|
+
#
|
1528
|
+
# Input from `data` is TODO.
|
1529
|
+
# Output to prod_data is TODO.
|
1135
1530
|
production(:VarOrTermOrQuotedTP) do |input, data, callback|
|
1136
1531
|
data.values.each {|v| add_prod_datum(:VarOrTermOrQuotedTP, v)}
|
1137
1532
|
end
|
1138
1533
|
|
1139
|
-
# [107]
|
1534
|
+
# [107] VarOrIri ::= Var | iri
|
1535
|
+
#
|
1536
|
+
# Input from `data` is TODO.
|
1537
|
+
# Output to prod_data is TODO.
|
1140
1538
|
production(:VarOrIri) do |input, data, callback|
|
1141
1539
|
data.values.each {|v| add_prod_datum(:VarOrIri, v)}
|
1142
1540
|
end
|
1143
1541
|
|
1144
|
-
# [109]
|
1145
|
-
# |
|
1542
|
+
# [109] GraphTerm ::= iri | RDFLiteral | NumericLiteral
|
1543
|
+
# | BooleanLiteral | BlankNode | NIL
|
1544
|
+
#
|
1545
|
+
# Input from `data` is one of `:iri`, `:literal`, `:BlankNode`, or `:NIL`.
|
1546
|
+
# Output to prod_data is `:GraphTerm` created from the data.
|
1146
1547
|
production(:GraphTerm) do |input, data, callback|
|
1147
1548
|
add_prod_datum(:GraphTerm,
|
1148
1549
|
data[:iri] ||
|
@@ -1151,42 +1552,60 @@ module SPARQL::Grammar
|
|
1151
1552
|
data[:NIL])
|
1152
1553
|
end
|
1153
1554
|
|
1154
|
-
# [110]
|
1555
|
+
# [110] Expression ::= ConditionalOrExpression
|
1556
|
+
#
|
1557
|
+
# Input from `data` is TODO.
|
1558
|
+
# Output to prod_data is TODO.
|
1155
1559
|
production(:Expression) do |input, data, callback|
|
1156
1560
|
add_prod_datum(:Expression, data[:Expression])
|
1157
1561
|
end
|
1158
1562
|
|
1159
|
-
# [111]
|
1160
|
-
#
|
1563
|
+
# [111] ConditionalOrExpression ::= ConditionalAndExpression
|
1564
|
+
# ( '||' ConditionalAndExpression )*
|
1565
|
+
#
|
1566
|
+
# Input from `data` is TODO.
|
1567
|
+
# Output to prod_data is TODO.
|
1161
1568
|
production(:ConditionalOrExpression) do |input, data, callback|
|
1162
1569
|
add_operator_expressions(:_OR, data)
|
1163
1570
|
end
|
1164
1571
|
|
1165
1572
|
# ( '||' ConditionalAndExpression )*
|
1573
|
+
#
|
1574
|
+
# Input from `data` is TODO.
|
1575
|
+
# Output to prod_data is TODO.
|
1166
1576
|
production(:_ConditionalOrExpression_1) do |input, data, callback|
|
1167
1577
|
accumulate_operator_expressions(:ConditionalOrExpression, :_OR, data)
|
1168
1578
|
end
|
1169
1579
|
|
1170
|
-
# [112]
|
1580
|
+
# [112] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )*
|
1581
|
+
#
|
1582
|
+
# Input from `data` is TODO.
|
1583
|
+
# Output to prod_data is TODO.
|
1171
1584
|
production(:ConditionalAndExpression) do |input, data, callback|
|
1172
1585
|
add_operator_expressions(:_AND, data)
|
1173
1586
|
end
|
1174
1587
|
|
1175
1588
|
# ( '||' ConditionalAndExpression )*
|
1589
|
+
#
|
1590
|
+
# Input from `data` is TODO.
|
1591
|
+
# Output to prod_data is TODO.
|
1176
1592
|
production(:_ConditionalAndExpression_1) do |input, data, callback|
|
1177
1593
|
accumulate_operator_expressions(:ConditionalAndExpression, :_AND, data)
|
1178
1594
|
end
|
1179
1595
|
|
1180
|
-
# [114]
|
1181
|
-
#
|
1182
|
-
#
|
1183
|
-
#
|
1184
|
-
#
|
1185
|
-
#
|
1186
|
-
#
|
1187
|
-
#
|
1188
|
-
#
|
1189
|
-
#
|
1596
|
+
# [114] RelationalExpression ::= NumericExpression
|
1597
|
+
# ( '=' NumericExpression
|
1598
|
+
# | '!=' NumericExpression
|
1599
|
+
# | '<' NumericExpression
|
1600
|
+
# | '>' NumericExpression
|
1601
|
+
# | '<=' NumericExpression
|
1602
|
+
# | '>=' NumericExpression
|
1603
|
+
# | 'IN' ExpressionList
|
1604
|
+
# | 'NOT' 'IN' ExpressionList
|
1605
|
+
# )?
|
1606
|
+
#
|
1607
|
+
# Input from `data` is TODO.
|
1608
|
+
# Output to prod_data is TODO.
|
1190
1609
|
production(:RelationalExpression) do |input, data, callback|
|
1191
1610
|
if data[:_Compare_Numeric]
|
1192
1611
|
add_prod_datum(:Expression, SPARQL::Algebra::Expression.for(data[:_Compare_Numeric].insert(1, *data[:Expression])))
|
@@ -1203,6 +1622,9 @@ module SPARQL::Grammar
|
|
1203
1622
|
end
|
1204
1623
|
|
1205
1624
|
# ( '=' NumericExpression | '!=' NumericExpression | ... )?
|
1625
|
+
#
|
1626
|
+
# Input from `data` is TODO.
|
1627
|
+
# Output to prod_data is TODO.
|
1206
1628
|
production(:_RelationalExpression_1) do |input, data, callback|
|
1207
1629
|
if data[:RelationalExpression]
|
1208
1630
|
add_prod_datum(:_Compare_Numeric, data[:RelationalExpression] + data[:Expression])
|
@@ -1214,11 +1636,17 @@ module SPARQL::Grammar
|
|
1214
1636
|
end
|
1215
1637
|
|
1216
1638
|
# 'IN' ExpressionList
|
1639
|
+
#
|
1640
|
+
# Input from `data` is TODO.
|
1641
|
+
# Output to prod_data is TODO.
|
1217
1642
|
production(:_RelationalExpression_9) do |input, data, callback|
|
1218
1643
|
add_prod_datum(:in, data[:ExpressionList])
|
1219
1644
|
end
|
1220
1645
|
|
1221
1646
|
# 'NOT' 'IN' ExpressionList
|
1647
|
+
#
|
1648
|
+
# Input from `data` is TODO.
|
1649
|
+
# Output to prod_data is TODO.
|
1222
1650
|
production(:_RelationalExpression_10) do |input, data, callback|
|
1223
1651
|
add_prod_datum(:notin, data[:ExpressionList])
|
1224
1652
|
end
|
@@ -1226,10 +1654,14 @@ module SPARQL::Grammar
|
|
1226
1654
|
# [116] AdditiveExpression ::= MultiplicativeExpression
|
1227
1655
|
# ( '+' MultiplicativeExpression
|
1228
1656
|
# | '-' MultiplicativeExpression
|
1229
|
-
# | ( NumericLiteralPositive
|
1657
|
+
# | ( NumericLiteralPositive
|
1658
|
+
# | NumericLiteralNegative )
|
1230
1659
|
# ( ( '*' UnaryExpression )
|
1231
1660
|
# | ( '/' UnaryExpression ) )?
|
1232
1661
|
# )*
|
1662
|
+
#
|
1663
|
+
# Input from `data` is TODO.
|
1664
|
+
# Output to prod_data is TODO.
|
1233
1665
|
production(:AdditiveExpression) do |input, data, callback|
|
1234
1666
|
add_operator_expressions(:_Add_Sub, data)
|
1235
1667
|
end
|
@@ -1240,11 +1672,17 @@ module SPARQL::Grammar
|
|
1240
1672
|
# ( ( '*' UnaryExpression )
|
1241
1673
|
# | ( '/' UnaryExpression ) )?
|
1242
1674
|
# )*
|
1675
|
+
#
|
1676
|
+
# Input from `data` is TODO.
|
1677
|
+
# Output to prod_data is TODO.
|
1243
1678
|
production(:_AdditiveExpression_1) do |input, data, callback|
|
1244
1679
|
accumulate_operator_expressions(:AdditiveExpression, :_Add_Sub, data)
|
1245
1680
|
end
|
1246
1681
|
|
1247
1682
|
# | ( NumericLiteralPositive | NumericLiteralNegative )
|
1683
|
+
#
|
1684
|
+
# Input from `data` is TODO.
|
1685
|
+
# Output to prod_data is TODO.
|
1248
1686
|
production(:_AdditiveExpression_7) do |input, data, callback|
|
1249
1687
|
lit = data[:literal]
|
1250
1688
|
val = lit.to_s
|
@@ -1253,23 +1691,32 @@ module SPARQL::Grammar
|
|
1253
1691
|
add_prod_datum(:Expression, [lit.class.new(val)])
|
1254
1692
|
end
|
1255
1693
|
|
1256
|
-
# [117]
|
1257
|
-
#
|
1258
|
-
#
|
1694
|
+
# [117] MultiplicativeExpression ::= UnaryExpression
|
1695
|
+
# ( '*' UnaryExpression
|
1696
|
+
# | '/' UnaryExpression )*
|
1697
|
+
#
|
1698
|
+
# Input from `data` is TODO.
|
1699
|
+
# Output to prod_data is TODO.
|
1259
1700
|
production(:MultiplicativeExpression) do |input, data, callback|
|
1260
1701
|
add_operator_expressions(:_Mul_Div, data)
|
1261
1702
|
end
|
1262
1703
|
|
1263
1704
|
# ( '*' UnaryExpression
|
1264
1705
|
# | '/' UnaryExpression )*
|
1706
|
+
#
|
1707
|
+
# Input from `data` is TODO.
|
1708
|
+
# Output to prod_data is TODO.
|
1265
1709
|
production(:_MultiplicativeExpression_1) do |input, data, callback|
|
1266
1710
|
accumulate_operator_expressions(:MultiplicativeExpression, :_Mul_Div, data)
|
1267
1711
|
end
|
1268
1712
|
|
1269
|
-
# [118]
|
1270
|
-
#
|
1271
|
-
#
|
1272
|
-
#
|
1713
|
+
# [118] UnaryExpression ::= '!' PrimaryExpression
|
1714
|
+
# | '+' PrimaryExpression
|
1715
|
+
# | '-' PrimaryExpression
|
1716
|
+
# | PrimaryExpression
|
1717
|
+
#
|
1718
|
+
# Input from `data` is TODO.
|
1719
|
+
# Output to prod_data is TODO.
|
1273
1720
|
production(:UnaryExpression) do |input, data, callback|
|
1274
1721
|
case data[:UnaryExpression]
|
1275
1722
|
when ["!"]
|
@@ -1286,11 +1733,14 @@ module SPARQL::Grammar
|
|
1286
1733
|
end
|
1287
1734
|
end
|
1288
1735
|
|
1289
|
-
# [119]
|
1290
|
-
#
|
1291
|
-
#
|
1292
|
-
#
|
1293
|
-
#
|
1736
|
+
# [119] PrimaryExpression ::= BrackettedExpression | BuiltInCall
|
1737
|
+
# | iriOrFunction | RDFLiteral
|
1738
|
+
# | NumericLiteral | BooleanLiteral
|
1739
|
+
# | Var
|
1740
|
+
# | ExprQuotedTP
|
1741
|
+
#
|
1742
|
+
# Input from `data` is TODO.
|
1743
|
+
# Output to prod_data is TODO.
|
1294
1744
|
production(:PrimaryExpression) do |input, data, callback|
|
1295
1745
|
if data[:Expression]
|
1296
1746
|
add_prod_datum(:Expression, data[:Expression])
|
@@ -1312,62 +1762,65 @@ module SPARQL::Grammar
|
|
1312
1762
|
add_prod_datum(:UnaryExpression, data[:UnaryExpression])
|
1313
1763
|
end
|
1314
1764
|
|
1315
|
-
# [121] BuiltInCall
|
1316
|
-
#
|
1317
|
-
#
|
1318
|
-
#
|
1319
|
-
#
|
1320
|
-
#
|
1321
|
-
#
|
1322
|
-
#
|
1323
|
-
#
|
1324
|
-
#
|
1325
|
-
#
|
1326
|
-
#
|
1327
|
-
#
|
1328
|
-
#
|
1329
|
-
#
|
1330
|
-
#
|
1331
|
-
#
|
1332
|
-
#
|
1333
|
-
#
|
1334
|
-
#
|
1335
|
-
#
|
1336
|
-
#
|
1337
|
-
#
|
1338
|
-
#
|
1339
|
-
#
|
1340
|
-
#
|
1341
|
-
#
|
1342
|
-
#
|
1343
|
-
#
|
1344
|
-
#
|
1345
|
-
#
|
1346
|
-
#
|
1347
|
-
#
|
1348
|
-
#
|
1349
|
-
#
|
1350
|
-
#
|
1351
|
-
#
|
1352
|
-
#
|
1353
|
-
#
|
1354
|
-
#
|
1355
|
-
#
|
1356
|
-
#
|
1357
|
-
#
|
1358
|
-
#
|
1359
|
-
#
|
1360
|
-
#
|
1361
|
-
#
|
1362
|
-
#
|
1363
|
-
#
|
1364
|
-
#
|
1365
|
-
#
|
1366
|
-
#
|
1367
|
-
#
|
1368
|
-
#
|
1369
|
-
#
|
1370
|
-
#
|
1765
|
+
# [121] BuiltInCall ::= Aggregate
|
1766
|
+
# | 'STR' '(' Expression ')'
|
1767
|
+
# | 'LANG' '(' Expression ')'
|
1768
|
+
# | 'LANGMATCHES' '(' Expression ',' Expression ')'
|
1769
|
+
# | 'DATATYPE' '(' Expression ')'
|
1770
|
+
# | 'BOUND' '(' Var ')'
|
1771
|
+
# | 'IRI' '(' Expression ')'
|
1772
|
+
# | 'URI' '(' Expression ')'
|
1773
|
+
# | 'BNODE' ( '(' Expression ')' | NIL )
|
1774
|
+
# | 'RAND' NIL
|
1775
|
+
# | 'ABS' '(' Expression ')'
|
1776
|
+
# | 'CEIL' '(' Expression ')'
|
1777
|
+
# | 'FLOOR' '(' Expression ')'
|
1778
|
+
# | 'ROUND' '(' Expression ')'
|
1779
|
+
# | 'CONCAT' ExpressionList
|
1780
|
+
# | SubstringExpression
|
1781
|
+
# | 'STRLEN' '(' Expression ')'
|
1782
|
+
# | StrReplaceExpression
|
1783
|
+
# | 'UCASE' '(' Expression ')'
|
1784
|
+
# | 'LCASE' '(' Expression ')'
|
1785
|
+
# | 'ENCODE_FOR_URI' '(' Expression ')'
|
1786
|
+
# | 'CONTAINS' '(' Expression ',' Expression ')'
|
1787
|
+
# | 'STRSTARTS' '(' Expression ',' Expression ')'
|
1788
|
+
# | 'STRENDS' '(' Expression ',' Expression ')'
|
1789
|
+
# | 'STRBEFORE' '(' Expression ',' Expression ')'
|
1790
|
+
# | 'STRAFTER' '(' Expression ',' Expression ')'
|
1791
|
+
# | 'YEAR' '(' Expression ')'
|
1792
|
+
# | 'MONTH' '(' Expression ')'
|
1793
|
+
# | 'DAY' '(' Expression ')'
|
1794
|
+
# | 'HOURS' '(' Expression ')'
|
1795
|
+
# | 'MINUTES' '(' Expression ')'
|
1796
|
+
# | 'SECONDS' '(' Expression ')'
|
1797
|
+
# | 'TIMEZONE' '(' Expression ')'
|
1798
|
+
# | 'TZ' '(' Expression ')'
|
1799
|
+
# | 'NOW' NIL
|
1800
|
+
# | 'UUID' NIL
|
1801
|
+
# | 'STRUUID' NIL
|
1802
|
+
# | 'MD5' '(' Expression ')'
|
1803
|
+
# | 'SHA1' '(' Expression ')'
|
1804
|
+
# | 'SHA224' '(' Expression ')'
|
1805
|
+
# | 'SHA256' '(' Expression ')'
|
1806
|
+
# | 'SHA384' '(' Expression ')'
|
1807
|
+
# | 'SHA512' '(' Expression ')'
|
1808
|
+
# | 'COALESCE' ExpressionList
|
1809
|
+
# | 'IF' '(' Expression ',' Expression ',' Expression ')'
|
1810
|
+
# | 'STRLANG' '(' Expression ',' Expression ')'
|
1811
|
+
# | 'STRDT' '(' Expression ',' Expression ')'
|
1812
|
+
# | 'sameTerm' '(' Expression ',' Expression ')'
|
1813
|
+
# | 'isIRI' '(' Expression ')'
|
1814
|
+
# | 'isURI' '(' Expression ')'
|
1815
|
+
# | 'isBLANK' '(' Expression ')'
|
1816
|
+
# | 'isLITERAL' '(' Expression ')'
|
1817
|
+
# | 'isNUMERIC' '(' Expression ')'
|
1818
|
+
# | RegexExpression
|
1819
|
+
# | ExistsFunc
|
1820
|
+
# | NotExistsFunc
|
1821
|
+
#
|
1822
|
+
# Input from `data` is TODO.
|
1823
|
+
# Output to prod_data is TODO.
|
1371
1824
|
production(:BuiltInCall) do |input, data, callback|
|
1372
1825
|
input[:BuiltInCall] = if builtin = data.keys.detect {|k| BUILTINS.include?(k)}
|
1373
1826
|
SPARQL::Algebra::Expression.for(
|
@@ -1384,45 +1837,63 @@ module SPARQL::Grammar
|
|
1384
1837
|
end
|
1385
1838
|
end
|
1386
1839
|
|
1387
|
-
# [122]
|
1388
|
-
#
|
1840
|
+
# [122] RegexExpression ::= 'REGEX' '(' Expression ',' Expression
|
1841
|
+
# ( ',' Expression )? ')'
|
1842
|
+
#
|
1843
|
+
# Input from `data` is TODO.
|
1844
|
+
# Output to prod_data is TODO.
|
1389
1845
|
production(:RegexExpression) do |input, data, callback|
|
1390
1846
|
add_prod_datum(:regex, data[:Expression])
|
1391
1847
|
end
|
1392
1848
|
|
1393
|
-
# [123]
|
1394
|
-
#
|
1395
|
-
#
|
1849
|
+
# [123] SubstringExpression ::= 'SUBSTR'
|
1850
|
+
# '(' Expression ',' Expression
|
1851
|
+
# ( ',' Expression )? ')'
|
1852
|
+
#
|
1853
|
+
# Input from `data` is TODO.
|
1854
|
+
# Output to prod_data is TODO.
|
1396
1855
|
production(:SubstringExpression) do |input, data, callback|
|
1397
1856
|
add_prod_datum(:substr, data[:Expression])
|
1398
1857
|
end
|
1399
1858
|
|
1400
|
-
# [124] StrReplaceExpression
|
1401
|
-
#
|
1402
|
-
#
|
1403
|
-
#
|
1859
|
+
# [124] StrReplaceExpression ::= 'REPLACE'
|
1860
|
+
# '(' Expression ','
|
1861
|
+
# Expression ',' Expression
|
1862
|
+
# ( ',' Expression )? ')'
|
1863
|
+
#
|
1864
|
+
# Input from `data` is TODO.
|
1865
|
+
# Output to prod_data is TODO.
|
1404
1866
|
production(:StrReplaceExpression) do |input, data, callback|
|
1405
1867
|
add_prod_datum(:replace, data[:Expression])
|
1406
1868
|
end
|
1407
1869
|
|
1408
|
-
# [125]
|
1870
|
+
# [125] ExistsFunc ::= 'EXISTS' GroupGraphPattern
|
1871
|
+
#
|
1872
|
+
# Input from `data` is TODO.
|
1873
|
+
# Output to prod_data is TODO.
|
1409
1874
|
production(:ExistsFunc) do |input, data, callback|
|
1410
1875
|
add_prod_datum(:exists, data[:query])
|
1411
1876
|
end
|
1412
1877
|
|
1413
|
-
# [126]
|
1878
|
+
# [126] NotExistsFunc ::= 'NOT' 'EXISTS' GroupGraphPattern
|
1879
|
+
#
|
1880
|
+
# Input from `data` is TODO.
|
1881
|
+
# Output to prod_data is TODO.
|
1414
1882
|
production(:NotExistsFunc) do |input, data, callback|
|
1415
1883
|
add_prod_datum(:notexists, data[:query])
|
1416
1884
|
end
|
1417
1885
|
|
1418
|
-
# [127] Aggregate
|
1419
|
-
#
|
1420
|
-
#
|
1421
|
-
#
|
1422
|
-
#
|
1423
|
-
#
|
1424
|
-
#
|
1425
|
-
#
|
1886
|
+
# [127] Aggregate ::= 'COUNT' '(' 'DISTINCT'? ( '*' | Expression ) ')'
|
1887
|
+
# | 'SUM' '(' 'DISTINCT'? Expression ')'
|
1888
|
+
# | 'MIN' '(' 'DISTINCT'? Expression ')'
|
1889
|
+
# | 'MAX' '(' 'DISTINCT'? Expression ')'
|
1890
|
+
# | 'AVG' '(' 'DISTINCT'? Expression ')'
|
1891
|
+
# | 'SAMPLE' '(' 'DISTINCT'? Expression ')'
|
1892
|
+
# | 'GROUP_CONCAT' '(' 'DISTINCT'? Expression
|
1893
|
+
# ( ';' 'SEPARATOR' '=' String )? ')'
|
1894
|
+
#
|
1895
|
+
# Input from `data` is TODO.
|
1896
|
+
# Output to prod_data is TODO.
|
1426
1897
|
production(:Aggregate) do |input, data, callback|
|
1427
1898
|
if aggregate_rule = data.keys.detect {|k| AGGREGATE_RULES.include?(k)}
|
1428
1899
|
parts = [aggregate_rule]
|
@@ -1433,30 +1904,39 @@ module SPARQL::Grammar
|
|
1433
1904
|
end
|
1434
1905
|
end
|
1435
1906
|
|
1436
|
-
# [128]
|
1907
|
+
# [128] iriOrFunction ::= iri ArgList?
|
1908
|
+
#
|
1909
|
+
# Input from `data` is TODO.
|
1910
|
+
# Output to prod_data is TODO.
|
1437
1911
|
production(:iriOrFunction) do |input, data, callback|
|
1438
1912
|
if data.has_key?(:ArgList)
|
1439
1913
|
# Function is (func arg1 arg2 ...)
|
1440
|
-
add_prod_data(:Function,
|
1914
|
+
add_prod_data(:Function, SPARQL::Algebra::Operator::FunctionCall.new(data[:iri], *data[:ArgList]))
|
1441
1915
|
else
|
1442
1916
|
input[:iri] = data[:iri]
|
1443
1917
|
end
|
1444
1918
|
end
|
1445
1919
|
|
1446
|
-
# [129]
|
1920
|
+
# [129] RDFLiteral ::= String ( LANGTAG | ( '^^' iri ) )?
|
1921
|
+
#
|
1922
|
+
# Input from `data` is TODO.
|
1923
|
+
# Output to prod_data is TODO.
|
1447
1924
|
production(:RDFLiteral) do |input, data, callback|
|
1448
1925
|
if data[:string]
|
1449
1926
|
lit = data.dup
|
1450
1927
|
str = lit.delete(:string)
|
1451
1928
|
lit[:datatype] = lit.delete(:iri) if lit[:iri]
|
1452
|
-
lit[:language] = lit.delete(:language).
|
1929
|
+
lit[:language] = lit.delete(:language).downcase if lit[:language]
|
1453
1930
|
input[:literal] = RDF::Literal.new(str, **lit) if str
|
1454
1931
|
end
|
1455
1932
|
end
|
1456
1933
|
|
1457
|
-
# [132]
|
1458
|
-
#
|
1459
|
-
#
|
1934
|
+
# [132] NumericLiteralPositive ::= INTEGER_POSITIVE
|
1935
|
+
# | DECIMAL_POSITIVE
|
1936
|
+
# | DOUBLE_POSITIVE
|
1937
|
+
#
|
1938
|
+
# Input from `data` is TODO.
|
1939
|
+
# Output to prod_data is TODO.
|
1460
1940
|
production(:NumericLiteralPositive) do |input, data, callback|
|
1461
1941
|
num = data.values.flatten.last
|
1462
1942
|
input[:literal] = num
|
@@ -1465,9 +1945,12 @@ module SPARQL::Grammar
|
|
1465
1945
|
add_prod_datum(:UnaryExpression, data[:UnaryExpression])
|
1466
1946
|
end
|
1467
1947
|
|
1468
|
-
# [133]
|
1469
|
-
#
|
1470
|
-
#
|
1948
|
+
# [133] NumericLiteralNegative ::= INTEGER_NEGATIVE
|
1949
|
+
# | DECIMAL_NEGATIVE
|
1950
|
+
# | DOUBLE_NEGATIVE
|
1951
|
+
#
|
1952
|
+
# Input from `data` is TODO.
|
1953
|
+
# Output to prod_data is TODO.
|
1471
1954
|
production(:NumericLiteralNegative) do |input, data, callback|
|
1472
1955
|
num = data.values.flatten.last
|
1473
1956
|
input[:literal] = num
|
@@ -1477,61 +1960,81 @@ module SPARQL::Grammar
|
|
1477
1960
|
end
|
1478
1961
|
|
1479
1962
|
# [174] QuotedTP ::= '<<' qtSubjectOrObject Verb qtSubjectOrObject '>>'
|
1963
|
+
#
|
1964
|
+
# Input from `data` is `:qtSubjectOrObject` from which subject and object are extracted and `:Verb` from which predicate is extracted.
|
1965
|
+
# Output to prod_data is `:QuotedTP` containing subject, predicate, and object.
|
1480
1966
|
production(:QuotedTP) do |input, data, callback|
|
1481
1967
|
subject, object = data[:qtSubjectOrObject]
|
1482
1968
|
predicate = data[:Verb]
|
1483
1969
|
add_pattern(:QuotedTP,
|
1484
1970
|
subject: subject,
|
1485
1971
|
predicate: predicate,
|
1486
|
-
object: object
|
1972
|
+
object: object,
|
1973
|
+
quoted: true)
|
1487
1974
|
end
|
1488
1975
|
|
1489
1976
|
# [175] QuotedTriple ::= '<<' DataValueTerm (iri | 'a') DataValueTerm '>>'
|
1977
|
+
#
|
1978
|
+
# Input from `data` is TODO.
|
1979
|
+
# Output to prod_data is TODO.
|
1490
1980
|
production(:QuotedTriple) do |input, data, callback|
|
1491
1981
|
subject, object = data[:DataValueTerm]
|
1492
1982
|
predicate = data[:iri]
|
1493
1983
|
add_pattern(:QuotedTriple,
|
1494
1984
|
subject: subject,
|
1495
1985
|
predicate: predicate,
|
1496
|
-
object: object
|
1986
|
+
object: object,
|
1987
|
+
quoted: true)
|
1497
1988
|
end
|
1498
1989
|
|
1499
|
-
# [176] qtSubjectOrObject ::=
|
1500
|
-
#
|
1990
|
+
# [176] qtSubjectOrObject ::= Var | BlankNode | iri | RDFLiteral
|
1991
|
+
# | NumericLiteral | BooleanLiteral | QuotedTP
|
1992
|
+
#
|
1993
|
+
# Input from `data` is TODO.
|
1994
|
+
# Output to prod_data is TODO.
|
1501
1995
|
production(:qtSubjectOrObject) do |input, data, callback|
|
1502
1996
|
data.values.each {|v| add_prod_datum(:qtSubjectOrObject, v)}
|
1503
1997
|
end
|
1504
1998
|
|
1505
|
-
# [177] DataValueTerm
|
1999
|
+
# [177] DataValueTerm ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | QuotedTriple
|
2000
|
+
#
|
2001
|
+
# Input from `data` is TODO.
|
2002
|
+
# Output to prod_data is TODO.
|
1506
2003
|
production(:DataValueTerm) do |input, data, callback|
|
1507
2004
|
add_prod_datum :DataValueTerm, data.values.first
|
1508
2005
|
end
|
1509
2006
|
|
1510
|
-
# [180]
|
2007
|
+
# [180] AnnotationPatternPath ::= '{|' PropertyListPathNotEmpty '|}'
|
1511
2008
|
start_production(:AnnotationPatternPath) do |input, data, callback|
|
1512
2009
|
data[:TriplesNode] = input[:TriplesNode]
|
1513
2010
|
end
|
2011
|
+
|
2012
|
+
#
|
2013
|
+
# Add `:TriplesNode` as subject of collected patterns
|
2014
|
+
# Input from `data` is `:pattern`.
|
2015
|
+
# Output to prod_data is `:pattern`.
|
1514
2016
|
production(:AnnotationPatternPath) do |input, data, callback|
|
1515
|
-
|
1516
|
-
add_prod_datum(:pattern, data[:pattern])
|
1517
|
-
elsif data[:path]
|
1518
|
-
# Replace the subject in the path with the node being annotated.
|
1519
|
-
data[:path].first.operands[0] = data[:TriplesNode]
|
1520
|
-
add_prod_datum(:path, data[:path])
|
1521
|
-
end
|
2017
|
+
add_prod_datum(:pattern, data[:pattern])
|
1522
2018
|
end
|
1523
2019
|
|
1524
2020
|
# [181] ExprQuotedTP ::= '<<' ExprVarOrTerm Verb ExprVarOrTerm '>>'
|
2021
|
+
#
|
2022
|
+
# Input from `data` is TODO.
|
2023
|
+
# Output to prod_data is TODO.
|
1525
2024
|
production(:ExprQuotedTP) do |input, data, callback|
|
1526
2025
|
subject, object = data[:ExprVarOrTerm]
|
1527
2026
|
predicate = data[:Verb]
|
1528
2027
|
add_pattern(:ExprQuotedTP,
|
1529
2028
|
subject: subject,
|
1530
2029
|
predicate: predicate,
|
1531
|
-
object: object
|
2030
|
+
object: object,
|
2031
|
+
quoted: true)
|
1532
2032
|
end
|
1533
2033
|
|
1534
|
-
# [182] ExprVarOrTerm ::=
|
2034
|
+
# [182] ExprVarOrTerm ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprQuotedTP
|
2035
|
+
#
|
2036
|
+
# Input from `data` is TODO.
|
2037
|
+
# Output to prod_data is TODO.
|
1535
2038
|
production(:ExprVarOrTerm) do |input, data, callback|
|
1536
2039
|
data.values.each {|v| add_prod_datum(:ExprVarOrTerm, v)}
|
1537
2040
|
end
|
@@ -1541,20 +2044,23 @@ module SPARQL::Grammar
|
|
1541
2044
|
#
|
1542
2045
|
# @param [String, IO, StringIO, #to_s] input
|
1543
2046
|
# @param [Hash{Symbol => Object}] options
|
1544
|
-
# @option options [
|
1545
|
-
#
|
1546
|
-
#
|
1547
|
-
# the base URI to use when resolving relative URIs (for acessing intermediate parser productions)
|
2047
|
+
# @option options [Boolean] :all_vars (false)
|
2048
|
+
# If `true`, emits on empty `project` operator when parsing `SELECT *`, which will emit all in-scope variables, rather than just those used in solutions.
|
2049
|
+
# In the next minor release, the default for this option will change to `true`.
|
1548
2050
|
# @option options [#to_s] :anon_base ("b0")
|
1549
2051
|
# Basis for generating anonymous Nodes
|
2052
|
+
# @option options [#to_s] :base_uri (nil)
|
2053
|
+
# the base URI to use when resolving relative URIs (for acessing intermediate parser productions)
|
2054
|
+
# @option options [Logger, #write, #<<] :logger
|
2055
|
+
# Record error/info/debug output
|
2056
|
+
# @option options [Hash] :prefixes (Hash.new)
|
2057
|
+
# the prefix mappings to use (for acessing intermediate parser productions)
|
1550
2058
|
# @option options [Boolean] :resolve_iris (false)
|
1551
2059
|
# Resolve prefix and relative IRIs, otherwise, when serializing the parsed SSE
|
1552
2060
|
# as S-Expressions, use the original prefixed and relative URIs along with `base` and `prefix`
|
1553
2061
|
# definitions.
|
1554
2062
|
# @option options [Boolean] :validate (false)
|
1555
2063
|
# whether to validate the parsed statements and values
|
1556
|
-
# @option options [Logger, #write, #<<] :logger
|
1557
|
-
# Record error/info/debug output
|
1558
2064
|
# @yield [parser] `self`
|
1559
2065
|
# @yieldparam [SPARQL::Grammar::Parser] parser
|
1560
2066
|
# @yieldreturn [void] ignored
|
@@ -1615,7 +2121,7 @@ module SPARQL::Grammar
|
|
1615
2121
|
#
|
1616
2122
|
# @param [Symbol, #to_s] prod The starting production for the parser.
|
1617
2123
|
# It may be a URI from the grammar, or a symbol representing the local_name portion of the grammar URI.
|
1618
|
-
# @return [
|
2124
|
+
# @return [RDF::Queryable]
|
1619
2125
|
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
1620
2126
|
# @see https://axel.deri.ie/sparqltutorial/ESWC2007_SPARQL_Tutorial_unit2b.pdf
|
1621
2127
|
def parse(prod = START)
|
@@ -1811,9 +2317,7 @@ module SPARQL::Grammar
|
|
1811
2317
|
# If we have a base URI, use that when constructing a new URI
|
1812
2318
|
value = RDF::URI(value)
|
1813
2319
|
if base_uri && value.relative?
|
1814
|
-
|
1815
|
-
#u.lexical = "<#{value}>" unless resolve_iris?
|
1816
|
-
#u
|
2320
|
+
base_uri.join(value)
|
1817
2321
|
else
|
1818
2322
|
value
|
1819
2323
|
end
|
@@ -1823,10 +2327,7 @@ module SPARQL::Grammar
|
|
1823
2327
|
base = prefix(prefix).to_s
|
1824
2328
|
suffix = suffix.to_s.sub(/^\#/, "") if base.index("#")
|
1825
2329
|
debug {"ns(#{prefix.inspect}): base: '#{base}', suffix: '#{suffix}'"}
|
1826
|
-
iri
|
1827
|
-
# Cause URI to be serialized as a lexical
|
1828
|
-
#iri.lexical = "#{prefix}:#{suffix}" unless resolve_iris?
|
1829
|
-
#iri
|
2330
|
+
iri(base + suffix.to_s)
|
1830
2331
|
end
|
1831
2332
|
|
1832
2333
|
# Create a literal
|
@@ -1869,10 +2370,12 @@ module SPARQL::Grammar
|
|
1869
2370
|
# add a pattern
|
1870
2371
|
#
|
1871
2372
|
# @param [String] production Production generating pattern
|
2373
|
+
# @param [Boolean] quoted For quoted triple
|
1872
2374
|
# @param [Hash{Symbol => Object}] options
|
1873
|
-
def add_pattern(production, **options)
|
2375
|
+
def add_pattern(production, quoted: false, **options)
|
1874
2376
|
progress(production, "[:pattern, #{options[:subject]}, #{options[:predicate]}, #{options[:object]}]")
|
1875
2377
|
triple = {}
|
2378
|
+
triple[:quoted] = true if quoted
|
1876
2379
|
options.each_pair do |r, v|
|
1877
2380
|
if v.is_a?(Array) && v.flatten.length == 1
|
1878
2381
|
v = v.flatten.first
|
@@ -1894,6 +2397,7 @@ module SPARQL::Grammar
|
|
1894
2397
|
[expr, query]
|
1895
2398
|
end
|
1896
2399
|
|
2400
|
+
##
|
1897
2401
|
# Merge query modifiers, datasets, and projections
|
1898
2402
|
#
|
1899
2403
|
# This includes tranforming aggregates if also used with a GROUP BY
|
@@ -1988,7 +2492,14 @@ module SPARQL::Grammar
|
|
1988
2492
|
|
1989
2493
|
query = SPARQL::Algebra::Expression[:order, data[:order].first, query] unless order.empty?
|
1990
2494
|
|
1991
|
-
|
2495
|
+
# If SELECT * was used, emit a projection with empty variables, vs no projection at all. Only if :all_vars is true
|
2496
|
+
query = if vars == %i(*)
|
2497
|
+
options[:all_vars] ? SPARQL::Algebra::Expression[:project, [], query] : query
|
2498
|
+
elsif !vars.empty?
|
2499
|
+
SPARQL::Algebra::Expression[:project, vars, query]
|
2500
|
+
else
|
2501
|
+
query
|
2502
|
+
end
|
1992
2503
|
|
1993
2504
|
query = SPARQL::Algebra::Expression[data[:DISTINCT_REDUCED], query] if data[:DISTINCT_REDUCED]
|
1994
2505
|
|