json_select 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitmodules +3 -0
- data/.travis.yml +1 -1
- data/Gemfile +1 -0
- data/README.md +52 -1
- data/Rakefile +12 -1
- data/lib/json_select/helpers/depth.rb +6 -2
- data/lib/json_select/helpers/key.rb +6 -2
- data/lib/json_select/helpers/position.rb +15 -7
- data/lib/json_select/helpers/size.rb +14 -6
- data/lib/json_select/helpers/type.rb +8 -4
- data/lib/json_select/selector.rb +47 -11
- data/lib/json_select/selector_parser.rb +179 -44
- data/lib/json_select/selector_parser.tt +9 -2
- data/lib/json_select/version.rb +1 -1
- data/spec/conformance_spec.rb +94 -38
- data/spec/fixtures/{basic_children.selector → parser/level_1/basic_children.output} +0 -0
- data/spec/fixtures/parser/level_1/basic_children.selector +1 -0
- data/spec/fixtures/{basic_combination.selector → parser/level_1/basic_combination.output} +0 -0
- data/spec/fixtures/parser/level_1/basic_combination.selector +1 -0
- data/spec/fixtures/parser/level_1/basic_first-child.output +1 -0
- data/spec/fixtures/{basic_first-child.selector → parser/level_1/basic_first-child.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_grouping.output +1 -0
- data/spec/fixtures/{basic_grouping.selector → parser/level_1/basic_grouping.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_id.output +1 -0
- data/spec/fixtures/{basic_id.selector → parser/level_1/basic_id.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_id_multiple.output +1 -0
- data/spec/fixtures/{basic_id_multiple.selector → parser/level_1/basic_id_multiple.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_id_quotes.output +1 -0
- data/spec/fixtures/{basic_id_quotes.selector → parser/level_1/basic_id_quotes.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_id_with_type.output +1 -0
- data/spec/fixtures/{basic_id_with_type.selector → parser/level_1/basic_id_with_type.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_last-child.output +1 -0
- data/spec/fixtures/{basic_last-child.selector → parser/level_1/basic_last-child.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_nth-child-2.output +1 -0
- data/spec/fixtures/{basic_nth-child-2.selector → parser/level_1/basic_nth-child-2.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_nth-child.output +1 -0
- data/spec/fixtures/{basic_nth-child.selector → parser/level_1/basic_nth-child.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_nth-last-child.output +1 -0
- data/spec/fixtures/{basic_nth-last-child.selector → parser/level_1/basic_nth-last-child.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_root_pseudo.output +1 -0
- data/spec/fixtures/{basic_root_pseudo.selector → parser/level_1/basic_root_pseudo.selector} +0 -0
- data/spec/fixtures/{basic_type.selector → parser/level_1/basic_type.output} +0 -0
- data/spec/fixtures/parser/level_1/basic_type.selector +1 -0
- data/spec/fixtures/{basic_type2.selector → parser/level_1/basic_type2.output} +0 -0
- data/spec/fixtures/parser/level_1/basic_type2.selector +1 -0
- data/spec/fixtures/parser/level_1/basic_type3.output +1 -0
- data/spec/fixtures/{basic_type3.selector → parser/level_1/basic_type3.selector} +0 -0
- data/spec/fixtures/parser/level_1/basic_universal.output +1 -0
- data/spec/fixtures/{basic_universal.selector → parser/level_1/basic_universal.selector} +0 -0
- data/spec/fixtures/parser/level_3/basic_has-sans-paren.output +1 -0
- data/spec/fixtures/parser/level_3/basic_has-sans-paren.selector +2 -0
- data/spec/fixtures/parser/level_3/basic_has-whitespace.output +1 -0
- data/spec/fixtures/parser/level_3/basic_has-whitespace.selector +3 -0
- data/spec/fixtures/parser/level_3/basic_has.output +1 -0
- data/spec/fixtures/parser/level_3/basic_has.selector +1 -0
- data/spec/parser_spec.rb +52 -0
- metadata +123 -148
- data/spec/fixtures/README.md +0 -14
- data/spec/fixtures/alltests.txt +0 -31
- data/spec/fixtures/basic.json +0 -31
- data/spec/fixtures/basic.xml +0 -31
- data/spec/fixtures/basic_children.ast +0 -14
- data/spec/fixtures/basic_children.output +0 -1
- data/spec/fixtures/basic_combination.ast +0 -13
- data/spec/fixtures/basic_combination.output +0 -1
- data/spec/fixtures/basic_first-child.ast +0 -11
- data/spec/fixtures/basic_first-child.output +0 -2
- data/spec/fixtures/basic_grouping.ast +0 -22
- data/spec/fixtures/basic_grouping.output +0 -4
- data/spec/fixtures/basic_id.ast +0 -7
- data/spec/fixtures/basic_id.output +0 -1
- data/spec/fixtures/basic_id_multiple.ast +0 -7
- data/spec/fixtures/basic_id_multiple.output +0 -3
- data/spec/fixtures/basic_id_quotes.ast +0 -7
- data/spec/fixtures/basic_id_quotes.output +0 -2
- data/spec/fixtures/basic_id_with_type.ast +0 -10
- data/spec/fixtures/basic_id_with_type.output +0 -1
- data/spec/fixtures/basic_last-child.ast +0 -11
- data/spec/fixtures/basic_last-child.output +0 -2
- data/spec/fixtures/basic_nth-child-2.ast +0 -11
- data/spec/fixtures/basic_nth-child-2.output +0 -4
- data/spec/fixtures/basic_nth-child.ast +0 -11
- data/spec/fixtures/basic_nth-child.output +0 -3
- data/spec/fixtures/basic_nth-last-child.ast +0 -11
- data/spec/fixtures/basic_nth-last-child.output +0 -2
- data/spec/fixtures/basic_root_pseudo.ast +0 -6
- data/spec/fixtures/basic_root_pseudo.output +0 -31
- data/spec/fixtures/basic_type.ast +0 -7
- data/spec/fixtures/basic_type.output +0 -14
- data/spec/fixtures/basic_type2.ast +0 -7
- data/spec/fixtures/basic_type2.output +0 -1
- data/spec/fixtures/basic_type3.ast +0 -7
- data/spec/fixtures/basic_type3.output +0 -47
- data/spec/fixtures/basic_universal.ast +0 -5
- data/spec/fixtures/basic_universal.output +0 -86
data/.gitmodules
ADDED
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -53,8 +53,59 @@ JSONSelect('string:first-child').match(json) # => "window"
|
|
|
53
53
|
JSONSelect('string:first-child').matches(json) # => ["window", "beer"]
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
## Language support
|
|
57
|
+
|
|
58
|
+
✓ — **Level 1** — `*`<br>
|
|
59
|
+
Any node
|
|
60
|
+
|
|
61
|
+
✓ — **Level 1** — `T`<br>
|
|
62
|
+
A node of type `T`, where `T` is one `string`, `number`, `object`, `array`, `boolean`, or `null`
|
|
63
|
+
|
|
64
|
+
✓ — **Level 1** — `T.key`<br>
|
|
65
|
+
A node of type `T` which is the child of an object and is the value its parents key property
|
|
66
|
+
|
|
67
|
+
✓ — **Level 1** — `T."complex key"`<br>
|
|
68
|
+
Same as previous, but with property name specified as a JSON string
|
|
69
|
+
|
|
70
|
+
✓ — **Level 1** — `T:root`<br>
|
|
71
|
+
A node of type `T` which is the root of the JSON document
|
|
72
|
+
|
|
73
|
+
✓ — **Level 1** — `T:nth-child(n)`<br>
|
|
74
|
+
A node of type `T` which is the nth child of an array parent
|
|
75
|
+
|
|
76
|
+
✓ — **Level 2** — `T:nth-last-child(n)`<br>
|
|
77
|
+
A node of type `T` which is the nth child of an array parent counting from the end
|
|
78
|
+
|
|
79
|
+
✓ — **Level 1** — `T:first-child`<br>
|
|
80
|
+
A node of type `T` which is the first child of an array parent (equivalent to `T:nth-child(1)`)
|
|
81
|
+
|
|
82
|
+
✓ — **Level 2** — `T:last-child`<br>
|
|
83
|
+
A node of type `T` which is the last child of an array parent (equivalent to `T:nth-last-child(1)`)
|
|
84
|
+
|
|
85
|
+
✓ — **Level 2** — `T:only-child`<br>
|
|
86
|
+
A node of type `T` which is the only child of an array parent
|
|
87
|
+
|
|
88
|
+
✓ — **Level 2** — `T:empty`<br>
|
|
89
|
+
A node of type `T` which is an array or object with no child
|
|
90
|
+
|
|
91
|
+
✓ — **Level 1** — `T U`<br>
|
|
92
|
+
A node of type `U` with an ancestor of type `T`
|
|
93
|
+
|
|
94
|
+
✓ — **Level 1** — `T > U`<br>
|
|
95
|
+
A node of type `U` with a parent of type `T`
|
|
96
|
+
|
|
97
|
+
✗ — **Level 2** — `T ~ U`<br>
|
|
98
|
+
A node of type `U` with a sibling of type `T`
|
|
99
|
+
|
|
100
|
+
✓ — **Level 1** — `S1, S2`<br>
|
|
101
|
+
Any node which matches either selector `S1` or `S2`
|
|
102
|
+
|
|
103
|
+
✗ — **Level 3** — `T:has(S)`<br>
|
|
104
|
+
A node of type `T` which has a child node satisfying the selector `S`
|
|
105
|
+
|
|
106
|
+
|
|
56
107
|
## Note on Patches/Pull Requests
|
|
57
|
-
|
|
108
|
+
|
|
58
109
|
* Fork the project.
|
|
59
110
|
* Make your feature addition or bug fix.
|
|
60
111
|
* Add tests for it. This is important so I don't break it in a future version
|
data/Rakefile
CHANGED
|
@@ -9,6 +9,11 @@ RSpec::Core::RakeTask.new do |t|
|
|
|
9
9
|
'-r', File.expand_path("../spec/spec_helper.rb", __FILE__)]
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
task :checkout_conformance_tests do
|
|
13
|
+
sh "git submodule init"
|
|
14
|
+
sh "git submodule update"
|
|
15
|
+
end
|
|
16
|
+
|
|
12
17
|
task :build_parser do
|
|
13
18
|
sh "bundle exec tt lib/json_select/selector_parser.tt -o lib/json_select/selector_parser.rb"
|
|
14
19
|
|
|
@@ -18,6 +23,12 @@ task :build_parser do
|
|
|
18
23
|
File.open(path, 'w+') { |f| f.write src }
|
|
19
24
|
end
|
|
20
25
|
|
|
21
|
-
task :
|
|
26
|
+
task :build do
|
|
27
|
+
h = Bundler::GemHelper.instance
|
|
28
|
+
path = Dir[File.join(h.base, "pkg", "#{h.gemspec.name}-*.gem")].sort_by{|f| File.mtime(f)}.last
|
|
29
|
+
sh "gem sign #{path}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
task :spec => [:checkout_conformance_tests, :build_parser]
|
|
22
33
|
task :build => :build_parser
|
|
23
34
|
task :default => :spec
|
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
module JSONSelect::PositionHelpers
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
def nth_child(object, test, key, idx, size, depth)
|
|
4
4
|
return false unless idx and size
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
idx += 1
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
a = test[:a]
|
|
9
9
|
b = test[:b]
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
if a == 0
|
|
12
12
|
(b == idx)
|
|
13
13
|
else
|
|
14
14
|
(((idx - b) % a) == 0) and ((idx * a + b) >= 0)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
|
-
|
|
17
|
+
|
|
18
|
+
def format_nth_child(test)
|
|
19
|
+
":nth-child(#{test[:a]}n#{test[:b]})"
|
|
20
|
+
end
|
|
21
|
+
|
|
18
22
|
def nth_last_child(object, test, key, idx, size, depth)
|
|
19
23
|
return false unless idx and size
|
|
20
|
-
|
|
24
|
+
|
|
21
25
|
nth_child(object, test, key, (size - idx) - 1, size, depth)
|
|
22
26
|
end
|
|
23
|
-
|
|
27
|
+
|
|
28
|
+
def format_nth_last_child(test)
|
|
29
|
+
":nth-last-child(#{test[:a]}n#{test[:b]})"
|
|
30
|
+
end
|
|
31
|
+
|
|
24
32
|
end
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
module JSONSelect::SizeHelpers
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
def only_child(object, test, key, idx, size, depth)
|
|
4
4
|
return false unless size
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
size == 1
|
|
7
7
|
end
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
def format_only_child(test)
|
|
10
|
+
":only-child"
|
|
11
|
+
end
|
|
12
|
+
|
|
9
13
|
def empty(object, test, key, idx, size, depth)
|
|
10
14
|
return false unless size
|
|
11
|
-
|
|
15
|
+
|
|
12
16
|
case object
|
|
13
17
|
when Array then return object.empty?
|
|
14
18
|
else
|
|
@@ -17,8 +21,12 @@ module JSONSelect::SizeHelpers
|
|
|
17
21
|
return true
|
|
18
22
|
end
|
|
19
23
|
end
|
|
20
|
-
|
|
24
|
+
|
|
21
25
|
return false
|
|
22
26
|
end
|
|
23
|
-
|
|
27
|
+
|
|
28
|
+
def format_empty(test)
|
|
29
|
+
":empty"
|
|
30
|
+
end
|
|
31
|
+
|
|
24
32
|
end
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
module JSONSelect::TypeHelpers
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
def instance_of_type(object, test, key, idx, size, depth)
|
|
4
4
|
test[:n] == type_of(object)
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
+
def format_instance_of_type(test)
|
|
8
|
+
test[:n].to_s
|
|
9
|
+
end
|
|
10
|
+
|
|
7
11
|
private
|
|
8
12
|
|
|
9
13
|
def type_of(object)
|
|
10
14
|
if object.respond_to?(:json_select_each)
|
|
11
15
|
return 'array'
|
|
12
16
|
end
|
|
13
|
-
|
|
17
|
+
|
|
14
18
|
if object.respond_to?(:json_select_each_pair)
|
|
15
19
|
return 'object'
|
|
16
20
|
end
|
|
17
|
-
|
|
21
|
+
|
|
18
22
|
case object
|
|
19
23
|
when Hash then 'object'
|
|
20
24
|
when Array then 'array'
|
|
@@ -27,5 +31,5 @@ private
|
|
|
27
31
|
else raise "Invalid object of class #{object.class} for JSONSelect: #{object.inspect}"
|
|
28
32
|
end
|
|
29
33
|
end
|
|
30
|
-
|
|
34
|
+
|
|
31
35
|
end
|
data/lib/json_select/selector.rb
CHANGED
|
@@ -42,7 +42,7 @@ class JSONSelect
|
|
|
42
42
|
raise ArgumentError, "Expected a string for ast"
|
|
43
43
|
|
|
44
44
|
end
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
@helpers = Module.new
|
|
47
47
|
@helpers.send(:extend,
|
|
48
48
|
JSONSelect::KeyHelpers,
|
|
@@ -50,7 +50,7 @@ class JSONSelect
|
|
|
50
50
|
JSONSelect::SizeHelpers,
|
|
51
51
|
JSONSelect::DepthHelpers,
|
|
52
52
|
JSONSelect::PositionHelpers)
|
|
53
|
-
|
|
53
|
+
|
|
54
54
|
@helper_methods = {}
|
|
55
55
|
(@helpers.public_methods - Module.public_methods).map do |name|
|
|
56
56
|
@helper_methods[name.to_sym] = @helpers.method(name)
|
|
@@ -90,6 +90,42 @@ class JSONSelect
|
|
|
90
90
|
|
|
91
91
|
alias_method :===, :test
|
|
92
92
|
|
|
93
|
+
def to_s
|
|
94
|
+
selectors = @ast
|
|
95
|
+
selectors = (selectors[0] == ',' ? selectors[1..-1] : [selectors])
|
|
96
|
+
|
|
97
|
+
selectors.map do |selector|
|
|
98
|
+
selector.map do |part|
|
|
99
|
+
case part
|
|
100
|
+
|
|
101
|
+
when :>
|
|
102
|
+
'>'
|
|
103
|
+
|
|
104
|
+
when Hash
|
|
105
|
+
tests = (part[:tests].empty? ? ['*'] : part[:tests])
|
|
106
|
+
|
|
107
|
+
tests.map do |test|
|
|
108
|
+
case test
|
|
109
|
+
|
|
110
|
+
when '*'
|
|
111
|
+
'*'
|
|
112
|
+
|
|
113
|
+
when Hash
|
|
114
|
+
@helpers.send("format_#{test[:f]}", test)
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
end.join('')
|
|
118
|
+
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end.join(' ')
|
|
122
|
+
end.join(', ')
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def inspect
|
|
126
|
+
"#<JSONSelect (#{to_s})>"
|
|
127
|
+
end
|
|
128
|
+
|
|
93
129
|
private
|
|
94
130
|
|
|
95
131
|
def _each(selector, object, id, number, total, depth, &block)
|
|
@@ -129,21 +165,21 @@ private
|
|
|
129
165
|
object.json_select_each do |value|
|
|
130
166
|
children << value
|
|
131
167
|
end
|
|
132
|
-
|
|
168
|
+
|
|
133
169
|
a1.unshift(',')
|
|
134
170
|
size = children.size
|
|
135
|
-
|
|
171
|
+
|
|
136
172
|
children.each_with_index do |child, idx|
|
|
137
173
|
_each(a1, child, nil, idx, size, depth + 1, &block)
|
|
138
174
|
end
|
|
139
|
-
|
|
175
|
+
|
|
140
176
|
elsif object.respond_to?(:json_select_each_pair)
|
|
141
177
|
a1.unshift(',')
|
|
142
|
-
|
|
178
|
+
|
|
143
179
|
object.json_select_each_pair do |key, child|
|
|
144
180
|
_each(a1, child, key, nil, nil, depth + 1, &block)
|
|
145
181
|
end
|
|
146
|
-
|
|
182
|
+
|
|
147
183
|
end
|
|
148
184
|
end
|
|
149
185
|
end
|
|
@@ -163,7 +199,7 @@ private
|
|
|
163
199
|
if test[:f] == :is_root
|
|
164
200
|
has_root_test = true
|
|
165
201
|
end
|
|
166
|
-
|
|
202
|
+
|
|
167
203
|
if match
|
|
168
204
|
match = !!@helper_methods[test[:f].to_sym].call(object, test, id, number, total, depth)
|
|
169
205
|
end
|
|
@@ -183,16 +219,16 @@ private
|
|
|
183
219
|
unless match
|
|
184
220
|
return [match, selectors]
|
|
185
221
|
end
|
|
186
|
-
|
|
222
|
+
|
|
187
223
|
# continue search for decendants
|
|
188
224
|
unless selector[0] == :>
|
|
189
225
|
match = false
|
|
190
226
|
selectors.push selector[1..-1]
|
|
191
227
|
return [match, selectors]
|
|
192
228
|
end
|
|
193
|
-
|
|
229
|
+
|
|
194
230
|
# continue search for children
|
|
195
|
-
if selector.length > 2
|
|
231
|
+
if selector.length > 2
|
|
196
232
|
match = false
|
|
197
233
|
selectors.push selector[2..-1]
|
|
198
234
|
end
|
|
@@ -619,7 +619,18 @@ module JSONSelect::Selector
|
|
|
619
619
|
end
|
|
620
620
|
|
|
621
621
|
def e
|
|
622
|
-
elements[
|
|
622
|
+
elements[5]
|
|
623
|
+
end
|
|
624
|
+
|
|
625
|
+
end
|
|
626
|
+
|
|
627
|
+
module Pseudo2
|
|
628
|
+
def a
|
|
629
|
+
elements[1]
|
|
630
|
+
end
|
|
631
|
+
|
|
632
|
+
def s
|
|
633
|
+
elements[5]
|
|
623
634
|
end
|
|
624
635
|
|
|
625
636
|
end
|
|
@@ -669,53 +680,66 @@ module JSONSelect::Selector
|
|
|
669
680
|
end
|
|
670
681
|
s4 << r5
|
|
671
682
|
if r5
|
|
672
|
-
r6 =
|
|
683
|
+
r6 = _nt_positional_pseudo_function_name
|
|
673
684
|
s4 << r6
|
|
674
685
|
if r6
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
686
|
+
s7, i7 = [], index
|
|
687
|
+
loop do
|
|
688
|
+
r8 = _nt_ws
|
|
689
|
+
if r8
|
|
690
|
+
s7 << r8
|
|
691
|
+
else
|
|
692
|
+
break
|
|
693
|
+
end
|
|
681
694
|
end
|
|
695
|
+
r7 = instantiate_node(SyntaxNode,input, i7...index, s7)
|
|
682
696
|
s4 << r7
|
|
683
697
|
if r7
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
break
|
|
691
|
-
end
|
|
698
|
+
if has_terminal?('(', false, index)
|
|
699
|
+
r9 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
|
700
|
+
@index += 1
|
|
701
|
+
else
|
|
702
|
+
terminal_parse_failure('(')
|
|
703
|
+
r9 = nil
|
|
692
704
|
end
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
705
|
+
s4 << r9
|
|
706
|
+
if r9
|
|
707
|
+
s10, i10 = [], index
|
|
708
|
+
loop do
|
|
709
|
+
r11 = _nt_ws
|
|
710
|
+
if r11
|
|
711
|
+
s10 << r11
|
|
712
|
+
else
|
|
713
|
+
break
|
|
714
|
+
end
|
|
715
|
+
end
|
|
716
|
+
r10 = instantiate_node(SyntaxNode,input, i10...index, s10)
|
|
697
717
|
s4 << r10
|
|
698
718
|
if r10
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
if r11
|
|
711
|
-
if has_terminal?(')', false, index)
|
|
712
|
-
r13 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
|
713
|
-
@index += 1
|
|
714
|
-
else
|
|
715
|
-
terminal_parse_failure(')')
|
|
716
|
-
r13 = nil
|
|
719
|
+
r12 = _nt_expression
|
|
720
|
+
s4 << r12
|
|
721
|
+
if r12
|
|
722
|
+
s13, i13 = [], index
|
|
723
|
+
loop do
|
|
724
|
+
r14 = _nt_ws
|
|
725
|
+
if r14
|
|
726
|
+
s13 << r14
|
|
727
|
+
else
|
|
728
|
+
break
|
|
729
|
+
end
|
|
717
730
|
end
|
|
731
|
+
r13 = instantiate_node(SyntaxNode,input, i13...index, s13)
|
|
718
732
|
s4 << r13
|
|
733
|
+
if r13
|
|
734
|
+
if has_terminal?(')', false, index)
|
|
735
|
+
r15 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
|
736
|
+
@index += 1
|
|
737
|
+
else
|
|
738
|
+
terminal_parse_failure(')')
|
|
739
|
+
r15 = nil
|
|
740
|
+
end
|
|
741
|
+
s4 << r15
|
|
742
|
+
end
|
|
719
743
|
end
|
|
720
744
|
end
|
|
721
745
|
end
|
|
@@ -732,8 +756,95 @@ module JSONSelect::Selector
|
|
|
732
756
|
if r4
|
|
733
757
|
r0 = r4
|
|
734
758
|
else
|
|
735
|
-
|
|
736
|
-
|
|
759
|
+
i16, s16 = index, []
|
|
760
|
+
if has_terminal?(':', false, index)
|
|
761
|
+
r17 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
|
762
|
+
@index += 1
|
|
763
|
+
else
|
|
764
|
+
terminal_parse_failure(':')
|
|
765
|
+
r17 = nil
|
|
766
|
+
end
|
|
767
|
+
s16 << r17
|
|
768
|
+
if r17
|
|
769
|
+
r18 = _nt_subselector_pseudo_function_name
|
|
770
|
+
s16 << r18
|
|
771
|
+
if r18
|
|
772
|
+
s19, i19 = [], index
|
|
773
|
+
loop do
|
|
774
|
+
r20 = _nt_ws
|
|
775
|
+
if r20
|
|
776
|
+
s19 << r20
|
|
777
|
+
else
|
|
778
|
+
break
|
|
779
|
+
end
|
|
780
|
+
end
|
|
781
|
+
r19 = instantiate_node(SyntaxNode,input, i19...index, s19)
|
|
782
|
+
s16 << r19
|
|
783
|
+
if r19
|
|
784
|
+
if has_terminal?('(', false, index)
|
|
785
|
+
r21 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
|
786
|
+
@index += 1
|
|
787
|
+
else
|
|
788
|
+
terminal_parse_failure('(')
|
|
789
|
+
r21 = nil
|
|
790
|
+
end
|
|
791
|
+
s16 << r21
|
|
792
|
+
if r21
|
|
793
|
+
s22, i22 = [], index
|
|
794
|
+
loop do
|
|
795
|
+
r23 = _nt_ws
|
|
796
|
+
if r23
|
|
797
|
+
s22 << r23
|
|
798
|
+
else
|
|
799
|
+
break
|
|
800
|
+
end
|
|
801
|
+
end
|
|
802
|
+
r22 = instantiate_node(SyntaxNode,input, i22...index, s22)
|
|
803
|
+
s16 << r22
|
|
804
|
+
if r22
|
|
805
|
+
r24 = _nt_selectors_group
|
|
806
|
+
s16 << r24
|
|
807
|
+
if r24
|
|
808
|
+
s25, i25 = [], index
|
|
809
|
+
loop do
|
|
810
|
+
r26 = _nt_ws
|
|
811
|
+
if r26
|
|
812
|
+
s25 << r26
|
|
813
|
+
else
|
|
814
|
+
break
|
|
815
|
+
end
|
|
816
|
+
end
|
|
817
|
+
r25 = instantiate_node(SyntaxNode,input, i25...index, s25)
|
|
818
|
+
s16 << r25
|
|
819
|
+
if r25
|
|
820
|
+
if has_terminal?(')', false, index)
|
|
821
|
+
r27 = instantiate_node(SyntaxNode,input, index...(index + 1))
|
|
822
|
+
@index += 1
|
|
823
|
+
else
|
|
824
|
+
terminal_parse_failure(')')
|
|
825
|
+
r27 = nil
|
|
826
|
+
end
|
|
827
|
+
s16 << r27
|
|
828
|
+
end
|
|
829
|
+
end
|
|
830
|
+
end
|
|
831
|
+
end
|
|
832
|
+
end
|
|
833
|
+
end
|
|
834
|
+
end
|
|
835
|
+
if s16.last
|
|
836
|
+
r16 = instantiate_node(JSONSelect::Ast::PseudoSelector,input, i16...index, s16)
|
|
837
|
+
r16.extend(Pseudo2)
|
|
838
|
+
else
|
|
839
|
+
@index = i16
|
|
840
|
+
r16 = nil
|
|
841
|
+
end
|
|
842
|
+
if r16
|
|
843
|
+
r0 = r16
|
|
844
|
+
else
|
|
845
|
+
@index = i0
|
|
846
|
+
r0 = nil
|
|
847
|
+
end
|
|
737
848
|
end
|
|
738
849
|
end
|
|
739
850
|
|
|
@@ -817,10 +928,10 @@ module JSONSelect::Selector
|
|
|
817
928
|
r0
|
|
818
929
|
end
|
|
819
930
|
|
|
820
|
-
def
|
|
931
|
+
def _nt_positional_pseudo_function_name
|
|
821
932
|
start_index = index
|
|
822
|
-
if node_cache[:
|
|
823
|
-
cached = node_cache[:
|
|
933
|
+
if node_cache[:positional_pseudo_function_name].has_key?(index)
|
|
934
|
+
cached = node_cache[:positional_pseudo_function_name][index]
|
|
824
935
|
if cached
|
|
825
936
|
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
|
826
937
|
@index = cached.interval.end
|
|
@@ -854,7 +965,31 @@ module JSONSelect::Selector
|
|
|
854
965
|
end
|
|
855
966
|
end
|
|
856
967
|
|
|
857
|
-
node_cache[:
|
|
968
|
+
node_cache[:positional_pseudo_function_name][start_index] = r0
|
|
969
|
+
|
|
970
|
+
r0
|
|
971
|
+
end
|
|
972
|
+
|
|
973
|
+
def _nt_subselector_pseudo_function_name
|
|
974
|
+
start_index = index
|
|
975
|
+
if node_cache[:subselector_pseudo_function_name].has_key?(index)
|
|
976
|
+
cached = node_cache[:subselector_pseudo_function_name][index]
|
|
977
|
+
if cached
|
|
978
|
+
cached = SyntaxNode.new(input, index...(index + 1)) if cached == true
|
|
979
|
+
@index = cached.interval.end
|
|
980
|
+
end
|
|
981
|
+
return cached
|
|
982
|
+
end
|
|
983
|
+
|
|
984
|
+
if has_terminal?('has', false, index)
|
|
985
|
+
r0 = instantiate_node(SyntaxNode,input, index...(index + 3))
|
|
986
|
+
@index += 3
|
|
987
|
+
else
|
|
988
|
+
terminal_parse_failure('has')
|
|
989
|
+
r0 = nil
|
|
990
|
+
end
|
|
991
|
+
|
|
992
|
+
node_cache[:subselector_pseudo_function_name][start_index] = r0
|
|
858
993
|
|
|
859
994
|
r0
|
|
860
995
|
end
|