shex 0.4.0 → 0.5.0

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.
@@ -1,3 +1,4 @@
1
+ # -*- encoding: utf-8 -*-
1
2
  require 'ebnf'
2
3
  require 'ebnf/ll1/parser'
3
4
  require 'shex/meta'
@@ -102,6 +103,18 @@ module ShEx
102
103
  terminal(:LANGTAG, LANGTAG) do |prod, token, input|
103
104
  input[:language] = token.value[1..-1]
104
105
  end
106
+ terminal(:LANG_STRING_LITERAL_LONG1, LANG_STRING_LITERAL_LONG1, unescape: true) do |prod, token, input|
107
+ input[:string], _, input[:language] = token.value[3..-1].rpartition("'''@")
108
+ end
109
+ terminal(:LANG_STRING_LITERAL_LONG2, LANG_STRING_LITERAL_LONG2, unescape: true) do |prod, token, input|
110
+ input[:string], _, input[:language] = token.value[3..-1].rpartition('"""@')
111
+ end
112
+ terminal(:LANG_STRING_LITERAL1, LANG_STRING_LITERAL1, unescape: true) do |prod, token, input|
113
+ input[:string], _, input[:language] = token.value[1..-1].rpartition("'@")
114
+ end
115
+ terminal(:LANG_STRING_LITERAL2, LANG_STRING_LITERAL2, unescape: true) do |prod, token, input|
116
+ input[:string], _, input[:language] = token.value[1..-1].rpartition('"@')
117
+ end
105
118
  terminal(:STRING_LITERAL_LONG1, STRING_LITERAL_LONG1, unescape: true) do |prod, token, input|
106
119
  input[:string] = token.value[3..-4]
107
120
  end
@@ -114,6 +127,9 @@ module ShEx
114
127
  terminal(:STRING_LITERAL2, STRING_LITERAL2, unescape: true) do |prod, token, input|
115
128
  input[:string] = token.value[1..-2]
116
129
  end
130
+ terminal(:REGEXP, REGEXP) do |prod, token, input|
131
+ input[:regexp] = token.value
132
+ end
117
133
  terminal(:RDF_TYPE, RDF_TYPE) do |prod, token, input|
118
134
  input[:iri] = (a = RDF.type.dup; a.lexical = 'a'; a)
119
135
  end
@@ -143,8 +159,7 @@ module ShEx
143
159
  'MINEXCLUSIVE',
144
160
  'MAXINCLUSIVE',
145
161
  'MAXEXCLUSIVE' then input[:numericRange] = token.value.downcase.to_sym
146
- when 'NOT' then input[:not] = token.value.downcase.to_sym
147
- when 'PATTERN' then input[:pattern] = token.value.downcase.to_sym
162
+ when 'NOT' then input[:not] = token.value.downcase.to_sym
148
163
  when 'START' then input[:start] = token.value.downcase.to_sym
149
164
  else
150
165
  #raise "Unexpected MC terminal: #{token.inspect}"
@@ -184,7 +199,7 @@ module ShEx
184
199
  # [5] notStartAction ::= start | shapeExprDecl
185
200
  # [6] start ::= "start" '=' shapeExpression
186
201
  production(:start) do |input, data, callback|
187
- input[:start] = data[:shapeExpression]
202
+ input[:start] = Array(data[:shapeExpression]).first || data[:shape]
188
203
  end
189
204
  # [7] startActions ::= codeDecl+
190
205
 
@@ -193,9 +208,9 @@ module ShEx
193
208
  # [9] shapeExprDecl ::= shapeLabel (shapeExpression|"EXTERNAL")
194
209
  production(:shapeExprDecl) do |input, data, callback|
195
210
  id = Array(data[:shapeLabel]).first
196
- expression = case data[:shapeExpression]
211
+ expression = case Array(data[:shapeExpression]).first
197
212
  when Algebra::NodeConstraint, Algebra::Or, Algebra::And, Algebra::Not, Algebra::Shape, RDF::Resource
