synvert-core 1.1.1 → 1.3.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.
@@ -7,6 +7,8 @@ macros
7
7
  CLOSE_ARRAY /\)/
8
8
  OPEN_SELECTOR /\(/
9
9
  CLOSE_SELECTOR /\)/
10
+ OPEN_GOTO_SCOPE /</
11
+ CLOSE_GOTO_SCOPE />/
10
12
  OPEN_DYNAMIC_ATTRIBUTE /{{/
11
13
  CLOSE_DYNAMIC_ATTRIBUTE /}}/
12
14
  NODE_TYPE /\.[a-z]+/
@@ -20,8 +22,8 @@ macros
20
22
  REGEXP /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
21
23
  SYMBOL /:[\w!\?<>=]+/
22
24
  TRUE /true/
23
- SINGLE_QUOTE_STRING /'(.*?)'/
24
- DOUBLE_QUOTE_STRING /"(.*?)"/
25
+ SINGLE_QUOTE_STRING /'.*?'/
26
+ DOUBLE_QUOTE_STRING /".*?"/
25
27
 
26
28
  rules
27
29
 
@@ -34,24 +36,31 @@ rules
34
36
  /:has/ { [:tPSEUDO_CLASS, text[1..-1]] }
35
37
  /:not_has/ { [:tPSEUDO_CLASS, text[1..-1]] }
36
38
  /#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
37
- />/ { [:tCHILD, text] }
38
- /~/ { [:tSUBSEQUENT_SIBLING, text] }
39
- /\+/ { [:tNEXT_SIBLING, text] }
39
+ />/ { [:tRELATIONSHIP, text] }
40
+ /~/ { [:tRELATIONSHIP, text] }
41
+ /\+/ { [:tRELATIONSHIP, text] }
40
42
  /#{OPEN_SELECTOR}/ { [:tOPEN_SELECTOR, text] }
41
43
  /#{CLOSE_SELECTOR}/ { [:tCLOSE_SELECTOR, text] }
44
+ /#{OPEN_GOTO_SCOPE}/ { @state = :GOTO_SCOPE; [:tOPEN_GOTO_SCOPE, text] }
42
45
  /#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
46
+ :GOTO_SCOPE /\s+/
47
+ :GOTO_SCOPE /#{IDENTIFIER}/ { [:tIDENTIFIER, text] }
48
+ :GOTO_SCOPE /#{CLOSE_GOTO_SCOPE}/ { @state = nil; [:tCLOSE_GOTO_SCOPE, text] }
43
49
  :KEY /\s+/
44
- :KEY /!=/ { @state = :VALUE; [:tNOT_EQUAL, text] }
45
- :KEY /=~/ { @state = :VALUE; [:tMATCH, text] }
46
- :KEY /!~/ { @state = :VALUE; [:tNOT_MATCH, text] }
47
- :KEY />=/ { @state = :VALUE; [:tGREATER_THAN_OR_EQUAL, text] }
48
- :KEY /<=/ { @state = :VALUE; [:tLESS_THAN_OR_EQUAL, text] }
49
- :KEY />/ { @state = :VALUE; [:tGREATER_THAN, text] }
50
- :KEY /</ { @state = :VALUE; [:tLESS_THAN, text] }
51
- :KEY /=/ { @state = :VALUE; [:tEQUAL, text] }
52
- :KEY /includes/i { @state = :VALUE; [:tINCLUDES, text] }
53
- :KEY /not in/i { @state = :VALUE; [:tNOT_IN, text] }
54
- :KEY /in/i { @state = :VALUE; [:tIN, text] }
50
+ :KEY /\^=/ { @state = :VALUE; [:tOPERATOR, '^='] }
51
+ :KEY /\$=/ { @state = :VALUE; [:tOPERATOR, '$='] }
52
+ :KEY /\*=/ { @state = :VALUE; [:tOPERATOR, '*='] }
53
+ :KEY /!=/ { @state = :VALUE; [:tOPERATOR, '!='] }
54
+ :KEY /=~/ { @state = :VALUE; [:tOPERATOR, '=~'] }
55
+ :KEY /!~/ { @state = :VALUE; [:tOPERATOR, '!~'] }
56
+ :KEY />=/ { @state = :VALUE; [:tOPERATOR, '>='] }
57
+ :KEY /<=/ { @state = :VALUE; [:tOPERATOR, '<='] }
58
+ :KEY />/ { @state = :VALUE; [:tOPERATOR, '>'] }
59
+ :KEY /</ { @state = :VALUE; [:tOPERATOR, '<'] }
60
+ :KEY /=/ { @state = :VALUE; [:tOPERATOR, '=='] }
61
+ :KEY /includes/i { @state = :VALUE; [:tOPERATOR, 'includes'] }
62
+ :KEY /not in/i { @state = :VALUE; [:tOPERATOR, 'not_in'] }
63
+ :KEY /in/i { @state = :VALUE; [:tOPERATOR, 'in'] }
55
64
  :KEY /#{IDENTIFIER}/ { [:tKEY, text] }
