sparql 3.2.1 → 3.2.3
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 +57 -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 +35 -7
- data/lib/sparql/algebra/extensions.rb +18 -18
- data/lib/sparql/algebra/operator/adjust.rb +69 -0
- data/lib/sparql/algebra/operator/bgp.rb +1 -1
- data/lib/sparql/algebra/operator/construct.rb +1 -1
- data/lib/sparql/algebra/operator/dataset.rb +10 -0
- data/lib/sparql/algebra/operator/day.rb +2 -2
- data/lib/sparql/algebra/operator/delete.rb +1 -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/extend.rb +32 -2
- data/lib/sparql/algebra/operator/group.rb +34 -6
- data/lib/sparql/algebra/operator/hours.rb +2 -2
- data/lib/sparql/algebra/operator/insert.rb +1 -1
- data/lib/sparql/algebra/operator/insert_data.rb +1 -1
- data/lib/sparql/algebra/operator/join.rb +3 -3
- data/lib/sparql/algebra/operator/left_join.rb +3 -3
- data/lib/sparql/algebra/operator/minus.rb +1 -1
- 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/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 +7 -5
- data/lib/sparql/algebra/operator/project.rb +42 -1
- data/lib/sparql/algebra/operator/seconds.rb +2 -2
- data/lib/sparql/algebra/operator/seq.rb +3 -3
- data/lib/sparql/algebra/operator/sequence.rb +10 -0
- data/lib/sparql/algebra/operator/subtract.rb +9 -5
- data/lib/sparql/algebra/operator/table.rb +11 -2
- 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/using.rb +2 -2
- data/lib/sparql/algebra/operator/year.rb +2 -2
- data/lib/sparql/algebra/operator.rb +27 -10
- data/lib/sparql/algebra/query.rb +5 -3
- data/lib/sparql/algebra.rb +22 -3
- data/lib/sparql/grammar/meta.rb +1367 -267
- data/lib/sparql/grammar/parser11.rb +826 -328
- 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 +39 -17
@@ -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,8 +194,11 @@ 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
203
|
query = data[:query].first if data[:query]
|
201
204
|
|
@@ -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,30 @@ module SPARQL::Grammar
|
|
703
916
|
end
|
704
917
|
end
|
705
918
|
|
706
|
-
# [60] Bind
|
919
|
+
# [60] Bind ::= 'BIND' '(' Expression 'AS' Var ')'
|
920
|
+
#
|
921
|
+
# Input from `data` is TODO.
|
922
|
+
# Output to prod_data is TODO.
|
707
923
|
production(:Bind) do |input, data, callback|
|
708
924
|
add_prod_datum :extend, [data[:Expression].unshift(data[:Var].first)]
|
709
925
|
end
|
710
926
|
|
711
|
-
# [61] InlineData
|
927
|
+
# [61] InlineData ::= 'VALUES' DataBlock
|
928
|
+
#
|
929
|
+
# Input from `data` is TODO.
|
930
|
+
# Output to prod_data is TODO.
|
712
931
|
production(:InlineData) do |input, data, callback|
|
713
932
|
debug("InlineData") {"vars: #{data[:Var].inspect}, row: #{data[:row].inspect}"}
|
714
933
|
add_prod_datum :query, SPARQL::Algebra::Expression.for(:table,
|
715
|
-
data[:Var].unshift(:vars),
|
934
|
+
Array(data[:Var]).unshift(:vars),
|
716
935
|
*data[:row]
|
717
936
|
)
|
718
937
|
end
|
719
938
|
|
720
|
-
# [63] InlineDataOneVar
|
939
|
+
# [63] InlineDataOneVar ::= Var '{' DataBlockValue* '}'
|
940
|
+
#
|
941
|
+
# Input from `data` is TODO.
|
942
|
+
# Output to prod_data is TODO.
|
721
943
|
production(:InlineDataOneVar) do |input, data, callback|
|
722
944
|
add_prod_datum :Var, data[:Var]
|
723
945
|
|
@@ -726,8 +948,11 @@ module SPARQL::Grammar
|
|
726
948
|
end
|
727
949
|
end
|
728
950
|
|
729
|
-
# [64] InlineDataFull
|
730
|
-
#
|
951
|
+
# [64] InlineDataFull ::= ( NIL | '(' Var* ')' )
|
952
|
+
# '{' ( '(' DataBlockValue* ')' | NIL )* '}'
|
953
|
+
#
|
954
|
+
# Input from `data` is TODO.
|
955
|
+
# Output to prod_data is TODO.
|
731
956
|
production(:InlineDataFull) do |input, data, callback|
|
732
957
|
vars = data[:Var]
|
733
958
|
add_prod_datum :Var, vars
|
@@ -745,7 +970,10 @@ module SPARQL::Grammar
|
|
745
970
|
end
|
746
971
|
end
|
747
972
|
|
748
|
-
# _InlineDataFull_6
|
973
|
+
# _InlineDataFull_6 ::= '(' '(' DataBlockValue* ')' | NIL ')'
|
974
|
+
#
|
975
|
+
# Input from `data` is TODO.
|
976
|
+
# Output to prod_data is TODO.
|
749
977
|
production(:_InlineDataFull_6) do |input, data, callback|
|
750
978
|
if data[:DataBlockValue]
|
751
979
|
add_prod_data :rowdata, data[:DataBlockValue].map {|v| v unless v == :undef}
|
@@ -754,19 +982,28 @@ module SPARQL::Grammar
|
|
754
982
|
end
|
755
983
|
end
|
756
984
|
|
757
|
-
# [65] DataBlockValue
|
985
|
+
# [65] DataBlockValue ::= QuotedTriple | iri | RDFLiteral | NumericLiteral | BooleanLiteral | 'UNDEF'
|
986
|
+
#
|
987
|
+
# Input from `data` is TODO.
|
988
|
+
# Output to prod_data is TODO.
|
758
989
|
production(:DataBlockValue) do |input, data, callback|
|
759
990
|
add_prod_datum :DataBlockValue, data.values.first
|
760
991
|
end
|
761
992
|
|
762
|
-
# [66] MinusGraphPattern
|
993
|
+
# [66] MinusGraphPattern ::= 'MINUS' GroupGraphPattern
|
994
|
+
#
|
995
|
+
# Input from `data` is TODO.
|
996
|
+
# Output to prod_data is TODO.
|
763
997
|
production(:MinusGraphPattern) do |input, data, callback|
|
764
998
|
query = data[:query] ? data[:query].first : SPARQL::Algebra::Operator::BGP.new
|
765
999
|
add_prod_data(:minus, query)
|
766
1000
|
end
|
767
1001
|
|
768
|
-
# [67]
|
1002
|
+
# [67] GroupOrUnionGraphPattern ::= GroupGraphPattern
|
769
1003
|
# ( 'UNION' GroupGraphPattern )*
|
1004
|
+
#
|
1005
|
+
# Input from `data` is TODO.
|
1006
|
+
# Output to prod_data is TODO.
|
770
1007
|
production(:GroupOrUnionGraphPattern) do |input, data, callback|
|
771
1008
|
res = Array(data[:query]).first
|
772
1009
|
if data[:union]
|
@@ -782,17 +1019,26 @@ module SPARQL::Grammar
|
|
782
1019
|
end
|
783
1020
|
|
784
1021
|
# ( 'UNION' GroupGraphPattern )*
|
1022
|
+
#
|
1023
|
+
# Input from `data` is TODO.
|
1024
|
+
# Output to prod_data is TODO.
|
785
1025
|
production(:_GroupOrUnionGraphPattern_1) do |input, data, callback|
|
786
1026
|
input[:union] = Array(data[:union]).unshift(data[:query].first)
|
787
1027
|
end
|
788
1028
|
|
789
|
-
# [68]
|
1029
|
+
# [68] Filter ::= 'FILTER' Constraint
|
1030
|
+
#
|
1031
|
+
# Input from `data` is TODO.
|
1032
|
+
# Output to prod_data is TODO.
|
790
1033
|
production(:Filter) do |input, data, callback|
|
791
1034
|
add_prod_datum(:filter, data[:Constraint])
|
792
1035
|
end
|
793
1036
|
|
794
|
-
# [69]
|
1037
|
+
# [69] Constraint ::= BrackettedExpression | BuiltInCall
|
795
1038
|
# | FunctionCall
|
1039
|
+
#
|
1040
|
+
# Input from `data` is TODO.
|
1041
|
+
# Output to prod_data is TODO.
|
796
1042
|
production(:Constraint) do |input, data, callback|
|
797
1043
|
if data[:Expression]
|
798
1044
|
# Resolve expression to the point it is either an atom or an s-exp
|
@@ -804,28 +1050,41 @@ module SPARQL::Grammar
|
|
804
1050
|
end
|
805
1051
|
end
|
806
1052
|
|
807
|
-
# [70]
|
1053
|
+
# [70] FunctionCall ::= iri ArgList
|
1054
|
+
#
|
1055
|
+
# Input from `data` is TODO.
|
1056
|
+
# Output to prod_data is TODO.
|
808
1057
|
production(:FunctionCall) do |input, data, callback|
|
809
1058
|
add_prod_data(:Function, SPARQL::Algebra::Operator::FunctionCall.new(data[:iri], *data[:ArgList]))
|
810
1059
|
end
|
811
1060
|
|
812
|
-
# [71]
|
1061
|
+
# [71] ArgList ::= NIL
|
813
1062
|
# | '(' 'DISTINCT'? Expression ( ',' Expression )* ')'
|
1063
|
+
#
|
1064
|
+
# Input from `data` is TODO.
|
1065
|
+
# Output to prod_data is TODO.
|
814
1066
|
production(:ArgList) do |input, data, callback|
|
815
1067
|
data.values.each {|v| add_prod_datum(:ArgList, v)}
|
816
1068
|
end
|
817
1069
|
|
818
|
-
# [72]
|
1070
|
+
# [72] ExpressionList ::= NIL
|
819
1071
|
# | '(' Expression ( ',' Expression )* ')'
|
1072
|
+
#
|
1073
|
+
# Input from `data` is TODO.
|
1074
|
+
# Output to prod_data is TODO.
|
820
1075
|
production(:ExpressionList) do |input, data, callback|
|
821
1076
|
data.values.each {|v| add_prod_datum(:ExpressionList, v)}
|
822
1077
|
end
|
823
1078
|
|
824
|
-
# [73]
|
1079
|
+
# [73] ConstructTemplate ::= '{' ConstructTriples? '}'
|
825
1080
|
start_production(:ConstructTemplate) do |input, data, callback|
|
826
1081
|
# Generate BNodes instead of non-distinguished variables
|
827
1082
|
self.gen_bnodes
|
828
1083
|
end
|
1084
|
+
|
1085
|
+
#
|
1086
|
+
# Input from `data` is TODO.
|
1087
|
+
# Output to prod_data is TODO.
|
829
1088
|
production(:ConstructTemplate) do |input, data, callback|
|
830
1089
|
# Generate BNodes instead of non-distinguished variables
|
831
1090
|
self.gen_bnodes(false)
|
@@ -833,13 +1092,13 @@ module SPARQL::Grammar
|
|
833
1092
|
add_prod_datum(:ConstructTemplate, data[:ConstructTemplate])
|
834
1093
|
end
|
835
1094
|
|
836
|
-
# [75]
|
837
|
-
# |
|
1095
|
+
# [75] TriplesSameSubject ::= VarOrTermOrQuotedTP PropertyListNotEmpty
|
1096
|
+
# | TriplesNode PropertyList
|
838
1097
|
production(:TriplesSameSubject) do |input, data, callback|
|
839
1098
|
add_prod_datum(:pattern, data[:pattern])
|
840
1099
|
end
|
841
1100
|
|
842
|
-
# [77]
|
1101
|
+
# [77] PropertyListNotEmpty ::= Verb ObjectList
|
843
1102
|
# ( ';' ( Verb ObjectList )? )*
|
844
1103
|
start_production(:PropertyListNotEmpty) do |input, data, callback|
|
845
1104
|
subject = input[:VarOrTermOrQuotedTP] || input[:TriplesNode] || input[:GraphNode]
|
@@ -850,47 +1109,58 @@ module SPARQL::Grammar
|
|
850
1109
|
add_prod_datum(:pattern, data[:pattern])
|
851
1110
|
end
|
852
1111
|
|
853
|
-
# [78]
|
1112
|
+
# [78] Verb ::= VarOrIri | 'a'
|
1113
|
+
#
|
1114
|
+
# Output to input is `:Verb`.
|
854
1115
|
production(:Verb) do |input, data, callback|
|
855
1116
|
input[:Verb] = data.values.first
|
856
1117
|
end
|
857
1118
|
|
858
|
-
# [79]
|
1119
|
+
# [79] ObjectList ::= Object ( ',' Object )*
|
1120
|
+
#
|
1121
|
+
# Adds `:Subject`, `:Verb`, and `:VerbPath` from input to data with error checking.
|
859
1122
|
start_production(:ObjectList) do |input, data, callback|
|
860
1123
|
# 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] =
|
1124
|
+
data[:Subject] = input[:Subject]
|
1125
|
+
error(nil, "Expected Subject", production: :ObjectList) if !input[:Subject] && validate?
|
1126
|
+
error(nil, "Expected Verb", production: :ObjectList) if !(input[:Verb] || input[:VerbPath]) && validate?
|
1127
|
+
data[:Verb] = input[:Verb] if input[:Verb]
|
1128
|
+
data[:VerbPath] = input[:VerbPath] if input[:VerbPath]
|
866
1129
|
end
|
867
1130
|
production(:ObjectList) do |input, data, callback|
|
868
1131
|
add_prod_datum(:pattern, data[:pattern])
|
869
|
-
add_prod_datum(:path, data[:path])
|
870
1132
|
end
|
871
1133
|
|
872
|
-
# [80]
|
1134
|
+
# [80] Object ::= GraphNode AnnotationPattern?
|
1135
|
+
#
|
1136
|
+
# Sets `:Subject` and `:Verb` in data from input.
|
873
1137
|
start_production(:Object) do |input, data, callback|
|
874
1138
|
data[:Subject] = Array(input[:Subject]).first
|
875
1139
|
data[:Verb] = Array(input[:Verb]).first
|
876
1140
|
end
|
1141
|
+
|
1142
|
+
#
|
1143
|
+
# Input from `data` is `:Subject`, `:Verb` or `:VerbPath`, and `GraphNode`.
|
1144
|
+
# Output to prod_data is `:pattern`, either from `:Subject`, `:Verb`, and `GraphNode` or a new path if `VerbPath` is present instead of `Verb`.
|
877
1145
|
production(:Object) do |input, data, callback|
|
878
1146
|
object = data[:GraphNode]
|
879
1147
|
add_prod_datum(:pattern, data[:pattern])
|
880
1148
|
if object
|
881
|
-
if
|
882
|
-
add_pattern(:Object, subject:
|
883
|
-
elsif
|
884
|
-
add_prod_datum(:
|
1149
|
+
if input[:Verb]
|
1150
|
+
add_pattern(:Object, subject: input[:Subject], predicate: input[:Verb], object: object)
|
1151
|
+
elsif input[:VerbPath]
|
1152
|
+
add_prod_datum(:pattern,
|
885
1153
|
SPARQL::Algebra::Expression(:path,
|
886
|
-
|
887
|
-
|
1154
|
+
input[:Subject].first,
|
1155
|
+
input[:VerbPath],
|
888
1156
|
object.first))
|
889
1157
|
end
|
890
1158
|
end
|
891
1159
|
end
|
1160
|
+
|
1161
|
+
# AnnotationPattern?
|
892
1162
|
start_production(:_Object_1) do |input, data, callback|
|
893
|
-
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first)
|
1163
|
+
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first, quoted: true)
|
894
1164
|
error("ObjectPath", "Expected Verb",
|
895
1165
|
production: :_Object_1) unless input[:Verb]
|
896
1166
|
data[:TriplesNode] = [pattern]
|
@@ -899,13 +1169,17 @@ module SPARQL::Grammar
|
|
899
1169
|
add_prod_datum(:pattern, data[:pattern])
|
900
1170
|
end
|
901
1171
|
|
902
|
-
# [81]
|
1172
|
+
# [81] TriplesSameSubjectPath ::= VarOrTermOrQuotedTP PropertyListPathNotEmpty | TriplesNode PropertyListPath
|
903
1173
|
production(:TriplesSameSubjectPath) do |input, data, callback|
|
904
1174
|
add_prod_datum(:pattern, data[:pattern])
|
905
|
-
add_prod_datum(:path, data[:path])
|
906
1175
|
end
|
907
1176
|
|
908
|
-
# [83]
|
1177
|
+
# [83] PropertyListPathNotEmpty ::= ( VerbPath | VerbSimple ) ObjectList
|
1178
|
+
# ( ';' ( ( VerbPath | VerbSimple )
|
1179
|
+
# ObjectList )? )*
|
1180
|
+
#
|
1181
|
+
# Sets `:Subject` in data from either `:VarOrTermOrQuotedTP`,
|
1182
|
+
# `:TriplesNode`, or `:GraphNode` in input with error checking.
|
909
1183
|
start_production(:PropertyListPathNotEmpty) do |input, data, callback|
|
910
1184
|
subject = input[:VarOrTermOrQuotedTP] || input[:TriplesNode] || input[:GraphNode]
|
911
1185
|
error(nil, "Expected VarOrTermOrQuotedTP, got nothing", production: :PropertyListPathNotEmpty) if validate? && !subject
|
@@ -913,10 +1187,13 @@ module SPARQL::Grammar
|
|
913
1187
|
end
|
914
1188
|
production(:PropertyListPathNotEmpty) do |input, data, callback|
|
915
1189
|
add_prod_datum(:pattern, data[:pattern])
|
916
|
-
add_prod_datum(:path, data[:path])
|
917
1190
|
end
|
918
1191
|
|
919
|
-
# [84]
|
1192
|
+
# [84] VerbPath ::= Path
|
1193
|
+
#
|
1194
|
+
# Input from `data` is `:Path` or `:iri`.
|
1195
|
+
# Output to prod_data is either `:VerbPath` or `:Verb`.
|
1196
|
+
# If `:VerbPath` is added, then any existing `:Verb` is removed.
|
920
1197
|
production(:VerbPath) do |input, data, callback|
|
921
1198
|
if data[:Path]
|
922
1199
|
input.delete(:Verb)
|
@@ -926,70 +1203,80 @@ module SPARQL::Grammar
|
|
926
1203
|
end
|
927
1204
|
end
|
928
1205
|
|
929
|
-
# [85]
|
1206
|
+
# [85] VerbSimple ::= Var
|
930
1207
|
production(:VerbSimple) do |input, data, callback|
|
931
1208
|
input[:Verb] = data.values.flatten.first
|
932
1209
|
end
|
933
1210
|
|
934
|
-
# [86]
|
1211
|
+
# [86] ObjectListPath ::= ObjectPath ("," ObjectPath)*
|
1212
|
+
#
|
1213
|
+
# Addes `:Subject` from input to data with error checking.
|
1214
|
+
# Also adds either `:Verb` or `:VerbPath`
|
935
1215
|
start_production(:ObjectListPath) do |input, data, callback|
|
936
1216
|
# 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(
|
1217
|
+
data[:Subject] = input[:Subject]
|
1218
|
+
error(nil, "Expected Subject", production: :ObjectListPath) if !input[:Subject] && validate?
|
1219
|
+
error(nil, "Expected Verb", production: :ObjectListPath) if !(input[:Verb] || input[:VerbPath]) && validate?
|
1220
|
+
if input[:Verb]
|
1221
|
+
data[:Verb] = Array(input[:Verb]).last
|
942
1222
|
else
|
943
|
-
data[:VerbPath] =
|
1223
|
+
data[:VerbPath] = input[:VerbPath]
|
944
1224
|
end
|
945
1225
|
end
|
1226
|
+
|
1227
|
+
#
|
1228
|
+
# Input from `data` is TODO.
|
1229
|
+
# Output to prod_data is TODO.
|
946
1230
|
production(:ObjectListPath) do |input, data, callback|
|
947
1231
|
add_prod_datum(:pattern, data[:pattern])
|
948
|
-
add_prod_datum(:path, data[:path])
|
949
1232
|
end
|
950
1233
|
|
951
|
-
# [87]
|
1234
|
+
# [87] ObjectPath ::= GraphNodePath AnnotationPatternPath?
|
1235
|
+
#
|
1236
|
+
# Adds `:Subject` and `:Verb` to data from input.
|
952
1237
|
start_production(:ObjectPath) do |input, data, callback|
|
953
1238
|
data[:Subject] = Array(input[:Subject]).first
|
954
1239
|
data[:Verb] = Array(input[:Verb]).first
|
955
1240
|
end
|
1241
|
+
|
1242
|
+
# Input from `data` `:Subject`, either `:Verb` or `:VerbPath`, `:GraphNode` from GraphNodePath is used as the object, and `:pattern`.
|
1243
|
+
# 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
1244
|
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
|
1245
|
+
subject = data[:Subject]
|
1246
|
+
verb = data[:Verb]
|
1247
|
+
object = Array(data[:GraphNode]).first
|
1248
|
+
if verb
|
1249
|
+
add_prod_datum(:pattern, RDF::Query::Pattern.new(subject, verb, object))
|
1250
|
+
else
|
1251
|
+
add_prod_datum(:pattern, SPARQL::Algebra::Expression(:path,
|
1252
|
+
subject,
|
1253
|
+
input[:VerbPath],
|
1254
|
+
object))
|
979
1255
|
end
|
1256
|
+
add_prod_datum(:pattern, data[:pattern])
|
980
1257
|
end
|
1258
|
+
|
1259
|
+
# AnnotationPatternPath?
|
1260
|
+
#
|
1261
|
+
# Create `:TriplesNode` in data used as the subject of annotations
|
981
1262
|
start_production(:_ObjectPath_1) do |input, data, callback|
|
982
|
-
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first)
|
983
1263
|
error("ObjectPath", "Expected Verb",
|
984
1264
|
production: :_ObjectPath_1) unless input[:Verb]
|
1265
|
+
pattern = RDF::Query::Pattern.new(input[:Subject], input[:Verb], input[:GraphNode].first, quoted: true)
|
985
1266
|
data[:TriplesNode] = [pattern]
|
986
1267
|
end
|
1268
|
+
|
1269
|
+
#
|
1270
|
+
# Input from `data` is `:pattern`.
|
1271
|
+
# Output to prod_data is `:pattern`.
|
987
1272
|
production(:_ObjectPath_1) do |input, data, callback|
|
988
1273
|
add_prod_datum(:pattern, data[:pattern])
|
989
1274
|
end
|
990
1275
|
|
991
|
-
# [88]
|
992
|
-
#
|
1276
|
+
# [88] Path ::= PathAlternative
|
1277
|
+
#
|
1278
|
+
# Input from data is `:Path`
|
1279
|
+
# Output to input is either `:iri` or `:Path`, depending on if `:Path` is an IRI or not.
|
993
1280
|
production(:Path) do |input, data, callback|
|
994
1281
|
if data[:Path].is_a?(RDF::URI)
|
995
1282
|
input[:iri] = data[:Path]
|
@@ -998,7 +1285,10 @@ module SPARQL::Grammar
|
|
998
1285
|
end
|
999
1286
|
end
|
1000
1287
|
|
1001
|
-
# [89]
|
1288
|
+
# [89] PathAlternative ::= PathSequence ( '|' PathSequence )*
|
1289
|
+
#
|
1290
|
+
# Input from `data` is `:PathSequence` containing one or more path objects.
|
1291
|
+
# 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
1292
|
production(:PathAlternative) do |input, data, callback|
|
1003
1293
|
lhs = Array(data[:PathSequence]).shift
|
1004
1294
|
while data[:PathSequence] && !data[:PathSequence].empty?
|
@@ -1009,11 +1299,17 @@ module SPARQL::Grammar
|
|
1009
1299
|
end
|
1010
1300
|
|
1011
1301
|
# ( '|' PathSequence )*
|
1302
|
+
#
|
1303
|
+
# Input from `data` is `:PathSequence`.
|
1304
|
+
# Output to prod_data is `:PathSequence` which is accumulated.
|
1012
1305
|
production(:_PathAlternative_1) do |input, data, callback|
|
1013
1306
|
input[:PathSequence] += data[:PathSequence]
|
1014
1307
|
end
|
1015
1308
|
|
1016
|
-
# [90]
|
1309
|
+
# [90] PathSequence ::= PathEltOrInverse ( '/' PathEltOrInverse )*
|
1310
|
+
#
|
1311
|
+
# Input from `data` is `:PathSequence` containing one or more path objects.
|
1312
|
+
# 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
1313
|
production(:PathSequence) do |input, data, callback|
|
1018
1314
|
lhs = data[:PathEltOrInverse].shift
|
1019
1315
|
while data[:PathEltOrInverse] && !data[:PathEltOrInverse].empty?
|
@@ -1024,22 +1320,39 @@ module SPARQL::Grammar
|
|
1024
1320
|
end
|
1025
1321
|
|
1026
1322
|
# ( '/' PathEltOrInverse )*
|
1323
|
+
#
|
1324
|
+
# Input from `data` is `:PathSequence`.
|
1325
|
+
# Output to prod_data is `:PathSequence` which is accumulated.
|
1027
1326
|
production(:_PathSequence_1) do |input, data, callback|
|
1028
1327
|
input[:PathEltOrInverse] += data[:PathEltOrInverse]
|
1029
1328
|
end
|
1030
1329
|
|
1031
|
-
# [91]
|
1330
|
+
# [91] PathElt ::= PathPrimary PathMod?
|
1331
|
+
#
|
1332
|
+
# Input from `data` is `:PathMod` and `:PathPrimary`.
|
1333
|
+
# Output to prod_data is `:Path` a possibly modified `:PathPrimary`.
|
1032
1334
|
production(:PathElt) do |input, data, callback|
|
1033
1335
|
path_mod = data.delete(:PathMod) if data.has_key?(:PathMod)
|
1034
1336
|
path_mod ||= data.delete(:MultiplicativeExpression) if data.has_key?(:MultiplicativeExpression)
|
1035
1337
|
path_mod = path_mod.first if path_mod
|
1036
1338
|
|
1037
|
-
res =
|
1038
|
-
|
1339
|
+
res = case path_mod
|
1340
|
+
when SPARQL::Algebra::Expression
|
1341
|
+
# Path range :p{m,n}
|
1342
|
+
path_mod.operands[2] = data[:PathPrimary]
|
1343
|
+
path_mod
|
1344
|
+
when nil
|
1345
|
+
data[:PathPrimary]
|
1346
|
+
else
|
1347
|
+
SPARQL::Algebra::Expression("path#{path_mod}", data[:PathPrimary])
|
1348
|
+
end
|
1039
1349
|
input[:Path] = res
|
1040
1350
|
end
|
1041
1351
|
|
1042
|
-
# [92]
|
1352
|
+
# [92] PathEltOrInverse ::= PathElt | '^' PathElt
|
1353
|
+
#
|
1354
|
+
# Input from `data` is `:reverse` and `:Path`.
|
1355
|
+
# Output to prod_data is `:Path` a possibly reversed `:Path`.
|
1043
1356
|
production(:PathEltOrInverse) do |input, data, callback|
|
1044
1357
|
res = if data[:reverse]
|
1045
1358
|
SPARQL::Algebra::Expression(:reverse, data[:Path])
|
@@ -1049,7 +1362,44 @@ module SPARQL::Grammar
|
|
1049
1362
|
input[:PathEltOrInverse] = [res]
|
1050
1363
|
end
|
1051
1364
|
|
1052
|
-
# [
|
1365
|
+
# [93] PathMod ::= '*' | '?' | '+' | '{' INTEGER? (',' INTEGER?)? '}'
|
1366
|
+
# '{' INTEGER? (',' INTEGER?)? '}'
|
1367
|
+
start_production(:_PathMod_1) do |input, data, callback|
|
1368
|
+
data[:pathRange] = [nil]
|
1369
|
+
end
|
1370
|
+
production(:_PathMod_1) do |input, data, callback|
|
1371
|
+
raise Error, "expect property range to have integral elements" if data[:pathRange].all?(&:nil?)
|
1372
|
+
min, max = data[:pathRange]
|
1373
|
+
min ||= 0
|
1374
|
+
max = min if data[:pathRange].length == 1
|
1375
|
+
max ||= :*
|
1376
|
+
|
1377
|
+
# Last operand added in :PathElt
|
1378
|
+
add_prod_data(:PathMod, SPARQL::Algebra::Expression(:pathRange, min, max, RDF.nil))
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
# INTEGER?
|
1382
|
+
production(:_PathMod_2) do |input, data, callback|
|
1383
|
+
input[:pathRange][0] = data[:literal].object
|
1384
|
+
end
|
1385
|
+
|
1386
|
+
# (',' INTEGER?)
|
1387
|
+
start_production(:_PathMod_4) do |input, data, callback|
|
1388
|
+
data[:pathRange] = [nil, nil]
|
1389
|
+
end
|
1390
|
+
production(:_PathMod_4) do |input, data, callback|
|
1391
|
+
input[:pathRange][1] ||= data.fetch(:pathRange, [0, nil])[1]
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
# INTEGER?
|
1395
|
+
production(:_PathMod_5) do |input, data, callback|
|
1396
|
+
input[:pathRange][1] = data[:literal].object
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
# [94] PathPrimary ::= iri | 'a' | '!' PathNegatedPropertySet | '(' Path ')'
|
1400
|
+
#
|
1401
|
+
# Input from `data` is one of `:Verb`, `:iri`, `:PathNegatedPropertySet`, or `:Path`.
|
1402
|
+
# Output to prod_data is `:PathPrimary`.
|
1053
1403
|
production(:PathPrimary) do |input, data, callback|
|
1054
1404
|
input[:PathPrimary] = case
|
1055
1405
|
when data[:Verb] then data[:Verb]
|
@@ -1059,90 +1409,128 @@ module SPARQL::Grammar
|
|
1059
1409
|
end
|
1060
1410
|
end
|
1061
1411
|
|
1062
|
-
# [95]
|
1412
|
+
# [95] PathNegatedPropertySet ::= PathOneInPropertySet | '(' ( PathOneInPropertySet ( '|' PathOneInPropertySet )* )? ')'
|
1413
|
+
#
|
1414
|
+
# Input from `data` is TODO.
|
1415
|
+
# Output to prod_data is TODO.
|
1063
1416
|
production(:PathNegatedPropertySet) do |input, data, callback|
|
1064
1417
|
input[:Path] = SPARQL::Algebra::Expression(:notoneof, *Array(data[:Path]))
|
1065
1418
|
end
|
1066
1419
|
|
1067
1420
|
# ( '|' PathOneInPropertySet )* )?
|
1421
|
+
#
|
1422
|
+
# Input from `data` is TODO.
|
1423
|
+
# Output to prod_data is TODO.
|
1068
1424
|
production(:_PathNegatedPropertySet_4) do |input, data, callback|
|
1069
1425
|
add_prod_datum(:Path, data[:Path])
|
1070
1426
|
end
|
1071
1427
|
|
1072
|
-
# [96]
|
1428
|
+
# [96] PathOneInPropertySet ::= iri | 'a' | '^' ( iri | 'a' )
|
1429
|
+
#
|
1430
|
+
# Input from `data` is TODO.
|
1431
|
+
# Output to prod_data is TODO.
|
1073
1432
|
production(:PathOneInPropertySet) do |input, data, callback|
|
1074
1433
|
term = (Array(data[:iri]) || data[:Verb]).first
|
1075
1434
|
term = SPARQL::Algebra::Expression(:reverse, term) if data[:reverse]
|
1076
1435
|
input[:Path] = [term]
|
1077
1436
|
end
|
1078
1437
|
|
1079
|
-
# [98]
|
1438
|
+
# [98] TriplesNode ::= Collection | BlankNodePropertyList
|
1080
1439
|
start_production(:TriplesNode) do |input, data, callback|
|
1081
1440
|
# Called after Verb. The prod_data stack should have Subject and Verb elements
|
1082
1441
|
data[:TriplesNode] = bnode
|
1083
1442
|
end
|
1443
|
+
|
1444
|
+
#
|
1445
|
+
# Input from `data` is TODO.
|
1446
|
+
# Output to prod_data is TODO.
|
1084
1447
|
production(:TriplesNode) do |input, data, callback|
|
1085
1448
|
add_prod_datum(:pattern, data[:pattern])
|
1086
1449
|
add_prod_datum(:TriplesNode, data[:TriplesNode])
|
1087
1450
|
end
|
1088
1451
|
|
1089
|
-
# [100]
|
1452
|
+
# [100] TriplesNodePath ::= CollectionPath | BlankNodePropertyListPath
|
1090
1453
|
start_production(:TriplesNodePath) do |input, data, callback|
|
1091
1454
|
# Called after Verb. The prod_data stack should have Subject and Verb elements
|
1092
1455
|
data[:TriplesNode] = bnode
|
1093
1456
|
end
|
1457
|
+
|
1458
|
+
#
|
1459
|
+
# Input from `data` is TODO.
|
1460
|
+
# Output to prod_data is TODO.
|
1094
1461
|
production(:TriplesNodePath) do |input, data, callback|
|
1095
1462
|
add_prod_datum(:pattern, data[:pattern])
|
1096
|
-
add_prod_datum(:path, data[:path])
|
1097
1463
|
add_prod_datum(:TriplesNode, data[:TriplesNode])
|
1098
1464
|
end
|
1099
1465
|
|
1100
|
-
# [102]
|
1466
|
+
# [102] Collection ::= '(' GraphNode+ ')'
|
1101
1467
|
start_production(:Collection) do |input, data, callback|
|
1102
1468
|
# Tells the TriplesNode production to collect and not generate statements
|
1103
|
-
data[:Collection] =
|
1469
|
+
data[:Collection] = input[:TriplesNode]
|
1104
1470
|
end
|
1471
|
+
|
1472
|
+
#
|
1473
|
+
# Input from `data` is TODO.
|
1474
|
+
# Output to prod_data is TODO.
|
1105
1475
|
production(:Collection) do |input, data, callback|
|
1106
1476
|
expand_collection(data)
|
1107
1477
|
end
|
1108
1478
|
|
1109
|
-
# [103]
|
1479
|
+
# [103] CollectionPath ::= "(" GraphNodePath+ ")"
|
1110
1480
|
start_production(:CollectionPath) do |input, data, callback|
|
1111
1481
|
# Tells the TriplesNode production to collect and not generate statements
|
1112
|
-
data[:Collection] =
|
1482
|
+
data[:Collection] = input[:TriplesNode]
|
1113
1483
|
end
|
1484
|
+
|
1485
|
+
#
|
1486
|
+
# Input from `data` is TODO.
|
1487
|
+
# Output to prod_data is TODO.
|
1114
1488
|
production(:CollectionPath) do |input, data, callback|
|
1115
1489
|
expand_collection(data)
|
1116
|
-
add_prod_datum(:path, data[:path])
|
1117
1490
|
end
|
1118
1491
|
|
1119
|
-
# [104]
|
1492
|
+
# [104] GraphNode ::= VarOrTermOrQuotedTP | TriplesNode
|
1493
|
+
#
|
1494
|
+
# Input from `data` is TODO.
|
1495
|
+
# Output to prod_data is TODO.
|
1120
1496
|
production(:GraphNode) do |input, data, callback|
|
1121
1497
|
term = data[:VarOrTermOrQuotedTP] || data[:TriplesNode]
|
1122
1498
|
add_prod_datum(:pattern, data[:pattern])
|
1123
1499
|
add_prod_datum(:GraphNode, term)
|
1124
1500
|
end
|
1125
1501
|
|
1126
|
-
# [105]
|
1502
|
+
# [105] GraphNodePath ::= VarOrTermOrQuotedTP | TriplesNodePath
|
1503
|
+
#
|
1504
|
+
# Input from `data` is either `:VarOrTermOrQUotedTP` or `:TriplesNode`.
|
1505
|
+
# Additionally, `:pattern`. Also, `:pattern` and `:path`.
|
1506
|
+
# Output to prod_data is `:GraphNode`, along with any `:path` and `:pattern`.
|
1127
1507
|
production(:GraphNodePath) do |input, data, callback|
|
1128
1508
|
term = data[:VarOrTermOrQuotedTP] || data[:TriplesNode]
|
1129
1509
|
add_prod_datum(:pattern, data[:pattern])
|
1130
|
-
add_prod_datum(:path, data[:path])
|
1131
1510
|
add_prod_datum(:GraphNode, term)
|
1132
1511
|
end
|
1133
1512
|
|
1134
|
-
# [106s]
|
1513
|
+
# [106s] VarOrTermOrQuotedTP ::= Var | GraphTerm | QuotedTP
|
1514
|
+
#
|
1515
|
+
# Input from `data` is TODO.
|
1516
|
+
# Output to prod_data is TODO.
|
1135
1517
|
production(:VarOrTermOrQuotedTP) do |input, data, callback|
|
1136
1518
|
data.values.each {|v| add_prod_datum(:VarOrTermOrQuotedTP, v)}
|
1137
1519
|
end
|
1138
1520
|
|
1139
|
-
# [107]
|
1521
|
+
# [107] VarOrIri ::= Var | iri
|
1522
|
+
#
|
1523
|
+
# Input from `data` is TODO.
|
1524
|
+
# Output to prod_data is TODO.
|
1140
1525
|
production(:VarOrIri) do |input, data, callback|
|
1141
1526
|
data.values.each {|v| add_prod_datum(:VarOrIri, v)}
|
1142
1527
|
end
|
1143
1528
|
|
1144
|
-
# [109]
|
1145
|
-
# |
|
1529
|
+
# [109] GraphTerm ::= iri | RDFLiteral | NumericLiteral
|
1530
|
+
# | BooleanLiteral | BlankNode | NIL
|
1531
|
+
#
|
1532
|
+
# Input from `data` is one of `:iri`, `:literal`, `:BlankNode`, or `:NIL`.
|
1533
|
+
# Output to prod_data is `:GraphTerm` created from the data.
|
1146
1534
|
production(:GraphTerm) do |input, data, callback|
|
1147
1535
|
add_prod_datum(:GraphTerm,
|
1148
1536
|
data[:iri] ||
|
@@ -1151,42 +1539,60 @@ module SPARQL::Grammar
|
|
1151
1539
|
data[:NIL])
|
1152
1540
|
end
|
1153
1541
|
|
1154
|
-
# [110]
|
1542
|
+
# [110] Expression ::= ConditionalOrExpression
|
1543
|
+
#
|
1544
|
+
# Input from `data` is TODO.
|
1545
|
+
# Output to prod_data is TODO.
|
1155
1546
|
production(:Expression) do |input, data, callback|
|
1156
1547
|
add_prod_datum(:Expression, data[:Expression])
|
1157
1548
|
end
|
1158
1549
|
|
1159
|
-
# [111]
|
1160
|
-
#
|
1550
|
+
# [111] ConditionalOrExpression ::= ConditionalAndExpression
|
1551
|
+
# ( '||' ConditionalAndExpression )*
|
1552
|
+
#
|
1553
|
+
# Input from `data` is TODO.
|
1554
|
+
# Output to prod_data is TODO.
|
1161
1555
|
production(:ConditionalOrExpression) do |input, data, callback|
|
1162
1556
|
add_operator_expressions(:_OR, data)
|
1163
1557
|
end
|
1164
1558
|
|
1165
1559
|
# ( '||' ConditionalAndExpression )*
|
1560
|
+
#
|
1561
|
+
# Input from `data` is TODO.
|
1562
|
+
# Output to prod_data is TODO.
|
1166
1563
|
production(:_ConditionalOrExpression_1) do |input, data, callback|
|
1167
1564
|
accumulate_operator_expressions(:ConditionalOrExpression, :_OR, data)
|
1168
1565
|
end
|
1169
1566
|
|
1170
|
-
# [112]
|
1567
|
+
# [112] ConditionalAndExpression ::= ValueLogical ( '&&' ValueLogical )*
|
1568
|
+
#
|
1569
|
+
# Input from `data` is TODO.
|
1570
|
+
# Output to prod_data is TODO.
|
1171
1571
|
production(:ConditionalAndExpression) do |input, data, callback|
|
1172
1572
|
add_operator_expressions(:_AND, data)
|
1173
1573
|
end
|
1174
1574
|
|
1175
1575
|
# ( '||' ConditionalAndExpression )*
|
1576
|
+
#
|
1577
|
+
# Input from `data` is TODO.
|
1578
|
+
# Output to prod_data is TODO.
|
1176
1579
|
production(:_ConditionalAndExpression_1) do |input, data, callback|
|
1177
1580
|
accumulate_operator_expressions(:ConditionalAndExpression, :_AND, data)
|
1178
1581
|
end
|
1179
1582
|
|
1180
|
-
# [114]
|
1181
|
-
#
|
1182
|
-
#
|
1183
|
-
#
|
1184
|
-
#
|
1185
|
-
#
|
1186
|
-
#
|
1187
|
-
#
|
1188
|
-
#
|
1189
|
-
#
|
1583
|
+
# [114] RelationalExpression ::= NumericExpression
|
1584
|
+
# ( '=' NumericExpression
|
1585
|
+
# | '!=' NumericExpression
|
1586
|
+
# | '<' NumericExpression
|
1587
|
+
# | '>' NumericExpression
|
1588
|
+
# | '<=' NumericExpression
|
1589
|
+
# | '>=' NumericExpression
|
1590
|
+
# | 'IN' ExpressionList
|
1591
|
+
# | 'NOT' 'IN' ExpressionList
|
1592
|
+
# )?
|
1593
|
+
#
|
1594
|
+
# Input from `data` is TODO.
|
1595
|
+
# Output to prod_data is TODO.
|
1190
1596
|
production(:RelationalExpression) do |input, data, callback|
|
1191
1597
|
if data[:_Compare_Numeric]
|
1192
1598
|
add_prod_datum(:Expression, SPARQL::Algebra::Expression.for(data[:_Compare_Numeric].insert(1, *data[:Expression])))
|
@@ -1203,6 +1609,9 @@ module SPARQL::Grammar
|
|
1203
1609
|
end
|
1204
1610
|
|
1205
1611
|
# ( '=' NumericExpression | '!=' NumericExpression | ... )?
|
1612
|
+
#
|
1613
|
+
# Input from `data` is TODO.
|
1614
|
+
# Output to prod_data is TODO.
|
1206
1615
|
production(:_RelationalExpression_1) do |input, data, callback|
|
1207
1616
|
if data[:RelationalExpression]
|
1208
1617
|
add_prod_datum(:_Compare_Numeric, data[:RelationalExpression] + data[:Expression])
|
@@ -1214,11 +1623,17 @@ module SPARQL::Grammar
|
|
1214
1623
|
end
|
1215
1624
|
|
1216
1625
|
# 'IN' ExpressionList
|
1626
|
+
#
|
1627
|
+
# Input from `data` is TODO.
|
1628
|
+
# Output to prod_data is TODO.
|
1217
1629
|
production(:_RelationalExpression_9) do |input, data, callback|
|
1218
1630
|
add_prod_datum(:in, data[:ExpressionList])
|
1219
1631
|
end
|
1220
1632
|
|
1221
1633
|
# 'NOT' 'IN' ExpressionList
|
1634
|
+
#
|
1635
|
+
# Input from `data` is TODO.
|
1636
|
+
# Output to prod_data is TODO.
|
1222
1637
|
production(:_RelationalExpression_10) do |input, data, callback|
|
1223
1638
|
add_prod_datum(:notin, data[:ExpressionList])
|
1224
1639
|
end
|
@@ -1226,10 +1641,14 @@ module SPARQL::Grammar
|
|
1226
1641
|
# [116] AdditiveExpression ::= MultiplicativeExpression
|
1227
1642
|
# ( '+' MultiplicativeExpression
|
1228
1643
|
# | '-' MultiplicativeExpression
|
1229
|
-
# | ( NumericLiteralPositive
|
1644
|
+
# | ( NumericLiteralPositive
|
1645
|
+
# | NumericLiteralNegative )
|
1230
1646
|
# ( ( '*' UnaryExpression )
|
1231
1647
|
# | ( '/' UnaryExpression ) )?
|
1232
1648
|
# )*
|
1649
|
+
#
|
1650
|
+
# Input from `data` is TODO.
|
1651
|
+
# Output to prod_data is TODO.
|
1233
1652
|
production(:AdditiveExpression) do |input, data, callback|
|
1234
1653
|
add_operator_expressions(:_Add_Sub, data)
|
1235
1654
|
end
|
@@ -1240,11 +1659,17 @@ module SPARQL::Grammar
|
|
1240
1659
|
# ( ( '*' UnaryExpression )
|
1241
1660
|
# | ( '/' UnaryExpression ) )?
|
1242
1661
|
# )*
|
1662
|
+
#
|
1663
|
+
# Input from `data` is TODO.
|
1664
|
+
# Output to prod_data is TODO.
|
1243
1665
|
production(:_AdditiveExpression_1) do |input, data, callback|
|
1244
1666
|
accumulate_operator_expressions(:AdditiveExpression, :_Add_Sub, data)
|
1245
1667
|
end
|
1246
1668
|
|
1247
1669
|
# | ( NumericLiteralPositive | NumericLiteralNegative )
|
1670
|
+
#
|
1671
|
+
# Input from `data` is TODO.
|
1672
|
+
# Output to prod_data is TODO.
|
1248
1673
|
production(:_AdditiveExpression_7) do |input, data, callback|
|
1249
1674
|
lit = data[:literal]
|
1250
1675
|
val = lit.to_s
|
@@ -1253,23 +1678,32 @@ module SPARQL::Grammar
|
|
1253
1678
|
add_prod_datum(:Expression, [lit.class.new(val)])
|
1254
1679
|
end
|
1255
1680
|
|
1256
|
-
# [117]
|
1257
|
-
#
|
1258
|
-
#
|
1681
|
+
# [117] MultiplicativeExpression ::= UnaryExpression
|
1682
|
+
# ( '*' UnaryExpression
|
1683
|
+
# | '/' UnaryExpression )*
|
1684
|
+
#
|
1685
|
+
# Input from `data` is TODO.
|
1686
|
+
# Output to prod_data is TODO.
|
1259
1687
|
production(:MultiplicativeExpression) do |input, data, callback|
|
1260
1688
|
add_operator_expressions(:_Mul_Div, data)
|
1261
1689
|
end
|
1262
1690
|
|
1263
1691
|
# ( '*' UnaryExpression
|
1264
1692
|
# | '/' UnaryExpression )*
|
1693
|
+
#
|
1694
|
+
# Input from `data` is TODO.
|
1695
|
+
# Output to prod_data is TODO.
|
1265
1696
|
production(:_MultiplicativeExpression_1) do |input, data, callback|
|
1266
1697
|
accumulate_operator_expressions(:MultiplicativeExpression, :_Mul_Div, data)
|
1267
1698
|
end
|
1268
1699
|
|
1269
|
-
# [118]
|
1270
|
-
#
|
1271
|
-
#
|
1272
|
-
#
|
1700
|
+
# [118] UnaryExpression ::= '!' PrimaryExpression
|
1701
|
+
# | '+' PrimaryExpression
|
1702
|
+
# | '-' PrimaryExpression
|
1703
|
+
# | PrimaryExpression
|
1704
|
+
#
|
1705
|
+
# Input from `data` is TODO.
|
1706
|
+
# Output to prod_data is TODO.
|
1273
1707
|
production(:UnaryExpression) do |input, data, callback|
|
1274
1708
|
case data[:UnaryExpression]
|
1275
1709
|
when ["!"]
|
@@ -1286,11 +1720,14 @@ module SPARQL::Grammar
|
|
1286
1720
|
end
|
1287
1721
|
end
|
1288
1722
|
|
1289
|
-
# [119]
|
1290
|
-
#
|
1291
|
-
#
|
1292
|
-
#
|
1293
|
-
#
|
1723
|
+
# [119] PrimaryExpression ::= BrackettedExpression | BuiltInCall
|
1724
|
+
# | iriOrFunction | RDFLiteral
|
1725
|
+
# | NumericLiteral | BooleanLiteral
|
1726
|
+
# | Var
|
1727
|
+
# | ExprQuotedTP
|
1728
|
+
#
|
1729
|
+
# Input from `data` is TODO.
|
1730
|
+
# Output to prod_data is TODO.
|
1294
1731
|
production(:PrimaryExpression) do |input, data, callback|
|
1295
1732
|
if data[:Expression]
|
1296
1733
|
add_prod_datum(:Expression, data[:Expression])
|
@@ -1312,62 +1749,65 @@ module SPARQL::Grammar
|
|
1312
1749
|
add_prod_datum(:UnaryExpression, data[:UnaryExpression])
|
1313
1750
|
end
|
1314
1751
|
|
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
|
-
#
|
1752
|
+
# [121] BuiltInCall ::= Aggregate
|
1753
|
+
# | 'STR' '(' Expression ')'
|
1754
|
+
# | 'LANG' '(' Expression ')'
|
1755
|
+
# | 'LANGMATCHES' '(' Expression ',' Expression ')'
|
1756
|
+
# | 'DATATYPE' '(' Expression ')'
|
1757
|
+
# | 'BOUND' '(' Var ')'
|
1758
|
+
# | 'IRI' '(' Expression ')'
|
1759
|
+
# | 'URI' '(' Expression ')'
|
1760
|
+
# | 'BNODE' ( '(' Expression ')' | NIL )
|
1761
|
+
# | 'RAND' NIL
|
1762
|
+
# | 'ABS' '(' Expression ')'
|
1763
|
+
# | 'CEIL' '(' Expression ')'
|
1764
|
+
# | 'FLOOR' '(' Expression ')'
|
1765
|
+
# | 'ROUND' '(' Expression ')'
|
1766
|
+
# | 'CONCAT' ExpressionList
|
1767
|
+
# | SubstringExpression
|
1768
|
+
# | 'STRLEN' '(' Expression ')'
|
1769
|
+
# | StrReplaceExpression
|
1770
|
+
# | 'UCASE' '(' Expression ')'
|
1771
|
+
# | 'LCASE' '(' Expression ')'
|
1772
|
+
# | 'ENCODE_FOR_URI' '(' Expression ')'
|
1773
|
+
# | 'CONTAINS' '(' Expression ',' Expression ')'
|
1774
|
+
# | 'STRSTARTS' '(' Expression ',' Expression ')'
|
1775
|
+
# | 'STRENDS' '(' Expression ',' Expression ')'
|
1776
|
+
# | 'STRBEFORE' '(' Expression ',' Expression ')'
|
1777
|
+
# | 'STRAFTER' '(' Expression ',' Expression ')'
|
1778
|
+
# | 'YEAR' '(' Expression ')'
|
1779
|
+
# | 'MONTH' '(' Expression ')'
|
1780
|
+
# | 'DAY' '(' Expression ')'
|
1781
|
+
# | 'HOURS' '(' Expression ')'
|
1782
|
+
# | 'MINUTES' '(' Expression ')'
|
1783
|
+
# | 'SECONDS' '(' Expression ')'
|
1784
|
+
# | 'TIMEZONE' '(' Expression ')'
|
1785
|
+
# | 'TZ' '(' Expression ')'
|
1786
|
+
# | 'NOW' NIL
|
1787
|
+
# | 'UUID' NIL
|
1788
|
+
# | 'STRUUID' NIL
|
1789
|
+
# | 'MD5' '(' Expression ')'
|
1790
|
+
# | 'SHA1' '(' Expression ')'
|
1791
|
+
# | 'SHA224' '(' Expression ')'
|
1792
|
+
# | 'SHA256' '(' Expression ')'
|
1793
|
+
# | 'SHA384' '(' Expression ')'
|
1794
|
+
# | 'SHA512' '(' Expression ')'
|
1795
|
+
# | 'COALESCE' ExpressionList
|
1796
|
+
# | 'IF' '(' Expression ',' Expression ',' Expression ')'
|
1797
|
+
# | 'STRLANG' '(' Expression ',' Expression ')'
|
1798
|
+
# | 'STRDT' '(' Expression ',' Expression ')'
|
1799
|
+
# | 'sameTerm' '(' Expression ',' Expression ')'
|
1800
|
+
# | 'isIRI' '(' Expression ')'
|
1801
|
+
# | 'isURI' '(' Expression ')'
|
1802
|
+
# | 'isBLANK' '(' Expression ')'
|
1803
|
+
# | 'isLITERAL' '(' Expression ')'
|
1804
|
+
# | 'isNUMERIC' '(' Expression ')'
|
1805
|
+
# | RegexExpression
|
1806
|
+
# | ExistsFunc
|
1807
|
+
# | NotExistsFunc
|
1808
|
+
#
|
1809
|
+
# Input from `data` is TODO.
|
1810
|
+
# Output to prod_data is TODO.
|
1371
1811
|
production(:BuiltInCall) do |input, data, callback|
|
1372
1812
|
input[:BuiltInCall] = if builtin = data.keys.detect {|k| BUILTINS.include?(k)}
|
1373
1813
|
SPARQL::Algebra::Expression.for(
|
@@ -1384,45 +1824,63 @@ module SPARQL::Grammar
|
|
1384
1824
|
end
|
1385
1825
|
end
|
1386
1826
|
|
1387
|
-
# [122]
|
1388
|
-
#
|
1827
|
+
# [122] RegexExpression ::= 'REGEX' '(' Expression ',' Expression
|
1828
|
+
# ( ',' Expression )? ')'
|
1829
|
+
#
|
1830
|
+
# Input from `data` is TODO.
|
1831
|
+
# Output to prod_data is TODO.
|
1389
1832
|
production(:RegexExpression) do |input, data, callback|
|
1390
1833
|
add_prod_datum(:regex, data[:Expression])
|
1391
1834
|
end
|
1392
1835
|
|
1393
|
-
# [123]
|
1394
|
-
#
|
1395
|
-
#
|
1836
|
+
# [123] SubstringExpression ::= 'SUBSTR'
|
1837
|
+
# '(' Expression ',' Expression
|
1838
|
+
# ( ',' Expression )? ')'
|
1839
|
+
#
|
1840
|
+
# Input from `data` is TODO.
|
1841
|
+
# Output to prod_data is TODO.
|
1396
1842
|
production(:SubstringExpression) do |input, data, callback|
|
1397
1843
|
add_prod_datum(:substr, data[:Expression])
|
1398
1844
|
end
|
1399
1845
|
|
1400
|
-
# [124] StrReplaceExpression
|
1401
|
-
#
|
1402
|
-
#
|
1403
|
-
#
|
1846
|
+
# [124] StrReplaceExpression ::= 'REPLACE'
|
1847
|
+
# '(' Expression ','
|
1848
|
+
# Expression ',' Expression
|
1849
|
+
# ( ',' Expression )? ')'
|
1850
|
+
#
|
1851
|
+
# Input from `data` is TODO.
|
1852
|
+
# Output to prod_data is TODO.
|
1404
1853
|
production(:StrReplaceExpression) do |input, data, callback|
|
1405
1854
|
add_prod_datum(:replace, data[:Expression])
|
1406
1855
|
end
|
1407
1856
|
|
1408
|
-
# [125]
|
1857
|
+
# [125] ExistsFunc ::= 'EXISTS' GroupGraphPattern
|
1858
|
+
#
|
1859
|
+
# Input from `data` is TODO.
|
1860
|
+
# Output to prod_data is TODO.
|
1409
1861
|
production(:ExistsFunc) do |input, data, callback|
|
1410
1862
|
add_prod_datum(:exists, data[:query])
|
1411
1863
|
end
|
1412
1864
|
|
1413
|
-
# [126]
|
1865
|
+
# [126] NotExistsFunc ::= 'NOT' 'EXISTS' GroupGraphPattern
|
1866
|
+
#
|
1867
|
+
# Input from `data` is TODO.
|
1868
|
+
# Output to prod_data is TODO.
|
1414
1869
|
production(:NotExistsFunc) do |input, data, callback|
|
1415
1870
|
add_prod_datum(:notexists, data[:query])
|
1416
1871
|
end
|
1417
1872
|
|
1418
|
-
# [127] Aggregate
|
1419
|
-
#
|
1420
|
-
#
|
1421
|
-
#
|
1422
|
-
#
|
1423
|
-
#
|
1424
|
-
#
|
1425
|
-
#
|
1873
|
+
# [127] Aggregate ::= 'COUNT' '(' 'DISTINCT'? ( '*' | Expression ) ')'
|
1874
|
+
# | 'SUM' '(' 'DISTINCT'? Expression ')'
|
1875
|
+
# | 'MIN' '(' 'DISTINCT'? Expression ')'
|
1876
|
+
# | 'MAX' '(' 'DISTINCT'? Expression ')'
|
1877
|
+
# | 'AVG' '(' 'DISTINCT'? Expression ')'
|
1878
|
+
# | 'SAMPLE' '(' 'DISTINCT'? Expression ')'
|
1879
|
+
# | 'GROUP_CONCAT' '(' 'DISTINCT'? Expression
|
1880
|
+
# ( ';' 'SEPARATOR' '=' String )? ')'
|
1881
|
+
#
|
1882
|
+
# Input from `data` is TODO.
|
1883
|
+
# Output to prod_data is TODO.
|
1426
1884
|
production(:Aggregate) do |input, data, callback|
|
1427
1885
|
if aggregate_rule = data.keys.detect {|k| AGGREGATE_RULES.include?(k)}
|
1428
1886
|
parts = [aggregate_rule]
|
@@ -1433,7 +1891,10 @@ module SPARQL::Grammar
|
|
1433
1891
|
end
|
1434
1892
|
end
|
1435
1893
|
|
1436
|
-
# [128]
|
1894
|
+
# [128] iriOrFunction ::= iri ArgList?
|
1895
|
+
#
|
1896
|
+
# Input from `data` is TODO.
|
1897
|
+
# Output to prod_data is TODO.
|
1437
1898
|
production(:iriOrFunction) do |input, data, callback|
|
1438
1899
|
if data.has_key?(:ArgList)
|
1439
1900
|
# Function is (func arg1 arg2 ...)
|
@@ -1443,20 +1904,26 @@ module SPARQL::Grammar
|
|
1443
1904
|
end
|
1444
1905
|
end
|
1445
1906
|
|
1446
|
-
# [129]
|
1907
|
+
# [129] RDFLiteral ::= String ( LANGTAG | ( '^^' iri ) )?
|
1908
|
+
#
|
1909
|
+
# Input from `data` is TODO.
|
1910
|
+
# Output to prod_data is TODO.
|
1447
1911
|
production(:RDFLiteral) do |input, data, callback|
|
1448
1912
|
if data[:string]
|
1449
1913
|
lit = data.dup
|
1450
1914
|
str = lit.delete(:string)
|
1451
1915
|
lit[:datatype] = lit.delete(:iri) if lit[:iri]
|
1452
|
-
lit[:language] = lit.delete(:language).
|
1916
|
+
lit[:language] = lit.delete(:language).downcase if lit[:language]
|
1453
1917
|
input[:literal] = RDF::Literal.new(str, **lit) if str
|
1454
1918
|
end
|
1455
1919
|
end
|
1456
1920
|
|
1457
|
-
# [132]
|
1458
|
-
#
|
1459
|
-
#
|
1921
|
+
# [132] NumericLiteralPositive ::= INTEGER_POSITIVE
|
1922
|
+
# | DECIMAL_POSITIVE
|
1923
|
+
# | DOUBLE_POSITIVE
|
1924
|
+
#
|
1925
|
+
# Input from `data` is TODO.
|
1926
|
+
# Output to prod_data is TODO.
|
1460
1927
|
production(:NumericLiteralPositive) do |input, data, callback|
|
1461
1928
|
num = data.values.flatten.last
|
1462
1929
|
input[:literal] = num
|
@@ -1465,9 +1932,12 @@ module SPARQL::Grammar
|
|
1465
1932
|
add_prod_datum(:UnaryExpression, data[:UnaryExpression])
|
1466
1933
|
end
|
1467
1934
|
|
1468
|
-
# [133]
|
1469
|
-
#
|
1470
|
-
#
|
1935
|
+
# [133] NumericLiteralNegative ::= INTEGER_NEGATIVE
|
1936
|
+
# | DECIMAL_NEGATIVE
|
1937
|
+
# | DOUBLE_NEGATIVE
|
1938
|
+
#
|
1939
|
+
# Input from `data` is TODO.
|
1940
|
+
# Output to prod_data is TODO.
|
1471
1941
|
production(:NumericLiteralNegative) do |input, data, callback|
|
1472
1942
|
num = data.values.flatten.last
|
1473
1943
|
input[:literal] = num
|
@@ -1477,61 +1947,81 @@ module SPARQL::Grammar
|
|
1477
1947
|
end
|
1478
1948
|
|
1479
1949
|
# [174] QuotedTP ::= '<<' qtSubjectOrObject Verb qtSubjectOrObject '>>'
|
1950
|
+
#
|
1951
|
+
# Input from `data` is `:qtSubjectOrObject` from which subject and object are extracted and `:Verb` from which predicate is extracted.
|
1952
|
+
# Output to prod_data is `:QuotedTP` containing subject, predicate, and object.
|
1480
1953
|
production(:QuotedTP) do |input, data, callback|
|
1481
1954
|
subject, object = data[:qtSubjectOrObject]
|
1482
1955
|
predicate = data[:Verb]
|
1483
1956
|
add_pattern(:QuotedTP,
|
1484
1957
|
subject: subject,
|
1485
1958
|
predicate: predicate,
|
1486
|
-
object: object
|
1959
|
+
object: object,
|
1960
|
+
quoted: true)
|
1487
1961
|
end
|
1488
1962
|
|
1489
1963
|
# [175] QuotedTriple ::= '<<' DataValueTerm (iri | 'a') DataValueTerm '>>'
|
1964
|
+
#
|
1965
|
+
# Input from `data` is TODO.
|
1966
|
+
# Output to prod_data is TODO.
|
1490
1967
|
production(:QuotedTriple) do |input, data, callback|
|
1491
1968
|
subject, object = data[:DataValueTerm]
|
1492
1969
|
predicate = data[:iri]
|
1493
1970
|
add_pattern(:QuotedTriple,
|
1494
1971
|
subject: subject,
|
1495
1972
|
predicate: predicate,
|
1496
|
-
object: object
|
1973
|
+
object: object,
|
1974
|
+
quoted: true)
|
1497
1975
|
end
|
1498
1976
|
|
1499
|
-
# [176] qtSubjectOrObject ::=
|
1500
|
-
#
|
1977
|
+
# [176] qtSubjectOrObject ::= Var | BlankNode | iri | RDFLiteral
|
1978
|
+
# | NumericLiteral | BooleanLiteral | QuotedTP
|
1979
|
+
#
|
1980
|
+
# Input from `data` is TODO.
|
1981
|
+
# Output to prod_data is TODO.
|
1501
1982
|
production(:qtSubjectOrObject) do |input, data, callback|
|
1502
1983
|
data.values.each {|v| add_prod_datum(:qtSubjectOrObject, v)}
|
1503
1984
|
end
|
1504
1985
|
|
1505
|
-
# [177] DataValueTerm
|
1986
|
+
# [177] DataValueTerm ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | QuotedTriple
|
1987
|
+
#
|
1988
|
+
# Input from `data` is TODO.
|
1989
|
+
# Output to prod_data is TODO.
|
1506
1990
|
production(:DataValueTerm) do |input, data, callback|
|
1507
1991
|
add_prod_datum :DataValueTerm, data.values.first
|
1508
1992
|
end
|
1509
1993
|
|
1510
|
-
# [180]
|
1994
|
+
# [180] AnnotationPatternPath ::= '{|' PropertyListPathNotEmpty '|}'
|
1511
1995
|
start_production(:AnnotationPatternPath) do |input, data, callback|
|
1512
1996
|
data[:TriplesNode] = input[:TriplesNode]
|
1513
1997
|
end
|
1998
|
+
|
1999
|
+
#
|
2000
|
+
# Add `:TriplesNode` as subject of collected patterns
|
2001
|
+
# Input from `data` is `:pattern`.
|
2002
|
+
# Output to prod_data is `:pattern`.
|
1514
2003
|
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
|
2004
|
+
add_prod_datum(:pattern, data[:pattern])
|
1522
2005
|
end
|
1523
2006
|
|
1524
2007
|
# [181] ExprQuotedTP ::= '<<' ExprVarOrTerm Verb ExprVarOrTerm '>>'
|
2008
|
+
#
|
2009
|
+
# Input from `data` is TODO.
|
2010
|
+
# Output to prod_data is TODO.
|
1525
2011
|
production(:ExprQuotedTP) do |input, data, callback|
|
1526
2012
|
subject, object = data[:ExprVarOrTerm]
|
1527
2013
|
predicate = data[:Verb]
|
1528
2014
|
add_pattern(:ExprQuotedTP,
|
1529
2015
|
subject: subject,
|
1530
2016
|
predicate: predicate,
|
1531
|
-
object: object
|
2017
|
+
object: object,
|
2018
|
+
quoted: true)
|
1532
2019
|
end
|
1533
2020
|
|
1534
|
-
# [182] ExprVarOrTerm ::=
|
2021
|
+
# [182] ExprVarOrTerm ::= iri | RDFLiteral | NumericLiteral | BooleanLiteral | Var | ExprQuotedTP
|
2022
|
+
#
|
2023
|
+
# Input from `data` is TODO.
|
2024
|
+
# Output to prod_data is TODO.
|
1535
2025
|
production(:ExprVarOrTerm) do |input, data, callback|
|
1536
2026
|
data.values.each {|v| add_prod_datum(:ExprVarOrTerm, v)}
|
1537
2027
|
end
|
@@ -1541,20 +2031,23 @@ module SPARQL::Grammar
|
|
1541
2031
|
#
|
1542
2032
|
# @param [String, IO, StringIO, #to_s] input
|
1543
2033
|
# @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)
|
2034
|
+
# @option options [Boolean] :all_vars (false)
|
2035
|
+
# If `true`, emits on empty `project` operator when parsing `SELECT *`, which will emit all in-scope variables, rather than just those used in solutions.
|
2036
|
+
# In the next minor release, the default for this option will change to `true`.
|
1548
2037
|
# @option options [#to_s] :anon_base ("b0")
|
1549
2038
|
# Basis for generating anonymous Nodes
|
2039
|
+
# @option options [#to_s] :base_uri (nil)
|
2040
|
+
# the base URI to use when resolving relative URIs (for acessing intermediate parser productions)
|
2041
|
+
# @option options [Logger, #write, #<<] :logger
|
2042
|
+
# Record error/info/debug output
|
2043
|
+
# @option options [Hash] :prefixes (Hash.new)
|
2044
|
+
# the prefix mappings to use (for acessing intermediate parser productions)
|
1550
2045
|
# @option options [Boolean] :resolve_iris (false)
|
1551
2046
|
# Resolve prefix and relative IRIs, otherwise, when serializing the parsed SSE
|
1552
2047
|
# as S-Expressions, use the original prefixed and relative URIs along with `base` and `prefix`
|
1553
2048
|
# definitions.
|
1554
2049
|
# @option options [Boolean] :validate (false)
|
1555
2050
|
# whether to validate the parsed statements and values
|
1556
|
-
# @option options [Logger, #write, #<<] :logger
|
1557
|
-
# Record error/info/debug output
|
1558
2051
|
# @yield [parser] `self`
|
1559
2052
|
# @yieldparam [SPARQL::Grammar::Parser] parser
|
1560
2053
|
# @yieldreturn [void] ignored
|
@@ -1615,7 +2108,7 @@ module SPARQL::Grammar
|
|
1615
2108
|
#
|
1616
2109
|
# @param [Symbol, #to_s] prod The starting production for the parser.
|
1617
2110
|
# It may be a URI from the grammar, or a symbol representing the local_name portion of the grammar URI.
|
1618
|
-
# @return [
|
2111
|
+
# @return [RDF::Queryable]
|
1619
2112
|
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
1620
2113
|
# @see https://axel.deri.ie/sparqltutorial/ESWC2007_SPARQL_Tutorial_unit2b.pdf
|
1621
2114
|
def parse(prod = START)
|
@@ -1811,9 +2304,7 @@ module SPARQL::Grammar
|
|
1811
2304
|
# If we have a base URI, use that when constructing a new URI
|
1812
2305
|
value = RDF::URI(value)
|
1813
2306
|
if base_uri && value.relative?
|
1814
|
-
|
1815
|
-
#u.lexical = "<#{value}>" unless resolve_iris?
|
1816
|
-
#u
|
2307
|
+
base_uri.join(value)
|
1817
2308
|
else
|
1818
2309
|
value
|
1819
2310
|
end
|
@@ -1823,10 +2314,7 @@ module SPARQL::Grammar
|
|
1823
2314
|
base = prefix(prefix).to_s
|
1824
2315
|
suffix = suffix.to_s.sub(/^\#/, "") if base.index("#")
|
1825
2316
|
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
|
2317
|
+
iri(base + suffix.to_s)
|
1830
2318
|
end
|
1831
2319
|
|
1832
2320
|
# Create a literal
|
@@ -1869,10 +2357,12 @@ module SPARQL::Grammar
|
|
1869
2357
|
# add a pattern
|
1870
2358
|
#
|
1871
2359
|
# @param [String] production Production generating pattern
|
2360
|
+
# @param [Boolean] quoted For quoted triple
|
1872
2361
|
# @param [Hash{Symbol => Object}] options
|
1873
|
-
def add_pattern(production, **options)
|
2362
|
+
def add_pattern(production, quoted: false, **options)
|
1874
2363
|
progress(production, "[:pattern, #{options[:subject]}, #{options[:predicate]}, #{options[:object]}]")
|
1875
2364
|
triple = {}
|
2365
|
+
triple[:quoted] = true if quoted
|
1876
2366
|
options.each_pair do |r, v|
|
1877
2367
|
if v.is_a?(Array) && v.flatten.length == 1
|
1878
2368
|
v = v.flatten.first
|
@@ -1894,6 +2384,7 @@ module SPARQL::Grammar
|
|
1894
2384
|
[expr, query]
|
1895
2385
|
end
|
1896
2386
|
|
2387
|
+
##
|
1897
2388
|
# Merge query modifiers, datasets, and projections
|
1898
2389
|
#
|
1899
2390
|
# This includes tranforming aggregates if also used with a GROUP BY
|
@@ -1988,7 +2479,14 @@ module SPARQL::Grammar
|
|
1988
2479
|
|
1989
2480
|
query = SPARQL::Algebra::Expression[:order, data[:order].first, query] unless order.empty?
|
1990
2481
|
|
1991
|
-
|
2482
|
+
# If SELECT * was used, emit a projection with empty variables, vs no projection at all. Only if :all_vars is true
|
2483
|
+
query = if vars == %i(*)
|
2484
|
+
options[:all_vars] ? SPARQL::Algebra::Expression[:project, [], query] : query
|
2485
|
+
elsif !vars.empty?
|
2486
|
+
SPARQL::Algebra::Expression[:project, vars, query]
|
2487
|
+
else
|
2488
|
+
query
|
2489
|
+
end
|
1992
2490
|
|
1993
2491
|
query = SPARQL::Algebra::Expression[data[:DISTINCT_REDUCED], query] if data[:DISTINCT_REDUCED]
|
1994
2492
|
|