198
- data[:shapeExpression]
213
+ Array(data[:shapeExpression]).first
199
214
  else
200
215
  data[:external] ? Algebra::External.new() : Algebra::Shape.new()
201
216
  end
@@ -204,13 +219,36 @@ module ShEx
204
219
  (input[:shapes] ||= []) << expression
205
220
  end
206
221
 
207
- # [10] shapeExpression ::= shapeOr
208
- # [11] inlineShapeExpression ::= inlineShapeOr
222
+ # [10] shapeExpression ::= shapeAtomNoRef shapeOr?
223
+ # | "NOT" (shapeAtomNoRef | shapeRef) shapeOr?
224
+ # | shapeRef shapeOr
225
+ production(:shapeExpression) do |input, data, callback|
226
+ expression = Array(data[:shapeExpression]).first || data[:shape]
227
+ expression = Algebra::Not.new(expression) if data[:not]
228
+ (input[:shapeExpression] ||= []) << expression
229
+ end
209
230
 
210
- # [12] shapeOr ::= shapeAnd ("OR" shapeAnd)*
211
- production(:shapeOr) do |input, data, callback|
231
+ # [11] inlineShapeExpression ::= inlineShapeOr
232
+ # [12] shapeOr ::= shapeOrA | shapeOrB shapeOrA?
233
+ # [12a] shapeOrA ::= ("OR" shapeAnd)+
234
+ start_production(:shapeOrA) do |input, data, callback|
235
+ data[:shapeExpression] = input.delete(:shapeExpression)
236
+ data[:shapeExpression] ||= Array(input.delete(:shape)) if input[:shape]
237
+ data[:shapeExpression] = [Algebra::Not.new(*data[:shapeExpression])] if input.delete(:not)
238
+ end
239
+ production(:shapeOrA) do |input, data, callback|
212
240
  shape_or(input, data)
213
241
  end
242
+ # [12b] shapeOrB ::= ("AND" shapeNot)+
243
+ start_production(:shapeOrB) do |input, data, callback|
244
+ data[:shapeExpression] = input.delete(:shapeExpression)
245
+ data[:shapeExpression] ||= Array(input.delete(:shape)) if input[:shape]
246
+ data[:shapeExpression] = [Algebra::Not.new(*data[:shapeExpression])] if input.delete(:not)
247
+ end
248
+ production(:shapeOrB) do |input, data, callback|
249
+ shape_and(input, data)
250
+ end
251
+
214
252
  # [13] inlineShapeOr ::= inlineShapeAnd ("OR" inlineShapeAnd)*
215
253
  production(:inlineShapeOr) do |input, data, callback|
216
254
  shape_or(input, data)
@@ -222,7 +260,7 @@ module ShEx
222
260
  else
223
261
  Array(data[:shapeExpression]).first
224
262
  end
225
- input[:shapeExpression] = expression if expression
263
+ (input[:shapeExpression] ||= []) << expression if expression
226
264
  rescue ArgumentError => e
227
265
  error(nil, "Argument Error on OR: #{e.message}")
228
266
  end
@@ -262,7 +300,7 @@ module ShEx
262
300
  end
263
301
  def shape_not(input, data)
264
302
  input.merge!(data.dup.keep_if {|k, v| [:closed, :extraPropertySet, :codeDecl].include?(k)})
265
- expression = data[:shapeExpression]
303
+ expression = Array(data[:shapeExpression]).first
266
304
  expression = Algebra::Not.new(expression) if data[:not]
267
305
  #error(nil, "Expected an atom for NOT") unless expression
268
306
  (input[:shapeExpression] ||= []) << expression if expression
@@ -276,7 +314,16 @@ module ShEx
276
314
  production(:shapeAtom) do |input, data, callback|
277
315
  shape_atom(input, data)
278
316
  end
