synvert-core 1.0.5 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +19 -0
- data/lib/synvert/core/array_ext.rb +9 -2
- data/lib/synvert/core/node_ext.rb +72 -151
- data/lib/synvert/core/node_query/compiler/array.rb +1 -1
- data/lib/synvert/core/node_query/compiler/expression.rb +69 -31
- data/lib/synvert/core/node_query/compiler/selector.rb +23 -18
- data/lib/synvert/core/node_query/compiler/string.rb +0 -11
- data/lib/synvert/core/node_query/lexer.rex +14 -2
- data/lib/synvert/core/node_query/lexer.rex.rb +31 -3
- data/lib/synvert/core/node_query/parser.racc.rb +223 -249
- data/lib/synvert/core/node_query/parser.y +9 -12
- data/lib/synvert/core/node_query.rb +1 -0
- data/lib/synvert/core/version.rb +1 -1
- data/spec/synvert/core/node_ext_spec.rb +41 -15
- data/spec/synvert/core/node_query/lexer_spec.rb +72 -5
- data/spec/synvert/core/node_query/parser_spec.rb +98 -23
- metadata +2 -2
@@ -20,6 +20,8 @@ class Synvert::Core::NodeQuery::Lexer
|
|
20
20
|
CLOSE_ARRAY = /\)/
|
21
21
|
OPEN_SELECTOR = /\(/
|
22
22
|
CLOSE_SELECTOR = /\)/
|
23
|
+
OPEN_GOTO_SCOPE = /</
|
24
|
+
CLOSE_GOTO_SCOPE = />/
|
23
25
|
OPEN_DYNAMIC_ATTRIBUTE = /{{/
|
24
26
|
CLOSE_DYNAMIC_ATTRIBUTE = /}}/
|
25
27
|
NODE_TYPE = /\.[a-z]+/
|
@@ -134,7 +136,9 @@ class Synvert::Core::NodeQuery::Lexer
|
|
134
136
|
when text = ss.scan(/:nth-last-child\(\d+\)/) then
|
135
137
|
action { [:tINDEX, -text.sub(':nth-last-child(', '').to_i] }
|
136
138
|
when text = ss.scan(/:has/) then
|
137
|
-
action { [:
|
139
|
+
action { [:tPSEUDO_CLASS, text[1..-1]] }
|
140
|
+
when text = ss.scan(/:not_has/) then
|
141
|
+
action { [:tPSEUDO_CLASS, text[1..-1]] }
|
138
142
|
when text = ss.scan(/#{NODE_TYPE}/) then
|
139
143
|
action { [:tNODE_TYPE, text[1..]] }
|
140
144
|
when text = ss.scan(/>/) then
|
@@ -147,12 +151,26 @@ class Synvert::Core::NodeQuery::Lexer
|
|
147
151
|
action { [:tOPEN_SELECTOR, text] }
|
148
152
|
when text = ss.scan(/#{CLOSE_SELECTOR}/) then
|
149
153
|
action { [:tCLOSE_SELECTOR, text] }
|
154
|
+
when text = ss.scan(/#{OPEN_GOTO_SCOPE}/) then
|
155
|
+
action { @state = :GOTO_SCOPE; [:tOPEN_GOTO_SCOPE, text] }
|
150
156
|
when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
|
151
157
|
action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
152
158
|
else
|
153
159
|
text = ss.string[ss.pos .. -1]
|
154
160
|
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
155
161
|
end
|
162
|
+
when :GOTO_SCOPE then
|
163
|
+
case
|
164
|
+
when ss.skip(/\s+/) then
|
165
|
+
# do nothing
|
166
|
+
when text = ss.scan(/#{IDENTIFIER}/) then
|
167
|
+
action { [:tIDENTIFIER, text] }
|
168
|
+
when text = ss.scan(/#{CLOSE_GOTO_SCOPE}/) then
|
169
|
+
action { @state = nil; [:tCLOSE_GOTO_SCOPE, text] }
|
170
|
+
else
|
171
|
+
text = ss.string[ss.pos .. -1]
|
172
|
+
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
173
|
+
end
|
156
174
|
when :KEY then
|
157
175
|
case
|
158
176
|
when ss.skip(/\s+/) then
|
@@ -189,12 +207,22 @@ class Synvert::Core::NodeQuery::Lexer
|
|
189
207
|
case
|
190
208
|
when ss.skip(/\s+/) then
|
191
209
|
# do nothing
|
210
|
+
when text = ss.scan(/\[\]=/) then
|
211
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
212
|
+
when text = ss.scan(/\[\]/) then
|
213
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
214
|
+
when text = ss.scan(/:\[\]=/) then
|
215
|
+
action { [:tSYMBOL, text[1..-1].to_sym] }
|
216
|
+
when text = ss.scan(/:\[\]/) then
|
217
|
+
action { [:tSYMBOL, text[1..-1].to_sym] }
|
192
218
|
when text = ss.scan(/#{OPEN_DYNAMIC_ATTRIBUTE}/) then
|
193
219
|
action { @state = :DYNAMIC_ATTRIBUTE; [:tOPEN_DYNAMIC_ATTRIBUTE, text] }
|
194
220
|
when text = ss.scan(/#{OPEN_ARRAY}/) then
|
195
221
|
action { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
|
196
222
|
when text = ss.scan(/#{CLOSE_ATTRIBUTE}/) then
|
197
223
|
action { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
|
224
|
+
when text = ss.scan(/#{NIL}\?/) then
|
225
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
198
226
|
when ss.skip(/#{NIL}/) then
|
199
227
|
action { [:tNIL, nil] }
|
200
228
|
when ss.skip(/#{TRUE}/) then
|
@@ -237,10 +265,10 @@ class Synvert::Core::NodeQuery::Lexer
|
|
237
265
|
case
|
238
266
|
when ss.skip(/\s+/) then
|
239
267
|
# do nothing
|
240
|
-
when text = ss.scan(/,/) then
|
241
|
-
action { [:tCOMMA, text] }
|
242
268
|
when text = ss.scan(/#{CLOSE_ARRAY}/) then
|
243
269
|
action { @state = :VALUE; [:tCLOSE_ARRAY, text] }
|
270
|
+
when text = ss.scan(/#{NIL}\?/) then
|
271
|
+
action { [:tIDENTIFIER_VALUE, text] }
|
244
272
|
when ss.skip(/#{NIL}/) then
|
245
273
|
action { [:tNIL, nil] }
|
246
274
|
when ss.skip(/#{TRUE}/) then
|