ldpath 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/.rubocop_hound.yml +1063 -0
- data/.rubocop_todo.yml +36 -0
- data/Gemfile +0 -1
- data/Rakefile +1 -1
- data/bin/ldpath +3 -3
- data/lib/ldpath.rb +3 -3
- data/lib/ldpath/field_mapping.rb +1 -2
- data/lib/ldpath/functions.rb +80 -73
- data/lib/ldpath/parser.rb +323 -258
- data/lib/ldpath/program.rb +23 -24
- data/lib/ldpath/selectors.rb +42 -43
- data/lib/ldpath/tests.rb +28 -31
- data/lib/ldpath/transform.rb +45 -47
- data/lib/ldpath/version.rb +1 -1
- data/spec/ldpath_parser_spec.rb +132 -72
- data/spec/ldpath_program_spec.rb +19 -25
- data/spec/ldpath_transform_spec.rb +114 -36
- data/spec/lib/functions/list_spec.rb +61 -0
- data/spec/spec_helper.rb +1 -1
- metadata +8 -3
data/lib/ldpath/program.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
module Ldpath
|
2
2
|
class Program
|
3
|
-
|
4
3
|
include Ldpath::Functions
|
5
4
|
|
6
5
|
class << self
|
7
|
-
def parse
|
6
|
+
def parse(program, transform_context = {})
|
8
7
|
parsed = parser.parse(program)
|
9
8
|
ast = transform.apply parsed, transform_context
|
10
9
|
|
@@ -12,6 +11,7 @@ module Ldpath
|
|
12
11
|
end
|
13
12
|
|
14
13
|
private
|
14
|
+
|
15
15
|
def transform
|
16
16
|
Ldpath::Transform.new
|
17
17
|
end
|
@@ -20,36 +20,35 @@ module Ldpath
|
|
20
20
|
@parser ||= Ldpath::Parser.new
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
24
|
-
attr_reader :mappings, :cache, :loaded, :prefixes, :filters
|
25
|
-
def initialize mappings, options = {}
|
26
23
|
|
24
|
+
attr_reader :mappings, :cache, :loaded, :prefixes, :filters
|
25
|
+
def initialize(mappings, options = {})
|
27
26
|
@mappings ||= mappings
|
28
27
|
@cache = options[:cache] || RDF::Util::Cache.new
|
29
28
|
@prefixes = options[:prefixes] || {}
|
30
29
|
@filters = options[:filters] || []
|
31
30
|
@loaded = {}
|
32
31
|
end
|
33
|
-
|
34
|
-
def loading
|
35
|
-
if uri.to_s =~ /^http/
|
32
|
+
|
33
|
+
def loading(uri, context)
|
34
|
+
if uri.to_s =~ /^http/ && !loaded[uri.to_s]
|
36
35
|
context << load_graph(uri.to_s)
|
37
36
|
end
|
38
37
|
end
|
39
38
|
|
40
|
-
def load_graph
|
39
|
+
def load_graph(uri)
|
41
40
|
cache[uri] ||= begin
|
42
|
-
Ldpath.logger.debug "[#{
|
41
|
+
Ldpath.logger.debug "[#{object_id}] Loading #{uri.inspect}"
|
43
42
|
|
44
43
|
reader_types = RDF::Format.reader_types.reject { |t| t.to_s =~ /html/ }.map do |t|
|
45
|
-
t.to_s =~ /text\/(?:plain|html)/
|
44
|
+
t.to_s =~ /text\/(?:plain|html)/ ? "#{t};q=0.5" : t
|
46
45
|
end
|
47
46
|
|
48
47
|
RDF::Graph.load(uri, headers: { 'Accept' => reader_types.join(", ") }).tap { loaded[uri] = true }
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
52
|
-
def evaluate
|
51
|
+
def evaluate(uri, context = nil)
|
53
52
|
h = {}
|
54
53
|
context ||= load_graph(uri.to_s)
|
55
54
|
|
@@ -60,14 +59,14 @@ module Ldpath
|
|
60
59
|
mappings.each do |m|
|
61
60
|
h[m.name] ||= []
|
62
61
|
h[m.name] += case m.selector
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
62
|
+
when Selector
|
63
|
+
m.selector.evaluate(self, uri, context).map do |x|
|
64
|
+
next x unless m.field_type
|
65
|
+
RDF::Literal.new(x.to_s, datatype: m.field_type).canonicalize.object
|
66
|
+
end
|
67
|
+
else
|
68
|
+
Array(m.selector)
|
69
|
+
end
|
71
70
|
end
|
72
71
|
|
73
72
|
h.merge(meta)
|
@@ -76,8 +75,8 @@ module Ldpath
|
|
76
75
|
def meta
|
77
76
|
@meta ||= {}
|
78
77
|
end
|
79
|
-
|
80
|
-
def func_call
|
78
|
+
|
79
|
+
def func_call(fname, uri, context, *arguments)
|
81
80
|
if function_method? fname
|
82
81
|
public_send(fname, uri, context, *arguments)
|
83
82
|
else
|
@@ -86,9 +85,9 @@ module Ldpath
|
|
86
85
|
end
|
87
86
|
|
88
87
|
private
|
89
|
-
|
88
|
+
|
89
|
+
def function_method?(function)
|
90
90
|
Functions.public_instance_methods(false).include? function.to_sym
|
91
91
|
end
|
92
|
-
|
93
92
|
end
|
94
93
|
end
|
data/lib/ldpath/selectors.rb
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
module Ldpath
|
2
2
|
class Selector
|
3
|
-
def evaluate
|
3
|
+
def evaluate(program, uris, context)
|
4
4
|
Array(uris).map do |uri|
|
5
5
|
loading program, uri, context
|
6
6
|
evaluate_one uri, context
|
7
7
|
end.flatten.compact
|
8
8
|
end
|
9
|
-
|
10
|
-
def loading
|
9
|
+
|
10
|
+
def loading(program, uri, context)
|
11
11
|
program.loading uri, context
|
12
12
|
end
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
class SelfSelector < Selector
|
16
|
-
def evaluate_one
|
16
|
+
def evaluate_one(uri, context)
|
17
17
|
uri
|
18
|
-
end
|
18
|
+
end
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
class FunctionSelector < Selector
|
22
22
|
attr_reader :fname, :arguments
|
23
23
|
|
24
|
-
def initialize
|
24
|
+
def initialize(fname, arguments = [])
|
25
25
|
@fname = fname
|
26
26
|
@arguments = Array(arguments)
|
27
27
|
end
|
28
|
-
|
29
|
-
def evaluate
|
28
|
+
|
29
|
+
def evaluate(program, uris, context)
|
30
30
|
Array(uris).map do |uri|
|
31
31
|
loading program, uri, context
|
32
32
|
args = arguments.map do |i|
|
@@ -41,25 +41,25 @@ module Ldpath
|
|
41
41
|
end.flatten.compact
|
42
42
|
end
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
class PropertySelector < Selector
|
46
46
|
attr_reader :property
|
47
|
-
def initialize
|
47
|
+
def initialize(property)
|
48
48
|
@property = property
|
49
49
|
end
|
50
50
|
|
51
|
-
def evaluate_one
|
51
|
+
def evaluate_one(uri, context)
|
52
52
|
context.query([uri, property, nil]).map(&:object)
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
class LoosePropertySelector < Selector
|
57
57
|
attr_reader :property
|
58
|
-
def initialize
|
58
|
+
def initialize(property)
|
59
59
|
@property = property
|
60
60
|
end
|
61
61
|
|
62
|
-
def evaluate_one
|
62
|
+
def evaluate_one(uri, context)
|
63
63
|
return PropertySelector.new(property).evaluate_one(uri_context) unless defined? RDF::Reasoner
|
64
64
|
|
65
65
|
context.query([uri, nil, nil]).select do |result|
|
@@ -67,83 +67,83 @@ module Ldpath
|
|
67
67
|
end.map(&:object)
|
68
68
|
end
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
class WildcardSelector < Selector
|
72
|
-
def evaluate_one
|
72
|
+
def evaluate_one(uri, context)
|
73
73
|
context.query([uri, nil, nil]).map(&:object)
|
74
74
|
end
|
75
75
|
end
|
76
|
-
|
76
|
+
|
77
77
|
class ReversePropertySelector < Selector
|
78
78
|
attr_reader :property
|
79
|
-
def initialize
|
79
|
+
def initialize(property)
|
80
80
|
@property = property
|
81
81
|
end
|
82
|
-
|
83
|
-
def evaluate_one
|
82
|
+
|
83
|
+
def evaluate_one(uri, context)
|
84
84
|
context.query([nil, property, uri]).map(&:subject)
|
85
85
|
end
|
86
86
|
end
|
87
|
-
|
87
|
+
|
88
88
|
class RecursivePathSelector < Selector
|
89
89
|
attr_reader :property, :repeat
|
90
|
-
def initialize
|
90
|
+
def initialize(property, repeat)
|
91
91
|
@property = property
|
92
92
|
@repeat = repeat
|
93
93
|
end
|
94
|
-
|
95
|
-
def evaluate
|
94
|
+
|
95
|
+
def evaluate(program, uris, context)
|
96
96
|
result = []
|
97
97
|
input = Array(uris)
|
98
|
-
|
99
|
-
Range.new(0,repeat.min,true).each do
|
98
|
+
|
99
|
+
Range.new(0, repeat.min, true).each do
|
100
100
|
input = property.evaluate program, input, context
|
101
101
|
end
|
102
|
-
|
102
|
+
|
103
103
|
repeat.each_with_index do |i, idx|
|
104
|
-
break if input.empty?
|
104
|
+
break if input.empty? || idx > 25 # we're probably lost..
|
105
105
|
input = property.evaluate program, input, context
|
106
106
|
result |= input
|
107
107
|
end
|
108
108
|
result.flatten.compact
|
109
109
|
end
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
class CompoundSelector < Selector
|
113
113
|
attr_reader :left, :right
|
114
|
-
def initialize
|
114
|
+
def initialize(left, right)
|
115
115
|
@left = left
|
116
116
|
@right = right
|
117
117
|
end
|
118
118
|
end
|
119
|
-
|
119
|
+
|
120
120
|
class PathSelector < CompoundSelector
|
121
|
-
def evaluate
|
121
|
+
def evaluate(program, uris, context)
|
122
122
|
output = left.evaluate(program, uris, context)
|
123
123
|
right.evaluate(program, output, context)
|
124
124
|
end
|
125
125
|
end
|
126
|
-
|
126
|
+
|
127
127
|
class UnionSelector < CompoundSelector
|
128
|
-
def evaluate
|
128
|
+
def evaluate(program, uris, context)
|
129
129
|
left.evaluate(program, uris, context) | right.evaluate(program, uris, context)
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
class IntersectionSelector < CompoundSelector
|
134
|
-
def evaluate
|
133
|
+
class IntersectionSelector < CompoundSelector
|
134
|
+
def evaluate(program, uris, context)
|
135
135
|
left.evaluate(program, uris, context) & right.evaluate(program, uris, context)
|
136
136
|
end
|
137
137
|
end
|
138
138
|
|
139
139
|
class TapSelector < Selector
|
140
140
|
attr_reader :identifier, :tap
|
141
|
-
def initialize
|
141
|
+
def initialize(identifier, tap)
|
142
142
|
@identifier = identifier
|
143
143
|
@tap = tap
|
144
144
|
end
|
145
145
|
|
146
|
-
def evaluate
|
146
|
+
def evaluate(program, uris, context)
|
147
147
|
program.meta[identifier] = tap.evaluate(program, uris, context).map { |x| RDF::Literal.new(x.to_s).canonicalize.object }
|
148
148
|
|
149
149
|
Array(uris).map do |uri|
|
@@ -151,10 +151,9 @@ module Ldpath
|
|
151
151
|
evaluate_one uri, context
|
152
152
|
end.flatten.compact
|
153
153
|
end
|
154
|
-
|
155
|
-
def evaluate_one
|
154
|
+
|
155
|
+
def evaluate_one(uri, context)
|
156
156
|
uri
|
157
157
|
end
|
158
158
|
end
|
159
|
-
|
160
159
|
end
|
data/lib/ldpath/tests.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
module Ldpath
|
2
|
-
|
3
2
|
class TestSelector < Selector
|
4
3
|
attr_reader :delegate, :test
|
5
4
|
|
6
|
-
def initialize
|
5
|
+
def initialize(delegate, test)
|
7
6
|
@delegate = delegate
|
8
7
|
@test = test
|
9
8
|
end
|
10
9
|
|
11
|
-
def evaluate
|
10
|
+
def evaluate(program, uris, context)
|
12
11
|
entries = delegate.evaluate program, uris, context
|
13
12
|
entries.select do |uri|
|
14
13
|
Array(test.evaluate(program, uri, context)).any? do |x|
|
@@ -20,82 +19,80 @@ module Ldpath
|
|
20
19
|
|
21
20
|
class LanguageTest < TestSelector
|
22
21
|
attr_reader :lang
|
23
|
-
def initialize
|
22
|
+
def initialize(lang)
|
24
23
|
@lang = lang
|
25
24
|
end
|
26
25
|
|
27
|
-
def evaluate
|
26
|
+
def evaluate(program, uri, context)
|
28
27
|
return unless uri.literal?
|
29
|
-
if (lang == "none" && !uri.has_language?)
|
30
|
-
uri
|
28
|
+
if (lang == "none" && !uri.has_language?) || uri.language == lang
|
29
|
+
uri
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
34
|
class TypeTest < TestSelector
|
36
35
|
attr_reader :type
|
37
|
-
def initialize
|
36
|
+
def initialize(type)
|
38
37
|
@type = type
|
39
38
|
end
|
40
39
|
|
41
|
-
def evaluate
|
40
|
+
def evaluate(program, uri, context)
|
42
41
|
return unless uri.literal?
|
43
|
-
if uri.has_datatype?
|
42
|
+
if uri.has_datatype? && uri.datatype == type
|
44
43
|
uri
|
45
44
|
end
|
46
45
|
end
|
47
46
|
end
|
48
|
-
|
47
|
+
|
49
48
|
class NotTest < TestSelector
|
50
49
|
attr_reader :delegate
|
51
|
-
|
52
|
-
def initialize
|
50
|
+
|
51
|
+
def initialize(delegate)
|
53
52
|
@delegate = delegate
|
54
53
|
end
|
55
|
-
|
56
|
-
def evaluate
|
54
|
+
|
55
|
+
def evaluate(program, uri, context)
|
57
56
|
!Array(delegate.evaluate(program, uri, context)).any? { |x| x }
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
60
|
class OrTest < TestSelector
|
62
61
|
attr_reader :left, :right
|
63
|
-
|
64
|
-
def initialize
|
62
|
+
|
63
|
+
def initialize(left, right)
|
65
64
|
@left = left
|
66
65
|
@right = right
|
67
66
|
end
|
68
|
-
|
69
|
-
def evaluate
|
67
|
+
|
68
|
+
def evaluate(program, uri, context)
|
70
69
|
left.evaluate(program, uri, context).any? || right.evaluate(program, uri, context).any?
|
71
70
|
end
|
72
71
|
end
|
73
72
|
|
74
|
-
class AndTest < TestSelector
|
75
|
-
|
73
|
+
class AndTest < TestSelector
|
76
74
|
attr_reader :left, :right
|
77
|
-
|
78
|
-
def initialize
|
75
|
+
|
76
|
+
def initialize(left, right)
|
79
77
|
@left = left
|
80
78
|
@right = right
|
81
79
|
end
|
82
80
|
|
83
|
-
def evaluate
|
81
|
+
def evaluate(program, uri, context)
|
84
82
|
left.evaluate(program, uri, context).compact.any? &&
|
85
|
-
|
83
|
+
right.evaluate(program, uri, context).compact.any?
|
86
84
|
end
|
87
85
|
end
|
88
|
-
|
86
|
+
|
89
87
|
class IsTest < TestSelector
|
90
|
-
|
91
88
|
attr_reader :left, :right
|
92
|
-
|
93
|
-
def initialize
|
89
|
+
|
90
|
+
def initialize(left, right)
|
94
91
|
@left = left
|
95
92
|
@right = right
|
96
93
|
end
|
97
|
-
|
98
|
-
def evaluate
|
94
|
+
|
95
|
+
def evaluate(program, uri, context)
|
99
96
|
left.evaluate(program, uri, context).compact.include?(right)
|
100
97
|
end
|
101
98
|
end
|
data/lib/ldpath/transform.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
module Ldpath
|
2
2
|
class Transform < Parslet::Transform
|
3
|
+
attr_reader :prefixes
|
3
4
|
|
4
5
|
class << self
|
5
6
|
def default_prefixes
|
@@ -9,37 +10,38 @@ module Ldpath
|
|
9
10
|
"owl" => RDF::Vocabulary.new("http://www.w3.org/2002/07/owl#"),
|
10
11
|
"skos" => RDF::Vocabulary.new("http://www.w3.org/2004/02/skos/core#"),
|
11
12
|
"dc" => RDF::Vocabulary.new("http://purl.org/dc/elements/1.1/"),
|
12
|
-
"xsd" => RDF::Vocabulary.new("http://www.w3.org/2001/XMLSchema#")
|
13
|
-
"lmf" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/types/1.0/")
|
14
|
-
"fn" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/functions/1.0/")
|
13
|
+
"xsd" => RDF::Vocabulary.new("http://www.w3.org/2001/XMLSchema#"), # (LMF base index datatypes/XML Schema)
|
14
|
+
"lmf" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/types/1.0/"), # (LMF extended index datatypes)
|
15
|
+
"fn" => RDF::Vocabulary.new("http://www.newmedialab.at/lmf/functions/1.0/"), # (LMF index functions)
|
15
16
|
"foaf" => RDF::Vocabulary.new("http://xmlns.com/foaf/0.1/"),
|
16
17
|
"info" => RDF::Vocabulary.new("info:"),
|
17
|
-
"urn"
|
18
|
+
"urn" => RDF::Vocabulary.new("urn:"),
|
18
19
|
}
|
19
20
|
end
|
20
21
|
end
|
21
22
|
|
22
|
-
def apply
|
23
|
-
context ||= {
|
23
|
+
def apply(obj, context = nil)
|
24
|
+
context ||= {}
|
24
25
|
context[:filters] ||= []
|
25
26
|
context[:prefixes] ||= {}.merge(self.class.default_prefixes)
|
27
|
+
@prefixes = context[:prefixes]
|
26
28
|
super obj, context
|
27
29
|
end
|
28
|
-
|
30
|
+
|
29
31
|
# Core types
|
30
32
|
rule(literal: simple(:literal)) { literal.to_s }
|
31
|
-
rule(
|
32
|
-
|
33
|
+
rule(iri: simple(:iri)) { RDF::IRI.new(iri) }
|
34
|
+
|
33
35
|
# Namespaces
|
34
|
-
rule(
|
35
|
-
prefixes[
|
36
|
+
rule(prefixID: subtree(:prefixID)) do
|
37
|
+
prefixes[prefixID[:id].to_s] = RDF::Vocabulary.new(prefixID[:iri])
|
36
38
|
nil
|
37
39
|
end
|
38
|
-
|
40
|
+
|
39
41
|
rule(prefix: simple(:prefix), localName: simple(:localName)) do
|
40
42
|
(prefixes[prefix.to_s] || RDF::Vocabulary.new(prefix.to_s))[localName]
|
41
43
|
end
|
42
|
-
|
44
|
+
|
43
45
|
rule(filter: subtree(:filter)) do
|
44
46
|
filters << filter[:test]
|
45
47
|
nil
|
@@ -50,18 +52,16 @@ module Ldpath
|
|
50
52
|
nil
|
51
53
|
end
|
52
54
|
|
53
|
-
|
54
55
|
# Mappings
|
55
|
-
|
56
|
+
|
56
57
|
rule(mapping: subtree(:mapping)) do
|
57
58
|
FieldMapping.new mapping[:name].to_s, mapping[:selector], mapping[:field_type]
|
58
59
|
end
|
59
60
|
|
60
61
|
## Selectors
|
61
|
-
|
62
|
-
|
62
|
+
|
63
63
|
### Atomic Selectors
|
64
|
-
rule(self: simple(:self)) do
|
64
|
+
rule(self: simple(:self)) do
|
65
65
|
SelfSelector.new
|
66
66
|
end
|
67
67
|
|
@@ -72,12 +72,12 @@ module Ldpath
|
|
72
72
|
rule(fname: simple(:fname), arglist: subtree(:arglist)) do
|
73
73
|
FunctionSelector.new fname.to_s, arglist
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
rule(property: simple(:property)) do
|
77
77
|
PropertySelector.new property
|
78
78
|
end
|
79
|
-
|
80
|
-
rule(
|
79
|
+
|
80
|
+
rule(loose: simple(:loose), property: simple(:property)) do
|
81
81
|
LoosePropertySelector.new property
|
82
82
|
end
|
83
83
|
|
@@ -85,31 +85,31 @@ module Ldpath
|
|
85
85
|
WildcardSelector.new
|
86
86
|
end
|
87
87
|
|
88
|
-
rule(
|
88
|
+
rule(reverse: simple(:reverse), property: simple(:property)) do
|
89
89
|
ReversePropertySelector.new property
|
90
90
|
end
|
91
91
|
|
92
92
|
rule(range: subtree(:range)) do
|
93
|
-
range
|
94
|
-
end
|
95
|
-
|
96
|
-
rule(recursive: subtree(:properties)) do
|
97
|
-
repeat = case properties[:repeat]
|
93
|
+
case range
|
98
94
|
when "*"
|
99
95
|
0..Infinity
|
100
96
|
when "+"
|
101
97
|
1..Infinity
|
102
|
-
when
|
103
|
-
|
98
|
+
when "?"
|
99
|
+
0..1
|
100
|
+
else
|
101
|
+
range.fetch(:min, 0).to_i..range.fetch(:max, Infinity).to_f
|
104
102
|
end
|
103
|
+
end
|
105
104
|
|
106
|
-
|
105
|
+
rule(delegate: subtree(:delegate), repeat: simple(:repeat)) do
|
106
|
+
RecursivePathSelector.new delegate, repeat
|
107
107
|
end
|
108
108
|
|
109
109
|
rule(identifier: simple(:identifier), tap: subtree(:tap)) do
|
110
110
|
TapSelector.new identifier.to_s, tap
|
111
111
|
end
|
112
|
-
|
112
|
+
|
113
113
|
### Test Selectors
|
114
114
|
|
115
115
|
rule(delegate: subtree(:delegate), test: subtree(:test)) do
|
@@ -127,15 +127,15 @@ module Ldpath
|
|
127
127
|
rule(type: simple(:type)) do
|
128
128
|
TypeTest.new type
|
129
129
|
end
|
130
|
-
|
130
|
+
|
131
131
|
rule(not: subtree(:not_op)) do
|
132
132
|
NotTest.new not_op[:delegate]
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
rule(and: subtree(:op)) do
|
136
136
|
AndTest.new op[:left], op[:right]
|
137
137
|
end
|
138
|
-
|
138
|
+
|
139
139
|
rule(or: subtree(:op)) do
|
140
140
|
OrTest.new op[:left], op[:right]
|
141
141
|
end
|
@@ -143,25 +143,23 @@ module Ldpath
|
|
143
143
|
rule(is: subtree(:is)) do
|
144
144
|
IsTest.new PropertySelector.new(is[:property]), is[:right]
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
rule(is_a: subtree(:is_a)) do
|
148
148
|
IsTest.new PropertySelector.new(RDF.type), is_a[:right]
|
149
149
|
end
|
150
|
+
|
150
151
|
### Compound Selectors
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
rule(intersection: subtree(:intersection)) do
|
161
|
-
IntersectionSelector.new intersection[:left], intersection[:right]
|
152
|
+
rule(left: subtree(:left), op: simple(:op), right: subtree(:right)) do
|
153
|
+
case op
|
154
|
+
when "/"
|
155
|
+
PathSelector.new left, right
|
156
|
+
when "|"
|
157
|
+
UnionSelector.new left, right
|
158
|
+
when "&"
|
159
|
+
IntersectionSelector.new left, right
|
160
|
+
end
|
162
161
|
end
|
163
162
|
|
164
|
-
|
165
163
|
Infinity = 1.0 / 0.0
|
166
164
|
end
|
167
165
|
end
|