279
- # [19] inlineShapeAtom ::= nodeConstraint inlineShapeOrRef?
317
+
318
+ # [19] shapeAtomNoRef ::= nodeConstraint shapeOrRef?
319
+ # | shapeDefinition
320
+ # | "(" shapeExpression ")"
321
+ # | '.' # no constraint
322
+ production(:shapeAtomNoRef) do |input, data, callback|
323
+ shape_atom(input, data)
324
+ end
325
+
326
+ # [20] inlineShapeAtom ::= nodeConstraint inlineShapeOrRef?
280
327
  # | inlineShapeOrRef nodeConstraint?
281
328
  # | "(" shapeExpression ")"
282
329
  # | '.' # no constraint
@@ -285,7 +332,7 @@ module ShEx
285
332
  end
286
333
  def shape_atom(input, data)
287
334
  constraint = data[:nodeConstraint]
288
- shape = data[:shapeOrRef] || data[:shapeExpression]
335
+ shape = data[:shapeOrRef] || Array(data[:shapeExpression]).first || data[:shape]
289
336
  input.merge!(data.dup.keep_if {|k, v| [:closed, :extraPropertySet, :codeDecl].include?(k)})
290
337
 
291
338
  expression = [constraint, shape].compact
@@ -295,34 +342,36 @@ module ShEx
295
342
  else Algebra::And.new(*expression, {})
296
343
  end
297
344
 
298
- input[:shapeExpression] = expression if expression
345
+ (input[:shapeExpression] ||= []) << expression if expression
299
346
  end
300
347
  private :shape_atom
301
348
 
302
- # [20] shapeOrRef ::= ATPNAME_LN | ATPNAME_NS | '@' shapeLabel | shapeDefinition
349
+ # [21] shapeOrRef ::= shapeDefinition | shapeRef
303
350
  production(:shapeOrRef) do |input, data, callback|
304
351
  shape_or_ref(input, data)
305
352
  end
306
- # [21] inlineShapeOrRef ::= ATPNAME_LN | ATPNAME_NS | '@' shapeLabel | inlineShapeDefinition
353
+ # [22] inlineShapeOrRef ::= inlineShapeDefinition | shapeRef
307
354
  production(:inlineShapeOrRef) do |input, data, callback|
308
355
  shape_or_ref(input, data)
309
356
  end
310
357
  def shape_or_ref(input, data)
311
358
  input.merge!(data.dup.keep_if {|k, v| [:closed, :extraPropertySet, :codeDecl].include?(k)})
312
- if data[:shape] || Array(data[:shapeLabel]).first
313
- input[:shapeOrRef] = data[:shape] || Array(data[:shapeLabel]).first
314
- end
359
+ input[:shapeOrRef] = data[:shape] if data[:shape]
315
360
  rescue ArgumentError => e
316
361
  error(nil, "Argument Error on ShapeOrRef: #{e.message}")
317
362
  end
318
363
  private :shape_or_ref
319
364
 
320
- # [22] nodeConstraint ::= "LITERAL" xsFacet*
321
- # | nonLiteralKind stringFacet*
365
+ # [23] shapeRef ::= ATPNAME_LN | ATPNAME_NS | '@' shapeLabel
366
+ production(:shapeRef) do |input, data, callback|
367
+ input[:shape] = Array(data[:shapeLabel]).first
368
+ end
369
+
370
+ # [24] litNodeConstraint ::= "LITERAL" xsFacet*
322
371
  # | datatype xsFacet*
323
372
  # | valueSet xsFacet*
324
- # | xsFacet+
325
- production(:nodeConstraint) do |input, data, callback|
373
+ # | numericFacet+
374
+ production(:litNodeConstraint) do |input, data, callback|
326
375
  # Semantic validate (A Syntax error)
327
376
  case
328
377
  when data[:datatype] && data[:numericFacet]
@@ -333,7 +382,7 @@ module ShEx
333
382
 
334
383
  attrs = []
335
384
  attrs << [:datatype, data[:datatype]] if data [:datatype]
336
- attrs += [data[:shapeAtomLiteral], data[:nonLiteralKind]]
385
+ attrs += Array(data[:shapeAtomLiteral])
337
386
  attrs += Array(data[:valueSetValue])