56
65
  :VALUE /\s+/
57
66
  :VALUE /\[\]=/ { [:tIDENTIFIER_VALUE, text] }
@@ -61,6 +70,7 @@ rules
61
70
  :VALUE /#{OPEN_DYNAMIC_ATTRIBUTE}/ { @state = :DYNAMIC_ATTRIBUTE; [:tOPEN_DYNAMIC_ATTRIBUTE, text] }
62
71
  :VALUE /#{OPEN_ARRAY}/ { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
63
72
  :VALUE /#{CLOSE_ATTRIBUTE}/ { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
73
+ :VALUE /#{NIL}\?/ { [:tIDENTIFIER_VALUE, text] }
64
74
  :VALUE /#{NIL}/ { [:tNIL, nil] }
65
75
  :VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
66
76
  :VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
@@ -76,8 +86,8 @@ rules
76
86
  :DYNAMIC_ATTRIBUTE /#{CLOSE_DYNAMIC_ATTRIBUTE}/ { @state = :VALUE; [:tCLOSE_DYNAMIC_ATTRIBUTE, text] }
77
87
  :DYNAMIC_ATTRIBUTE /#{IDENTIFIER}/ { [:tDYNAMIC_ATTRIBUTE, text] }
78
88
  :ARRAY_VALUE /\s+/
79
- :ARRAY_VALUE /,/ { [:tCOMMA, text] }
80
89
  :ARRAY_VALUE /#{CLOSE_ARRAY}/ { @state = :VALUE; [:tCLOSE_ARRAY, text] }
90
+ :ARRAY_VALUE /#{NIL}\?/ { [:tIDENTIFIER_VALUE, text] }
81
91
  :ARRAY_VALUE /#{NIL}/ { [:tNIL, nil] }
82
92
  :ARRAY_VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
83
93
  :ARRAY_VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
@@ -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]+/
@@ -33,8 +35,8 @@ class Synvert::Core::NodeQuery::Lexer
33
35
  REGEXP = /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
34
36
  SYMBOL = /:[\w!\?<>=]+/
35
37
  TRUE = /true/
36
- SINGLE_QUOTE_STRING = /'(.*?)'/
37
- DOUBLE_QUOTE_STRING = /"(.*?)"/
38
+ SINGLE_QUOTE_STRING = /'.*?'/
39
+ DOUBLE_QUOTE_STRING = /".*?"/
38
40
  # :startdoc:
39
41
  # :stopdoc:
40
42
  class LexerError < StandardError ; end
