shex 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -3
- data/VERSION +1 -1
- data/lib/shex.rb +2 -2
- data/lib/shex/algebra.rb +3 -6
- data/lib/shex/algebra/and.rb +38 -8
- data/lib/shex/algebra/annotation.rb +1 -1
- data/lib/shex/algebra/each_of.rb +22 -1
- data/lib/shex/algebra/external.rb +4 -4
- data/lib/shex/algebra/node_constraint.rb +4 -4
- data/lib/shex/algebra/not.rb +36 -5
- data/lib/shex/algebra/one_of.rb +22 -1
- data/lib/shex/algebra/operator.rb +90 -62
- data/lib/shex/algebra/or.rb +43 -10
- data/lib/shex/algebra/schema.rb +34 -19
- data/lib/shex/algebra/shape.rb +25 -11
- data/lib/shex/algebra/{satisfiable.rb → shape_expression.rb} +2 -5
- data/lib/shex/algebra/start.rb +35 -5
- data/lib/shex/algebra/triple_constraint.rb +33 -8
- data/lib/shex/algebra/triple_expression.rb +1 -1
- data/lib/shex/parser.rb +25 -22
- data/lib/shex/shex_context.rb +1 -2
- metadata +5 -7
- data/lib/shex/algebra/inclusion.rb +0 -67
- data/lib/shex/algebra/shape_ref.rb +0 -71
data/lib/shex/algebra/or.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ShEx::Algebra
|
2
2
|
##
|
3
3
|
class Or < Operator
|
4
|
-
include
|
4
|
+
include ShapeExpression
|
5
5
|
NAME = :or
|
6
6
|
|
7
7
|
def initialize(*args, **options)
|
@@ -10,8 +10,8 @@ module ShEx::Algebra
|
|
10
10
|
raise ArgumentError, "wrong number of arguments (given #{args.length}, expected 2..)"
|
11
11
|
end
|
12
12
|
|
13
|
-
# All arguments must be
|
14
|
-
raise ArgumentError, "All operands must be Shape operands" unless args.all? {|o| o.is_a?(
|
13
|
+
# All arguments must be ShapeExpression
|
14
|
+
raise ArgumentError, "All operands must be Shape operands or resource" unless args.all? {|o| o.is_a?(ShapeExpression) || o.is_a?(RDF::Resource)}
|
15
15
|
super
|
16
16
|
end
|
17
17
|
|
@@ -27,22 +27,35 @@ module ShEx::Algebra
|
|
27
27
|
|
28
28
|
#
|
29
29
|
# S is a ShapeOr and there is some shape expression se2 in shapeExprs such that satisfies(n, se2, G, m).
|
30
|
-
# @param (see
|
31
|
-
# @return (see
|
32
|
-
# @raise (see
|
30
|
+
# @param (see ShapeExpression#satisfies?)
|
31
|
+
# @return (see ShapeExpression#satisfies?)
|
32
|
+
# @raise (see ShapeExpression#satisfies?)
|
33
33
|
def satisfies?(focus, depth: 0)
|
34
34
|
status "", depth: depth
|
35
|
-
expressions = operands.select {|o| o.is_a?(Satisfiable)}
|
36
35
|
unsatisfied = []
|
37
36
|
expressions.any? do |op|
|
38
37
|
begin
|
39
|
-
matched_op = op
|
38
|
+
matched_op = case op
|
39
|
+
when RDF::Resource
|
40
|
+
schema.enter_shape(op, focus) do |shape|
|
41
|
+
if shape
|
42
|
+
shape.satisfies?(focus, depth: depth + 1)
|
43
|
+
else
|
44
|
+
status "Satisfy as #{op} was re-entered for #{focus}", depth: depth
|
45
|
+
shape
|
46
|
+
end
|
47
|
+
end
|
48
|
+
when ShapeExpression
|
49
|
+
op.satisfies?(focus, depth: depth + 1)
|
50
|
+
end
|
40
51
|
return satisfy focus: focus, satisfied: matched_op, depth: depth
|
41
52
|
rescue ShEx::NotSatisfied => e
|
42
53
|
status "unsatisfied #{focus}", depth: depth
|
43
54
|
op = op.dup
|
44
|
-
op.satisfied
|
45
|
-
|
55
|
+
if op.respond_to?(:satisfied)
|
56
|
+
op.satisfied = e.expression.satisfied
|
57
|
+
op.unsatisfied = e.expression.unsatisfied
|
58
|
+
end
|
46
59
|
unsatisfied << op
|
47
60
|
status "unsatisfied: #{e.message}", depth: depth
|
48
61
|
false
|
@@ -53,6 +66,26 @@ module ShEx::Algebra
|
|
53
66
|
focus: focus, unsatisfied: unsatisfied, depth: depth
|
54
67
|
end
|
55
68
|
|
69
|
+
##
|
70
|
+
# expressions must be ShapeExpressions
|
71
|
+
#
|
72
|
+
# @return [Operator] `self`
|
73
|
+
# @raise [ShEx::StructureError] if the value is invalid
|
74
|
+
def validate!
|
75
|
+
expressions.each do |op|
|
76
|
+
case op
|
77
|
+
when ShapeExpression
|
78
|
+
when RDF::Resource
|
79
|
+
ref = schema.find(op)
|
80
|
+
ref.is_a?(ShapeExpression) ||
|
81
|
+
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
82
|
+
else
|
83
|
+
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
super
|
87
|
+
end
|
88
|
+
|
56
89
|
def json_type
|
57
90
|
"ShapeOr"
|
58
91
|
end
|
data/lib/shex/algebra/schema.rb
CHANGED
@@ -43,12 +43,12 @@ module ShEx::Algebra
|
|
43
43
|
# One or more schemas, or paths to ShEx schema resources used for finding external shapes.
|
44
44
|
# @return [Operand] Returns operand graph annotated with satisfied and unsatisfied operations.
|
45
45
|
# @param [Hash{Symbol => Object}] options
|
46
|
-
# @option options [String] :base_uri
|
46
|
+
# @option options [String] :base_uri (for resolving focus)
|
47
47
|
# @raise [ShEx::NotSatisfied] along with operand graph described for return
|
48
48
|
def execute(focus, graph, map, shapeExterns: [], depth: 0, **options)
|
49
49
|
@graph, @shapes_entered = graph, {}
|
50
50
|
@external_schemas = shapeExterns
|
51
|
-
focus = value(focus)
|
51
|
+
focus = value(focus, options)
|
52
52
|
|
53
53
|
logger = options[:logger] || @options[:logger]
|
54
54
|
each_descendant do |op|
|
@@ -66,7 +66,7 @@ module ShEx::Algebra
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
# If `n` is a Blank Node, we won't find it through normal matching, find an equivalent node in the graph having the same
|
69
|
+
# If `n` is a Blank Node, we won't find it through normal matching, find an equivalent node in the graph having the same id
|
70
70
|
graph_focus = graph.enum_term.detect {|t| t.node? && t.id == focus.id} if focus.is_a?(RDF::Node)
|
71
71
|
graph_focus ||= focus
|
72
72
|
|
@@ -89,10 +89,10 @@ module ShEx::Algebra
|
|
89
89
|
satisfied_shapes = {}
|
90
90
|
satisfied_schema.operands << [:shapes, satisfied_shapes] unless shapes.empty?
|
91
91
|
|
92
|
-
# Match against all shapes associated with the
|
93
|
-
Array(@map[focus]).each do |
|
94
|
-
enter_shape(
|
95
|
-
satisfied_shapes[
|
92
|
+
# Match against all shapes associated with the ids for focus
|
93
|
+
Array(@map[focus]).each do |id|
|
94
|
+
enter_shape(id, focus) do |shape|
|
95
|
+
satisfied_shapes[id] = shape.satisfies?(graph_focus, depth: depth + 1)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
status "schema satisfied", depth: depth
|
@@ -131,23 +131,24 @@ module ShEx::Algebra
|
|
131
131
|
|
132
132
|
##
|
133
133
|
# Indicate that a shape has been entered with a specific focus node. Any future attempt to enter the same shape with the same node raises an exception.
|
134
|
-
# @param [RDF::Resource]
|
134
|
+
# @param [RDF::Resource] id
|
135
135
|
# @param [RDF::Resource] node
|
136
136
|
# @yield :shape
|
137
|
-
# @yieldparam [
|
138
|
-
# @return
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
137
|
+
# @yieldparam [ShapeExpression] shape, or `nil` if shape already entered
|
138
|
+
# @return (see ShapeExpression#satisfies?)
|
139
|
+
# @raise (see ShapeExpression#satisfies?)
|
140
|
+
def enter_shape(id, node, &block)
|
141
|
+
shape = shapes.detect {|s| s.id == id}
|
142
|
+
structure_error("No shape found for #{id}") unless shape
|
143
|
+
@shapes_entered[id] ||= {}
|
144
|
+
if @shapes_entered[id][node]
|
144
145
|
block.call(false)
|
145
146
|
else
|
146
|
-
@shapes_entered[
|
147
|
+
@shapes_entered[id][node] = self
|
147
148
|
begin
|
148
149
|
block.call(shape)
|
149
150
|
ensure
|
150
|
-
@shapes_entered[
|
151
|
+
@shapes_entered[id].delete(node)
|
151
152
|
end
|
152
153
|
end
|
153
154
|
end
|
@@ -174,12 +175,26 @@ module ShEx::Algebra
|
|
174
175
|
@start ||= operands.detect {|op| op.is_a?(Start)}
|
175
176
|
end
|
176
177
|
|
178
|
+
##
|
179
|
+
# Find a ShapeExpression or TripleExpression by identifier
|
180
|
+
# @param [#to_s] id
|
181
|
+
# @return [TripleExpression, ShapeExpression]
|
182
|
+
def find(id)
|
183
|
+
each_descendant.detect {|op| op.id == id}
|
184
|
+
end
|
185
|
+
|
177
186
|
##
|
178
187
|
# Validate shapes, in addition to other operands
|
179
|
-
# @return [
|
188
|
+
# @return [Operator] `self`
|
180
189
|
# @raise [ArgumentError] if the value is invalid
|
181
190
|
def validate!
|
182
|
-
shapes.each
|
191
|
+
shapes.each do |op|
|
192
|
+
op.validate! if op.respond_to?(:validate!)
|
193
|
+
if op.is_a?(RDF::Resource)
|
194
|
+
ref = find(op)
|
195
|
+
structure_error("Missing reference: #{op}") if ref.nil?
|
196
|
+
end
|
197
|
+
end
|
183
198
|
super
|
184
199
|
end
|
185
200
|
end
|
data/lib/shex/algebra/shape.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module ShEx::Algebra
|
2
2
|
##
|
3
3
|
class Shape < Operator
|
4
|
-
include
|
4
|
+
include ShapeExpression
|
5
5
|
NAME = :shape
|
6
6
|
|
7
7
|
##
|
@@ -29,11 +29,10 @@ module ShEx::Algebra
|
|
29
29
|
end
|
30
30
|
|
31
31
|
# The `satisfies` semantics for a `Shape` depend on a matches function defined below. For a node `n`, shape `S`, graph `G`, and shapeMap `m`, `satisfies(n, S, G, m)`.
|
32
|
-
# @param (see
|
33
|
-
# @return (see
|
34
|
-
# @raise (see
|
32
|
+
# @param (see ShapeExpression#satisfies?)
|
33
|
+
# @return (see ShapeExpression#satisfies?)
|
34
|
+
# @raise (see ShapeExpression#satisfies?)
|
35
35
|
def satisfies?(focus, depth: 0)
|
36
|
-
expression = self.expression
|
37
36
|
# neigh(G, n) is the neighbourhood of the node n in the graph G.
|
38
37
|
#
|
39
38
|
# neigh(G, n) = arcsOut(G, n) ∪ arcsIn(G, n)
|
@@ -43,7 +42,12 @@ module ShEx::Algebra
|
|
43
42
|
|
44
43
|
# `matched` is the subset of statements which match `expression`.
|
45
44
|
status("arcsIn: #{arcs_in.count}, arcsOut: #{arcs_out.count}", depth: depth)
|
46
|
-
matched_expression =
|
45
|
+
matched_expression = case expression
|
46
|
+
when RDF::Resource
|
47
|
+
ref.matches(arcs_in, arcs_out, depth: depth + 1)
|
48
|
+
when TripleExpression
|
49
|
+
expression.matches(arcs_in, arcs_out, depth: depth + 1)
|
50
|
+
end
|
47
51
|
matched = Array(matched_expression && matched_expression.matched)
|
48
52
|
|
49
53
|
# `remainder` is the set of unmatched statements
|
@@ -101,12 +105,22 @@ module ShEx::Algebra
|
|
101
105
|
not_satisfied e.message, focus: focus, unsatisfied: e.expression, depth: depth
|
102
106
|
end
|
103
107
|
|
104
|
-
|
105
108
|
##
|
106
|
-
#
|
107
|
-
#
|
108
|
-
|
109
|
-
|
109
|
+
# expression must be a TripleExpression
|
110
|
+
#
|
111
|
+
# @return [Operator] `self`
|
112
|
+
# @raise [ShEx::StructureError] if the value is invalid
|
113
|
+
def validate!
|
114
|
+
case expression
|
115
|
+
when nil, TripleExpression
|
116
|
+
when RDF::Resource
|
117
|
+
ref = schema.find(expression)
|
118
|
+
ref.is_a?(TripleExpression) ||
|
119
|
+
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
120
|
+
else
|
121
|
+
structure_error("#{json_type} must reference a TripleExpression: #{ref}")
|
122
|
+
end
|
123
|
+
super
|
110
124
|
end
|
111
125
|
|
112
126
|
private
|
@@ -2,21 +2,18 @@ require 'sparql/algebra'
|
|
2
2
|
|
3
3
|
module ShEx::Algebra
|
4
4
|
# Implements `satisfies?` and `not_satisfies?`
|
5
|
-
module
|
5
|
+
module ShapeExpression
|
6
6
|
##
|
7
7
|
# Satisfies method
|
8
8
|
# @param [RDF::Resource] focus
|
9
9
|
# @param [Integer] depth for logging
|
10
10
|
# @param [Hash{Symbol => Object}] options
|
11
11
|
# Other, operand-specific options
|
12
|
-
# @return [
|
12
|
+
# @return [ShapeExpression] with `matched` and `satisfied` accessors for matched triples and sub-expressions
|
13
13
|
# @raise [ShEx::NotMatched] with `expression` accessor to access `matched` and `unmatched` statements along with `satisfied` and `unsatisfied` operations.
|
14
14
|
# @see [https://shexspec.github.io/spec/#shape-expression-semantics]
|
15
15
|
def satisfies?(focus, depth: 0, **options)
|
16
16
|
raise NotImplementedError, "#satisfies? Not implemented in #{self.class}"
|
17
17
|
end
|
18
|
-
|
19
|
-
# This operator includes Satisfiable
|
20
|
-
def satisfiable?; true; end
|
21
18
|
end
|
22
19
|
end
|
data/lib/shex/algebra/start.rb
CHANGED
@@ -1,20 +1,50 @@
|
|
1
1
|
module ShEx::Algebra
|
2
2
|
##
|
3
3
|
class Start < Operator::Unary
|
4
|
-
include
|
4
|
+
include ShapeExpression
|
5
5
|
NAME = :start
|
6
6
|
|
7
7
|
#
|
8
|
-
# @param (see
|
9
|
-
# @return (see
|
10
|
-
# @raise (see
|
8
|
+
# @param (see ShapeExpression#satisfies?)
|
9
|
+
# @return (see ShapeExpression#satisfies?)
|
10
|
+
# @raise (see ShapeExpression#satisfies?)
|
11
11
|
def satisfies?(focus, depth: 0)
|
12
12
|
status "", depth: depth
|
13
|
-
matched_op =
|
13
|
+
matched_op = case expression
|
14
|
+
when RDF::Resource
|
15
|
+
schema.enter_shape(expression, focus) do |shape|
|
16
|
+
if shape
|
17
|
+
shape.satisfies?(focus, depth: depth + 1)
|
18
|
+
else
|
19
|
+
status "Satisfy as #{expression} was re-entered for #{focus}", depth: depth
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
end
|
23
|
+
when ShapeExpression
|
24
|
+
expression.satisfies?(focus, depth: depth + 1)
|
25
|
+
end
|
14
26
|
satisfy focus: focus, satisfied: matched_op, depth: depth
|
15
27
|
rescue ShEx::NotSatisfied => e
|
16
28
|
not_satisfied e.message, focus: focus, unsatisfied: e.expression, depth: depth
|
17
29
|
raise
|
18
30
|
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# expression must be a ShapeExpression
|
34
|
+
#
|
35
|
+
# @return [Operator] `self`
|
36
|
+
# @raise [ShEx::StructureError] if the value is invalid
|
37
|
+
def validate!
|
38
|
+
case expression
|
39
|
+
when ShapeExpression
|
40
|
+
when RDF::Resource
|
41
|
+
ref = schema.find(expression)
|
42
|
+
ref.is_a?(ShapeExpression) ||
|
43
|
+
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
44
|
+
else
|
45
|
+
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
46
|
+
end
|
47
|
+
super
|
48
|
+
end
|
19
49
|
end
|
20
50
|
end
|
@@ -29,10 +29,21 @@ module ShEx::Algebra
|
|
29
29
|
statements.select {|st| st.predicate == predicate}.each do |statement|
|
30
30
|
break if num_iters == max # matched enough
|
31
31
|
|
32
|
-
|
32
|
+
focus = inverse? ? statement.subject : statement.object
|
33
33
|
|
34
34
|
begin
|
35
|
-
|
35
|
+
matched_shape = if expression.is_a?(RDF::Resource)
|
36
|
+
schema.enter_shape(expression, focus) do |shape|
|
37
|
+
if shape
|
38
|
+
shape.satisfies?(focus, depth: depth + 1)
|
39
|
+
else
|
40
|
+
status "Satisfy as #{expression} was re-entered for #{focus}", depth: depth
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
elsif expression
|
45
|
+
expression.satisfies?(focus, depth: depth + 1)
|
46
|
+
end
|
36
47
|
status "matched #{statement.to_sxp}", depth: depth
|
37
48
|
if matched_shape
|
38
49
|
matched_shape.matched = [statement]
|
@@ -46,7 +57,7 @@ module ShEx::Algebra
|
|
46
57
|
status "not satisfied: #{e.message}", depth: depth
|
47
58
|
unsatisfied << e.expression
|
48
59
|
statement = statement.dup.extend(ReferencedStatement)
|
49
|
-
statement.referenced =
|
60
|
+
statement.referenced = expression
|
50
61
|
unmatched << statement
|
51
62
|
end
|
52
63
|
end
|
@@ -70,7 +81,25 @@ module ShEx::Algebra
|
|
70
81
|
end
|
71
82
|
|
72
83
|
def predicate
|
73
|
-
operands.detect {|o| o.is_a?(
|
84
|
+
@predicate ||= operands.detect {|o| o.is_a?(Array) && o.first == :predicate}.last
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# expression must be a ShapeExpression
|
89
|
+
#
|
90
|
+
# @return [Operator] `self`
|
91
|
+
# @raise [ShEx::StructureError] if the value is invalid
|
92
|
+
def validate!
|
93
|
+
case expression
|
94
|
+
when nil, ShapeExpression
|
95
|
+
when RDF::Resource
|
96
|
+
ref = schema.find(expression)
|
97
|
+
ref.is_a?(ShapeExpression) ||
|
98
|
+
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
99
|
+
else
|
100
|
+
structure_error("#{json_type} must reference a ShapeExpression: #{ref}")
|
101
|
+
end
|
102
|
+
super
|
74
103
|
end
|
75
104
|
|
76
105
|
##
|
@@ -83,9 +112,5 @@ module ShEx::Algebra
|
|
83
112
|
def inverse?
|
84
113
|
operands.include?(:inverse)
|
85
114
|
end
|
86
|
-
|
87
|
-
def shape
|
88
|
-
operands.detect {|o| o.is_a?(Satisfiable)}
|
89
|
-
end
|
90
115
|
end
|
91
116
|
end
|
@@ -53,7 +53,7 @@ module ShEx::Algebra
|
|
53
53
|
end
|
54
54
|
|
55
55
|
module ReferencedStatement
|
56
|
-
# @return [ShEx::Algebra::
|
56
|
+
# @return [ShEx::Algebra::ShapeExpression] referenced operand which satisfied some of this statement
|
57
57
|
attr_accessor :referenced
|
58
58
|
|
59
59
|
def to_sxp_bin
|
data/lib/shex/parser.rb
CHANGED
@@ -156,7 +156,10 @@ module ShEx
|
|
156
156
|
production(:shexDoc) do |input, data, callback|
|
157
157
|
data[:start] = data[:start] if data[:start]
|
158
158
|
|
159
|
-
expressions =
|
159
|
+
expressions = []
|
160
|
+
expressions << [:base, data[:baseDecl]] if data[:baseDecl]
|
161
|
+
expressions << [:prefix, data[:prefixDecl]] if data[:prefixDecl]
|
162
|
+
expressions += Array(data[:codeDecl])
|
160
163
|
expressions << Algebra::Start.new(data[:start]) if data[:start]
|
161
164
|
expressions << data[:shapes].unshift(:shapes) if data[:shapes]
|
162
165
|
|
@@ -168,13 +171,14 @@ module ShEx
|
|
168
171
|
|
169
172
|
# [3] baseDecl ::= "BASE" IRIREF
|
170
173
|
production(:baseDecl) do |input, data, callback|
|
171
|
-
self.base_uri = iri(data[:iri])
|
174
|
+
input[:baseDecl] = self.base_uri = iri(data[:iri])
|
172
175
|
end
|
173
176
|
|
174
177
|
# [4] prefixDecl ::= "PREFIX" PNAME_NS IRIREF
|
175
178
|
production(:prefixDecl) do |input, data, callback|
|
176
179
|
pfx = data[:prefix]
|
177
180
|
self.prefix(pfx, data[:iri])
|
181
|
+
(input[:prefixDecl] ||= []) << [pfx.to_s, data[:iri]]
|
178
182
|
end
|
179
183
|
|
180
184
|
# [5] notStartAction ::= start | shapeExprDecl
|
@@ -188,14 +192,14 @@ module ShEx
|
|
188
192
|
|
189
193
|
# [9] shapeExprDecl ::= shapeLabel (shapeExpression|"EXTERNAL")
|
190
194
|
production(:shapeExprDecl) do |input, data, callback|
|
191
|
-
|
195
|
+
id = Array(data[:shapeLabel]).first
|
192
196
|
expression = case data[:shapeExpression]
|
193
|
-
when Algebra::NodeConstraint, Algebra::Or, Algebra::And, Algebra::Not, Algebra::
|
197
|
+
when Algebra::NodeConstraint, Algebra::Or, Algebra::And, Algebra::Not, Algebra::Shape, RDF::Resource
|
194
198
|
data[:shapeExpression]
|
195
199
|
else
|
196
200
|
data[:external] ? Algebra::External.new() : Algebra::Shape.new()
|
197
201
|
end
|
198
|
-
expression.
|
202
|
+
expression.id = id if id && !expression.is_a?(RDF::Resource)
|
199
203
|
|
200
204
|
(input[:shapes] ||= []) << expression
|
201
205
|
end
|
@@ -214,7 +218,7 @@ module ShEx
|
|
214
218
|
def shape_or(input, data)
|
215
219
|
input.merge!(data.dup.keep_if {|k, v| [:closed, :extraPropertySet, :codeDecl].include?(k)})
|
216
220
|
expression = if Array(data[:shapeExpression]).length > 1
|
217
|
-
Algebra::Or.new(*data[:shapeExpression])
|
221
|
+
Algebra::Or.new(*data[:shapeExpression], {})
|
218
222
|
else
|
219
223
|
Array(data[:shapeExpression]).first
|
220
224
|
end
|
@@ -238,7 +242,7 @@ module ShEx
|
|
238
242
|
memo.concat(expr.is_a?(Algebra::And) ? expr.operands : [expr])
|
239
243
|
end
|
240
244
|
expression = if expressions.length > 1
|
241
|
-
Algebra::And.new(*expressions)
|
245
|
+
Algebra::And.new(*expressions, {})
|
242
246
|
else
|
243
247
|
expressions.first
|
244
248
|
end
|
@@ -287,9 +291,8 @@ module ShEx
|
|
287
291
|
expression = [constraint, shape].compact
|
288
292
|
expression = case expression.length
|
289
293
|
when 0 then nil
|
290
|
-
when 1
|
291
|
-
|
292
|
-
else Algebra::And.new(*expression)
|
294
|
+
when 1 then expression.first
|
295
|
+
else Algebra::And.new(*expression, {})
|
293
296
|
end
|
294
297
|
|
295
298
|
input[:shapeExpression] = expression if expression
|
@@ -307,7 +310,7 @@ module ShEx
|
|
307
310
|
def shape_or_ref(input, data)
|
308
311
|
input.merge!(data.dup.keep_if {|k, v| [:closed, :extraPropertySet, :codeDecl].include?(k)})
|
309
312
|
if data[:shape] || Array(data[:shapeLabel]).first
|
310
|
-
input[:shapeOrRef] = data[:shape] ||
|
313
|
+
input[:shapeOrRef] = data[:shape] || Array(data[:shapeLabel]).first
|
311
314
|
end
|
312
315
|
rescue ArgumentError => e
|
313
316
|
error(nil, "Argument Error on ShapeOrRef: #{e.message}")
|
@@ -335,7 +338,7 @@ module ShEx
|
|
335
338
|
attrs += Array(data[:numericFacet])
|
336
339
|
attrs += Array(data[:stringFacet])
|
337
340
|
|
338
|
-
input[:nodeConstraint] = Algebra::NodeConstraint.new(*attrs.compact)
|
341
|
+
input[:nodeConstraint] = Algebra::NodeConstraint.new(*attrs.compact, {})
|
339
342
|
end
|
340
343
|
|
341
344
|
# [23] nonLiteralKind ::= "IRI" | "BNODE" | "NONLITERAL"
|
@@ -390,7 +393,7 @@ module ShEx
|
|
390
393
|
attrs += Array(data[:annotation])
|
391
394
|
attrs += Array(data[:codeDecl])
|
392
395
|
|
393
|
-
input[:shape] = Algebra::Shape.new(*attrs) if expression
|
396
|
+
input[:shape] = Algebra::Shape.new(*attrs, {}) if expression
|
394
397
|
end
|
395
398
|
private :shape_definition
|
396
399
|
|
@@ -403,7 +406,7 @@ module ShEx
|
|
403
406
|
# [34] oneOfTripleExpr ::= groupTripleExpr ('|' groupTripleExpr)*
|
404
407
|
production(:oneOfTripleExpr) do |input, data, callback|
|
405
408
|
expression = if Array(data[:tripleExpression]).length > 1
|
406
|
-
Algebra::OneOf.new(*data[:tripleExpression])
|
409
|
+
Algebra::OneOf.new(*data[:tripleExpression], {})
|
407
410
|
else
|
408
411
|
Array(data[:tripleExpression]).first
|
409
412
|
end
|
@@ -413,7 +416,7 @@ module ShEx
|
|
413
416
|
# [37] groupTripleExpr ::= unaryTripleExpr (';' unaryTripleExpr?)*
|
414
417
|
production(:groupTripleExpr) do |input, data, callback|
|
415
418
|
expression = if Array(data[:tripleExpression]).length > 1
|
416
|
-
Algebra::EachOf.new(*data[:tripleExpression])
|
419
|
+
Algebra::EachOf.new(*data[:tripleExpression], {})
|
417
420
|
else
|
418
421
|
Array(data[:tripleExpression]).first
|
419
422
|
end
|
@@ -423,7 +426,7 @@ module ShEx
|
|
423
426
|
# [40] unaryTripleExpr ::= productionLabel? (tripleConstraint | bracketedTripleExpr) | include
|
424
427
|
production(:unaryTripleExpr) do |input, data, callback|
|
425
428
|
expression = data[:tripleExpression]
|
426
|
-
expression.
|
429
|
+
expression.id = data[:productionLabel] if expression && data[:productionLabel]
|
427
430
|
|
428
431
|
(input[:tripleExpression] ||= []) << expression if expression
|
429
432
|
end
|
@@ -458,7 +461,7 @@ module ShEx
|
|
458
461
|
cardinality = data.fetch(:cardinality, {})
|
459
462
|
attrs = [
|
460
463
|
(:inverse if data[:inverse] || data[:not]),
|
461
|
-
Array(data[:predicate]).first,
|
464
|
+
[:predicate, Array(data[:predicate]).first],
|
462
465
|
data[:shapeExpression],
|
463
466
|
([:min, cardinality[:min]] if cardinality[:min]),
|
464
467
|
([:max, cardinality[:max]] if cardinality[:max])
|
@@ -466,7 +469,7 @@ module ShEx
|
|
466
469
|
attrs += Array(data[:codeDecl])
|
467
470
|
attrs += Array(data[:annotation])
|
468
471
|
|
469
|
-
input[:tripleExpression] = Algebra::TripleConstraint.new(*attrs) unless attrs.empty?
|
472
|
+
input[:tripleExpression] = Algebra::TripleConstraint.new(*attrs, {}) unless attrs.empty?
|
470
473
|
end
|
471
474
|
|
472
475
|
# [44] cardinality ::= '*' | '+' | '?' | REPEAT_RANGE
|
@@ -499,12 +502,12 @@ module ShEx
|
|
499
502
|
|
500
503
|
# [50] include ::= '&' shapeLabel
|
501
504
|
production(:include) do |input, data, callback|
|
502
|
-
input[:tripleExpression] =
|
505
|
+
input[:tripleExpression] = data[:shapeLabel].first
|
503
506
|
end
|
504
507
|
|
505
508
|
# [51] annotation ::= '//' predicate (iri | literal)
|
506
509
|
production(:annotation) do |input, data, callback|
|
507
|
-
annotation = Algebra::Annotation.new(data[:predicate].first, (data[:iri] || data[:literal]))
|
510
|
+
annotation = Algebra::Annotation.new([:predicate, data[:predicate].first], (data[:iri] || data[:literal]))
|
508
511
|
(input[:annotation] ||= []) << annotation
|
509
512
|
end
|
510
513
|
|
@@ -512,7 +515,7 @@ module ShEx
|
|
512
515
|
|
513
516
|
# [53] codeDecl ::= '%' iri (CODE | "%")
|
514
517
|
production(:codeDecl) do |input, data, callback|
|
515
|
-
(input[:codeDecl] ||= []) << Algebra::SemAct.new(*[data[:iri], data[:code]].compact)
|
518
|
+
(input[:codeDecl] ||= []) << Algebra::SemAct.new(*[data[:iri], data[:code]].compact, {})
|
516
519
|
end
|
517
520
|
|
518
521
|
# [13t] literal ::= rdfLiteral | numericLiteral | booleanLiteral
|
@@ -662,7 +665,7 @@ module ShEx
|
|
662
665
|
@result.validate! if @result && validate?
|
663
666
|
@result
|
664
667
|
rescue EBNF::LL1::Parser::Error, EBNF::LL1::Lexer::Error => e
|
665
|
-
raise ShEx::ParseError
|
668
|
+
raise ShEx::ParseError, e.message, e.backtrace
|
666
669
|
end
|
667
670
|
|
668
671
|
private
|