338
387
  attrs += Array(data[:numericFacet])
339
388
  attrs += Array(data[:stringFacet])
@@ -341,12 +390,23 @@ module ShEx
341
390
  input[:nodeConstraint] = Algebra::NodeConstraint.new(*attrs.compact, {})
342
391
  end
343
392
 
344
- # [23] nonLiteralKind ::= "IRI" | "BNODE" | "NONLITERAL"
393
+ # [25] nonLitNodeConstraint ::= nonLiteralKind stringFacet*
394
+ # | stringFacet+
395
+ production(:nonLitNodeConstraint) do |input, data, callback|
396
+ # Semantic validate (A Syntax error)
397
+
398
+ attrs = []
399
+ attrs += Array(data[:nonLiteralKind])
400
+ attrs += Array(data[:stringFacet])
345
401
 
346
- # [24] xsFacet ::= stringFacet | numericFacet
347
- # [25] stringFacet ::= stringLength INTEGER
348
- # | "PATTERN" string
349
- # | '~' string # shortcut for "PATTERN"
402
+ input[:nodeConstraint] = Algebra::NodeConstraint.new(*attrs.compact, {})
403
+ end
404
+
405
+ # [26] nonLiteralKind ::= "IRI" | "BNODE" | "NONLITERAL"
406
+
407
+ # [27] xsFacet ::= stringFacet | numericFacet
408
+ # [28] stringFacet ::= stringLength INTEGER
409
+ # | REGEXP
350
410
  production(:stringFacet) do |input, data, callback|
351
411
  input[:stringFacet] ||= []
352
412
  input[:stringFacet] << if data[:stringLength]
@@ -354,14 +414,27 @@ module ShEx
354
414
  error(nil, "#{data[:stringLength]} constraint may only be used once in a Node Constraint", production: :stringFacet)
355
415
  end
356
416
  [data[:stringLength], data[:literal]]