@@ -140,47 +142,67 @@ class Synvert::Core::NodeQuery::Lexer
140
142
  when text = ss.scan(/#{NODE_TYPE}/) then
141
143
  action { [:tNODE_TYPE, text[1..]] }
142
144
  when text = ss.scan(/>/) then
143
- action { [:tCHILD, text] }
145
+ action { [:tRELATIONSHIP, text] }
144
146
  when text = ss.scan(/~/) then
145
- action { [:tSUBSEQUENT_SIBLING, text] }
147
+ action { [:tRELATIONSHIP, text] }
146
148
  when text = ss.scan(/\+/) then
147
- action { [:tNEXT_SIBLING, text] }
149
+ action { [:tRELATIONSHIP, text] }
148
150
  when text = ss.scan(/#{OPEN_SELECTOR}/) then
149
151
  action { [:tOPEN_SELECTOR, text] }
150
152
  when text = ss.scan(/#{CLOSE_SELECTOR}/) then
151
153
  action { [:tCLOSE_SELECTOR, text] }
154
+ when text = ss.scan(/#{OPEN_GOTO_SCOPE}/) then
155
+ action { @state = :GOTO_SCOPE; [:tOPEN_GOTO_SCOPE, text] }
152
156
  when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
153
157
  action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
154
158
  else
155
159
  text = ss.string[ss.pos .. -1]
156
160
  raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
157
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
158
174
  when :KEY then
159
175
  case
160
176
  when ss.skip(/\s+/) then
161
177
  # do nothing
162
- when text = ss.scan(/!=/) then
163
- action { @state = :VALUE; [:tNOT_EQUAL, text] }
164
- when text = ss.scan(/=~/) then
165
- action { @state = :VALUE; [:tMATCH, text] }
166
- when text = ss.scan(/!~/) then
167
- action { @state = :VALUE; [:tNOT_MATCH, text] }
168
- when text = ss.scan(/>=/) then
169
- action { @state = :VALUE; [:tGREATER_THAN_OR_EQUAL, text] }
170
- when text = ss.scan(/<=/) then
171
- action { @state = :VALUE; [:tLESS_THAN_OR_EQUAL, text] }
172
- when text = ss.scan(/>/) then
173
- action { @state = :VALUE; [:tGREATER_THAN, text] }
174
- when text = ss.scan(/</) then
175
- action { @state = :VALUE; [:tLESS_THAN, text] }
176
- when text = ss.scan(/=/) then
177
- action { @state = :VALUE; [:tEQUAL, text] }
178
- when text = ss.scan(/includes/i) then
179
- action { @state = :VALUE; [:tINCLUDES, text] }
180
- when text = ss.scan(/not in/i) then
181
- action { @state = :VALUE; [:tNOT_IN, text] }
182
- when text = ss.scan(/in/i) then
183
- action { @state = :VALUE; [:tIN, text] }
178
+ when ss.skip(/\^=/) then
179
+ action { @state = :VALUE; [:tOPERATOR, '^='] }
180
+ when ss.skip(/\$=/) then
181
+ action { @state = :VALUE; [:tOPERATOR, '$='] }
182
+ when ss.skip(/\*=/) then
183
+ action { @state = :VALUE; [:tOPERATOR, '*='] }
184
+ when ss.skip(/!=/) then
185
+ action { @state = :VALUE; [:tOPERATOR, '!='] }
186
+ when ss.skip(/=~/) then
187
+ action { @state = :VALUE; [:tOPERATOR, '=~'] }
188
+ when ss.skip(/!~/) then
189
+ action { @state = :VALUE; [:tOPERATOR, '!~'] }
190
+ when ss.skip(/>=/) then
191
+ action { @state = :VALUE; [:tOPERATOR, '>='] }
192
+ when ss.skip(/<=/) then
193
+ action { @state = :VALUE; [:tOPERATOR, '<='] }
194
+ when ss.skip(/>/) then
195
+ action { @state = :VALUE; [:tOPERATOR, '>'] }
196
+ when ss.skip(/</) then
197
+ action { @state = :VALUE; [:tOPERATOR, '<'] }
198
+ when ss.skip(/=/) then
199
+ action { @state = :VALUE; [:tOPERATOR, '=='] }
200
+ when ss.skip(/includes/i) then
201
+ action { @state = :VALUE; [:tOPERATOR, 'includes'] }
202
+ when ss.skip(/not in/i) then
203
+ action { @state = :VALUE; [:tOPERATOR, 'not_in'] }
204
+ when ss.skip(/in/i) then
205
+ action { @state = :VALUE; [:tOPERATOR, 'in'] }
184
206
  when text = ss.scan(/#{IDENTIFIER}/) then
185
207
  action { [:tKEY, text] }
186
208
  else
@@ -205,6 +227,8 @@ class Synvert::Core::NodeQuery::Lexer
205
227
  action { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
206
228
  when text = ss.scan(/#{CLOSE_ATTRIBUTE}/) then
207
229
  action { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
230
+ when text = ss.scan(/#{NIL}\?/) then
231
+ action { [:tIDENTIFIER_VALUE, text] }
208
232
  when ss.skip(/#{NIL}/) then
209
233
  action { [:tNIL, nil] }
210
234
  when ss.skip(/#{TRUE}/) then
@@ -247,10 +271,10 @@ class Synvert::Core::NodeQuery::Lexer
247
271
  case
248
272
  when ss.skip(/\s+/) then
249
273
  # do nothing
250
- when text = ss.scan(/,/) then
251
- action { [:tCOMMA, text] }
252
274
  when text = ss.scan(/#{CLOSE_ARRAY}/) then
253
275
  action { @state = :VALUE; [:tCLOSE_ARRAY, text] }
276
+ when text = ss.scan(/#{NIL}\?/) then
277
+ action { [:tIDENTIFIER_VALUE, text] }
254
278
  when ss.skip(/#{NIL}/) then
255
279
  action { [:tNIL, nil] }
256
280
  when ss.skip(/#{TRUE}/) then