synvert-core 1.0.5 → 1.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/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
|