357
- elsif data[:pattern]
358
- [:pattern, data[:string]]
417
+ elsif re = data[:regexp]
418
+ unless re =~ %r(^/(.*)/([smix]*)$)
419
+ error(nil, "#{re.inspect} regular expression must be in the form /pattern/flags?", production: :stringFacet)
420
+ end
421
+ flags = $2 unless $2.to_s.empty?
422
+ pattern = $1.gsub('\\/', '/').gsub(UCHAR) do
423
+ [($1 || $2).hex].pack('U*')
424
+ end.force_encoding(Encoding::UTF_8)
425
+
426
+ # Any other escaped character is a syntax error
427
+ if pattern.match(%r([^\\]\\[^nrt/\\|\.?*+\[\]\(\){}$#x2D#x5B#x5D#x5E-]))
428
+ error(nil, "Regexp contains illegal escape: #{pattern.inspect}", production: :stringFacet)
429
+ end
430
+
431
+ [:pattern, pattern, flags].compact
359
432
  end
360
433
  end
361
434
 
362
- # [26] stringLength ::= "LENGTH" | "MINLENGTH" | "MAXLENGTH"
435
+ # [29] stringLength ::= "LENGTH" | "MINLENGTH" | "MAXLENGTH"
363
436
 
364
- # [27] numericFacet ::= numericRange (numericLiteral | string '^^' datatype )
437
+ # [30] numericFacet ::= numericRange (numericLiteral | string '^^' datatype )
365
438
  # | numericLength INTEGER
366
439
  production(:numericFacet) do |input, data, callback|
367
440
  input[:numericFacet] ||= []
@@ -374,18 +447,19 @@ module ShEx
374
447
  end
375
448
  end
376
449
 
377
- # [28] numericRange ::= "MININCLUSIVE" | "MINEXCLUSIVE" | "MAXINCLUSIVE" | "MAXEXCLUSIVE"
378
- # [29] numericLength ::= "TOTALDIGITS" | "FRACTIONDIGITS"
450
+ # [31] numericRange ::= "MININCLUSIVE" | "MINEXCLUSIVE" | "MAXINCLUSIVE" | "MAXEXCLUSIVE"
451
+ # [32] numericLength ::= "TOTALDIGITS" | "FRACTIONDIGITS"
379
452
 
380
- # [30] shapeDefinition ::= (extraPropertySet | "CLOSED")* '{' tripleExpression? '}' annotation* semanticActions
453
+ # [33] shapeDefinition ::= (includeSet | extraPropertySet | "CLOSED")* '{' tripleExpression? '}' annotation* semanticActions
381
454
  production(:shapeDefinition) do |input, data, callback|
382
455
  shape_definition(input, data)
383
456
  end
384
- # [31] inlineShapeDefinition ::= (extraPropertySet | "CLOSED")* '{' tripleExpression? '}'
457
+ # [34] inlineShapeDefinition ::= (includeSet | extraPropertySet | "CLOSED")* '{' tripleExpression? '}'
385
458
  production(:inlineShapeDefinition) do |input, data, callback|
386
459
  shape_definition(input, data)
387
460
  end
388
461
  def shape_definition(input, data)
462
+ # FIXME: includeSet
389
463
  expression = data[:tripleExpression]
390
464
  attrs = Array(data[:extraPropertySet])
391
465
  attrs << :closed if data[:closed]
@@ -397,13 +471,13 @@ module ShEx
397
471
  end
398
472
  private :shape_definition
399
473
 
400
- # [32] extraPropertySet ::= "EXTRA" predicate+
474
+ # [35] extraPropertySet ::= "EXTRA" predicate+
401
475
  production(:extraPropertySet) do |input, data, callback|
402
476
  (input[:extraPropertySet] ||= []) << data[:predicate].unshift(:extra)
403
477
  end
404
478
 
405
- # [33] tripleExpression ::= oneOfTripleExpr
406
- # [34] oneOfTripleExpr ::= groupTripleExpr ('|' groupTripleExpr)*
479
+ # [36] tripleExpression ::= oneOfTripleExpr
480
+ # [37] oneOfTripleExpr ::= groupTripleExpr ('|' groupTripleExpr)*
407
481
  production(:oneOfTripleExpr) do |input, data, callback|
408
482
  expression = if Array(data[:tripleExpression]).length > 1
409
483
  Algebra::OneOf.new(*data[:tripleExpression], {})
@@ -413,7 +487,7 @@ module ShEx
413
487
  input[:tripleExpression] = expression if expression
414
488
  end
415
489
 
416
- # [37] groupTripleExpr ::= unaryTripleExpr (';' unaryTripleExpr?)*
490
+ # [40] groupTripleExpr ::= unaryTripleExpr (';' unaryTripleExpr?)*
417
491
  production(:groupTripleExpr) do |input, data, callback|
418
492
  expression = if Array(data[:tripleExpression]).length > 1
419
493
  Algebra::EachOf.new(*data[:tripleExpression], {})
@@ -423,7 +497,7 @@ module ShEx
423
497
  (input[:tripleExpression] ||= []) << expression if expression
424
498
  end
425
499
 
426
- # [40] unaryTripleExpr ::= productionLabel? (tripleConstraint | bracketedTripleExpr) | include
500
+ # [43] unaryTripleExpr ::= productionLabel? (tripleConstraint | bracketedTripleExpr) | include
427
501
  production(:unaryTripleExpr) do |input, data, callback|
428
502
  expression = data[:tripleExpression]
429
503
  expression.id = data[:productionLabel] if expression && data[:productionLabel]
@@ -431,7 +505,12 @@ module ShEx
431
505
  (input[:tripleExpression] ||= []) << expression if expression
432
506
  end
433
507
 
434
- # [41] bracketedTripleExpr ::= '(' oneOfTripleExpr ')' cardinality? annotation* semanticActions
508
+ # [43a] productionLabel ::= '$' (iri | blankNode)
509
+ production(:productionLabel) do |input, data, callback|
510
+ input[:productionLabel] = data[:iri] || data[:blankNode]
511
+ end
512
+
513
+ # [44] bracketedTripleExpr ::= '(' oneOfTripleExpr ')' cardinality? annotation* semanticActions
435
514
  production(:bracketedTripleExpr) do |input, data, callback|
436
515
  # XXX cardinality? annotation* semanticActions
437
516
  case expression = data[:tripleExpression]
@@ -451,18 +530,13 @@ module ShEx
451
530
  input[:tripleExpression] = expression
452
531
  end
453
532
 
454
- # [42] productionLabel ::= '$' (iri | blankNode)
455
- production(:productionLabel) do |input, data, callback|
456
- input[:productionLabel] = data[:iri] || data[:blankNode]
457
- end
458
-
459
- # [43] tripleConstraint ::= senseFlags? predicate shapeExpression cardinality? annotation* semanticActions
533
+ # [45] tripleConstraint ::= senseFlags? predicate shapeExpression cardinality? annotation* semanticActions
460
534
  production(:tripleConstraint) do |input, data, callback|
461
535
  cardinality = data.fetch(:cardinality, {})
462
536
  attrs = [
463
537
  (:inverse if data[:inverse] || data[:not]),
464
538
  [:predicate, Array(data[:predicate]).first],
465
- data[:shapeExpression],
539
+ Array(data[:shapeExpression]).first,
466
540
  ([:min, cardinality[:min]] if cardinality[:min]),
467
541
  ([:max, cardinality[:max]] if cardinality[:max])
468
542
  ].compact
@@ -472,71 +546,146 @@ module ShEx
472
546
  input[:tripleExpression] = Algebra::TripleConstraint.new(*attrs, {}) unless attrs.empty?
473
547
  end
474
548
 
475
- # [44] cardinality ::= '*' | '+' | '?' | REPEAT_RANGE
476
- # [45] senseFlags ::= '^'
477
- # [46] valueSet ::= '[' valueSetValue* ']'
549
+ # [46] cardinality ::= '*' | '+' | '?' | REPEAT_RANGE
550
+ # [47] senseFlags ::= '^'
551
+ # [48] valueSet ::= '[' valueSetValue* ']'
478
552
 
479
- # [47] valueSetValue ::= iriRange | literal
553
+ # [49] valueSetValue ::= iriRange | literalRange | languageRange | '.' exclusion+
480
554
  production(:valueSetValue) do |input, data, callback|
481
- (input[:valueSetValue] ||= []) << Algebra::Value.new(data[:iriRange] || data[:literal])
555
+ range = data[:iriRange] || data[:literalRange] || data[:languageRange]
556
+ if !range
557
+ # All exclusions must be consistent IRI/Literal/Language
558
+ case data[:exclusion].first
559
+ when Algebra::IriStem, RDF::URI
560
+ unless data[:exclusion].all? {|e| e.is_a?(Algebra::IriStem) || e.is_a?(RDF::URI)}
561
+ error(nil, "Exclusions must all be IRI type")
562
+ end
563
+ range = Algebra::IriStemRange.new(:wildcard, data[:exclusion].unshift(:exclusions))
564
+ when Algebra::LiteralStem, RDF::Literal
565
+ unless data[:exclusion].all? {|e| e.is_a?(Algebra::LiteralStem) || e.is_a?(RDF::Literal)}
566
+ error(nil, "Exclusions must all be Literal type")
567
+ end
568
+ range = Algebra::LiteralStemRange.new(:wildcard, data[:exclusion].unshift(:exclusions))
569
+ else
570
+ unless data[:exclusion].all? {|e| e.is_a?(Algebra::LanguageStem) || e.is_a?(String)}
571
+ error(nil, "Exclusions must all be Language type")
572
+ end
573
+ range = Algebra::LanguageStemRange.new(:wildcard, data[:exclusion].unshift(:exclusions))
574
+ end
575
+ end
576
+ (input[:valueSetValue] ||= []) << Algebra::Value.new(range)
482
577
  end
483
578
 
484
- # [48] iriRange ::= iri ('~' exclusion*)? | '.' exclusion+
579
+ # [50] exclusion ::= '-' (iri | literal | LANGTAG) '~'?
580
+ production(:exclusion) do |input, data, callback|
581
+ (input[:exclusion] ||= []) << if data[:pattern]
582
+ case
583
+ when data[:iri] then Algebra::IriStem.new(data[:iri])
584
+ when data[:literal] then Algebra::LiteralStem.new(data[:literal])
585
+ when data[:language] then Algebra::LanguageStem.new(data[:language])
586
+ end
587
+ else
588
+ data[:iri] || data[:literal] || data[:language]
589
+ end
590
+ end
591
+
592
+ # [51] iriRange ::= iri ('~' iriExclusion*)?
485
593
  production(:iriRange) do |input, data, callback|
486
594
  exclusions = data[:exclusion].unshift(:exclusions) if data[:exclusion]
487
595
  input[:iriRange] = if data[:pattern] && exclusions
488
- Algebra::StemRange.new(data[:iri], exclusions)
596
+ Algebra::IriStemRange.new(data[:iri], exclusions)
489
597
  elsif data[:pattern]
490
- Algebra::Stem.new(data[:iri])
598
+ Algebra::IriStem.new(data[:iri])
491
599
  elsif data[:dot]
492
- Algebra::StemRange.new(:wildcard, exclusions)
600
+ Algebra::IriStemRange.new(:wildcard, exclusions)
493
601
  else
494
602
  data[:iri]
495
603
  end
496
604
  end
497
605
 
498
- # [49] exclusion ::= '-' iri '~'?
499
- production(:exclusion) do |input, data, callback|
500
- (input[:exclusion] ||= []) << (data[:pattern] ? Algebra::Stem.new(data[:iri]) : data[:iri])
606
+ # [52] iriExclusion ::= '-' iri '~'?
607
+ production(:iriExclusion) do |input, data, callback|
608
+ val = data[:iri]
609
+ (input[:exclusion] ||= []) << (data[:pattern] ? Algebra::IriStem.new(val) : val)
610
+ end
611
+
612
+ # [53] literalRange ::= literal ('~' literalExclusion*)?
613
+ production(:literalRange) do |input, data, callback|
614
+ exclusions = data[:exclusion].unshift(:exclusions) if data[:exclusion]
615
+ input[:literalRange] = if data[:pattern] && exclusions
616
+ Algebra::LiteralStemRange.new(data[:literal], exclusions)
617
+ elsif data[:pattern]
618
+ Algebra::LiteralStem.new(data[:literal])
619
+ elsif data[:dot]
620
+ Algebra::LiteralStemRange.new(:wildcard, exclusions)
621
+ else
622
+ data[:literal]
623
+ end
624
+ end
625
+
626
+ # [54] literalExclusion ::= '-' literal '~'?
627
+ production(:literalExclusion) do |input, data, callback|
628
+ val = data[:literal]
629
+ (input[:exclusion] ||= []) << (data[:pattern] ? Algebra::LiteralStem.new(val) : val)
630
+ end
631
+
632
+ # [55] languageRange ::= LANGTAG ('~' languageExclusion*)?
633
+ production(:languageRange) do |input, data, callback|
634
+ exclusions = data[:exclusion].unshift(:exclusions) if data[:exclusion]
635
+ input[:languageRange] = if data[:pattern] && exclusions
636
+ Algebra::LanguageStemRange.new(data[:language], exclusions)
637
+ elsif data[:pattern]
638
+ Algebra::LanguageStem.new(data[:language])
639
+ elsif data[:dot]
640
+ Algebra::LanguageStemRange.new(:wildcard, exclusions)
641
+ else
642
+ data[:language]
643
+ end
644
+ end
645
+
646
+ # [56] languageExclusion ::= '-' literal '~'?
647
+ production(:languageExclusion) do |input, data, callback|
648
+ val = data[:language]
649
+ (input[:exclusion] ||= []) << (data[:pattern] ? Algebra::LanguageStem.new(val) : val)
501
650
  end
502
651
 
503
- # [50] include ::= '&' shapeLabel
652
+ # [57] include ::= '&' shapeLabel
504
653
  production(:include) do |input, data, callback|
505
654
  input[:tripleExpression] = data[:shapeLabel].first
506
655
  end
507
656
 
508
- # [51] annotation ::= '//' predicate (iri | literal)
657
+ # [58] annotation ::= '//' predicate (iri | literal)
509
658
  production(:annotation) do |input, data, callback|
510
659
  annotation = Algebra::Annotation.new([:predicate, data[:predicate].first], (data[:iri] || data[:literal]))
511
660
  (input[:annotation] ||= []) << annotation
512
661
  end
513
662
 
514
- # [52] semanticActions ::= codeDecl*
663
+ # [59] semanticActions ::= codeDecl*
515
664
 
516
- # [53] codeDecl ::= '%' iri (CODE | "%")
665
+ # [60] codeDecl ::= '%' iri (CODE | "%")
517
666
  production(:codeDecl) do |input, data, callback|
518
667
  (input[:codeDecl] ||= []) << Algebra::SemAct.new(*[data[:iri], data[:code]].compact, {})
519
668
  end
520
669
 
521
670
  # [13t] literal ::= rdfLiteral | numericLiteral | booleanLiteral
522
671
 
523
- # [54] predicate ::= iri | RDF_TYPE
672
+ # [61] predicate ::= iri | RDF_TYPE
524
673
  production(:predicate) do |input, data, callback|
525
674
  (input[:predicate] ||= []) << data[:iri]
526
675
  end
527
676
 
528
- # [55] datatype ::= iri
677
+ # [62] datatype ::= iri
529
678
  production(:datatype) do |input, data, callback|
530
679
  input[:datatype] = data[:iri]
531
680
  end
532
681
 
533
- # [56] shapeLabel ::= iri | blankNode
682
+ # [63] shapeLabel ::= iri | blankNode
534
683
  production(:shapeLabel) do |input, data, callback|
535
684
  (input[:shapeLabel] ||= []) << (data[:iri] || data[:blankNode])
536
685
  end
537
686
 
538
687
  # [16t] numericLiteral ::= INTEGER | DECIMAL | DOUBLE
539
- # [129s] rdfLiteral ::= string (LANGTAG | '^^' datatype)?
688
+ # [129s] rdfLiteral ::= langString | string ('^^' datatype)?
540
689
  production(:rdfLiteral) do |input, data, callback|
541
690
  input[:literal] = literal(data[:string], data)
542
691
  end
@@ -544,8 +693,10 @@ module ShEx
544
693
  # [134s] booleanLiteral ::= 'true' | 'false'
545
694
  # [135s] string ::= STRING_LITERAL1 | STRING_LITERAL_LONG1
546
695
  # | STRING_LITERAL2 | STRING_LITERAL_LONG2
696
+ # [66] langString ::= LANG_STRING_LITERAL1 | LANG_STRING_LITERAL_LONG1
697
+ # | LANG_STRING_LITERAL2 | LANG_STRING_LITERAL_LONG2
547
698
  # [136s] iri ::= IRIREF | prefixedName
548
- # [137s] prefixedName ::= PNAME_LN | PNAME_NS
699
+ # [1372] prefixedName ::= PNAME_LN | PNAME_NS
549
700
  # [138s] blankNode ::= BLANK_NODE_LABEL
550
701
 
551
702
  ##
@@ -638,7 +789,7 @@ module ShEx
638
789
  when 0
639
790
  log_error(*args, depth: depth, lineno: lineno)
640
791
  when 1
641
- log_warning(*args, depth: depth, lineno: lineno)
792
+ log_warn(*args, depth: depth, lineno: lineno)
642
793
  when 2
643
794
  log_info(*args, depth: depth, lineno: lineno)
644
795
  else