node_query 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 133039b40806dc003715b5d04f34bbb78d6f3cfe3969e1d10dc920063e8ebe11
4
- data.tar.gz: 43d5557d76103476d90c98f2575f0869ed8809abe639ec62d38695cd1131eca7
3
+ metadata.gz: 937481646456841ca565042544794aa91a0339c40790f14233d721f45b0531fa
4
+ data.tar.gz: 807b2709a6350489229a86febb0d6d7eb9684f8ce4fb712603d6bcd6cb62f192
5
5
  SHA512:
6
- metadata.gz: 0cb0b449357c4238ea7d123e16985a82e8fb4a1d2271359616720d0dd2833eac3a07963ff612c7a71a8afdb88ec5014e5f9f35fb22a51acd188e46295d86cae1
7
- data.tar.gz: 48ff7474de2c811103c71df2789d81818691e11e8c10303544d15dde4a9362933984ea60b353182fc4b9d16720532756e21c593a15b6a685466275bc880f7de3
6
+ metadata.gz: 9bff7b923a263ad1817226f7fbb095cb9275b1f0e6f27dadd5562202c04aa2ba7bebb0c5b4659484dfeafc5adff268a7f8cd09e7c1f628b17d9c638fbc280c41
7
+ data.tar.gz: 102c406278c8b752c6ead8856247678f79a5ca2fb178f625a746030c330f9310a6f3d4decdb860a12cad8ae95982d014b102704c5afe60edfe95c066ad26dc3f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.1.0 (2022-06-27)
4
+
5
+ * Support `*` in attribute key
6
+ * Add new Adapter method `is_node?`
7
+
3
8
  ## 1.0.0 (2022-06-26)
4
9
 
5
10
  * Abstract from synvert-core
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- node_query (1.0.0)
4
+ node_query (1.1.0)
5
5
  activesupport
6
6
 
7
7
  GEM
@@ -2,6 +2,12 @@
2
2
 
3
3
  # Abstract Adapter class
4
4
  class NodeQuery::Adapter
5
+ # Check if it is a node
6
+ # @return [Boolean]
7
+ def is_node?(node)
8
+ raise NotImplementedError, 'get_node_type is not implemented'
9
+ end
10
+
5
11
  # Get the type of node
6
12
  # @param node [Node] ast node
7
13
  # @return [Symbol] node type
@@ -46,9 +46,17 @@ module NodeQuery::Compiler
46
46
  when '<='
47
47
  actual_value(node) <= expected_value
48
48
  when 'in'
49
- expected_value.any? { |expected| expected.match?(node, '==') }
49
+ if node.is_a?(Array)
50
+ node.all? { |child| expected_value.any? { |expected| expected.match?(child, '==') } }
51
+ else
52
+ expected_value.any? { |expected| expected.match?(node, '==') }
53
+ end
50
54
  when 'not_in'
51
- expected_value.all? { |expected| expected.match?(node, '!=') }
55
+ if node.is_a?(Array)
56
+ node.all? { |child| expected_value.all? { |expected| expected.match?(child, '!=') } }
57
+ else
58
+ expected_value.all? { |expected| expected.match?(node, '!=') }
59
+ end
52
60
  when 'includes'
53
61
  actual_value(node).any? { |actual| actual == expected_value }
54
62
  else
@@ -9,10 +9,13 @@ class NodeQuery::Helper
9
9
  return unless node
10
10
 
11
11
  first_key, rest_keys = keys.to_s.split('.', 2)
12
- if (node.is_a?(Array) && first_key === "*")
12
+ if node.is_a?(Array) && first_key === "*"
13
13
  return node.map { |child_node| get_target_node(child_node, rest_keys) }
14
14
  end
15
15
 
16
+ if node.is_a?(Array) && first_key =~ /\d+/
17
+ child_node = node[first_key.to_i]
18
+ end
16
19
  if node.respond_to?(first_key)
17
20
  child_node = node.send(first_key)
18
21
  end
@@ -28,8 +31,10 @@ class NodeQuery::Helper
28
31
  # @yieldparam child [Parser::AST::Node] child node
29
32
  def self.handle_recursive_child(node, &block)
30
33
  NodeQuery.get_adapter.get_children(node).each do |child|
31
- block.call(child)
32
- handle_recursive_child(child, &block)
34
+ if NodeQuery.get_adapter.is_node?(child)
35
+ block.call(child)
36
+ handle_recursive_child(child, &block)
37
+ end
33
38
  end
34
39
  end
35
- end
40
+ end
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery::ParserAdapter
4
+ def is_node?(node)
5
+ node.is_a?(Parser::AST::Node)
6
+ end
7
+
4
8
  def get_node_type(node)
5
9
  node.type
6
10
  end
@@ -10,11 +14,11 @@ class NodeQuery::ParserAdapter
10
14
  end
11
15
 
12
16
  def get_children(node)
13
- node.is_a?(Parser::AST::Node) ? node.children : []
17
+ node.children
14
18
  end
15
19
 
16
20
  def get_siblings(node)
17
21
  index = node.parent.children.index(node)
18
22
  node.parent.children[index + 1..]
19
23
  end
20
- end
24
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class NodeQuery
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.0"
5
5
  end
@@ -10,7 +10,7 @@ macros
10
10
  OPEN_DYNAMIC_ATTRIBUTE /{{/
11
11
  CLOSE_DYNAMIC_ATTRIBUTE /}}/
12
12
  NODE_TYPE /\.[a-z]+/
13
- IDENTIFIER /[\.\w]+/
13
+ IDENTIFIER /[\*\.\w]*\w/
14
14
  IDENTIFIER_VALUE /[\.\w!&:\?<>=]+/
15
15
  FALSE /false/
16
16
  FLOAT /\d+\.\d+/
@@ -0,0 +1,291 @@
1
+ # frozen_string_literal: true
2
+ # encoding: UTF-8
3
+ #--
4
+ # This file is automatically generated. Do not modify it.
5
+ # Generated by: oedipus_lex version 2.6.0.
6
+ # Source: lib/node_query_lexer.rex
7
+ #++
8
+
9
+
10
+ ##
11
+ # The generated lexer NodeQueryLexer
12
+
13
+ class NodeQueryLexer
14
+ require 'strscan'
15
+
16
+ # :stopdoc:
17
+ OPEN_ATTRIBUTE = /\[/
18
+ CLOSE_ATTRIBUTE = /\]/
19
+ OPEN_ARRAY = /\(/
20
+ CLOSE_ARRAY = /\)/
21
+ OPEN_SELECTOR = /\(/
22
+ CLOSE_SELECTOR = /\)/
23
+ OPEN_DYNAMIC_ATTRIBUTE = /{{/
24
+ CLOSE_DYNAMIC_ATTRIBUTE = /}}/
25
+ NODE_TYPE = /\.[a-z]+/
26
+ IDENTIFIER = /[\*\.\w]*\w/
27
+ IDENTIFIER_VALUE = /[\.\w!&:\?<>=]+/
28
+ FALSE = /false/
29
+ FLOAT = /\d+\.\d+/
30
+ INTEGER = /\d+/
31
+ NIL = /nil/
32
+ REGEXP_BODY = /(?:[^\/]|\\\/)*/
33
+ REGEXP = /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
34
+ SYMBOL = /:[\w!\?<>=]+/
35
+ TRUE = /true/
36
+ SINGLE_QUOTE_STRING = /'.*?'/
37
+ DOUBLE_QUOTE_STRING = /".*?"/
38
+ # :startdoc:
39
+ # :stopdoc:
40
+ class LexerError < StandardError ; end
41
+ class ScanError < LexerError ; end
42
+ # :startdoc:
43
+
44
+ ##
45
+ # The file name / path
46
+
47
+ attr_accessor :filename
48
+
49
+ ##
50
+ # The StringScanner for this lexer.
51
+
52
+ attr_accessor :ss
53
+
54
+ ##
55
+ # The current lexical state.
56
+
57
+ attr_accessor :state
58
+
59
+ alias :match :ss
60
+
61
+ ##
62
+ # The match groups for the current scan.
63
+
64
+ def matches
65
+ m = (1..9).map { |i| ss[i] }
66
+ m.pop until m[-1] or m.empty?
67
+ m
68
+ end
69
+
70
+ ##
71
+ # Yields on the current action.
72
+
73
+ def action
74
+ yield
75
+ end
76
+
77
+
78
+ ##
79
+ # The current scanner class. Must be overridden in subclasses.
80
+
81
+ def scanner_class
82
+ StringScanner
83
+ end unless instance_methods(false).map(&:to_s).include?("scanner_class")
84
+
85
+ ##
86
+ # Parse the given string.
87
+
88
+ def parse str
89
+ self.ss = scanner_class.new str
90
+ self.state ||= nil
91
+
92
+ do_parse
93
+ end
94
+
95
+ ##
96
+ # Read in and parse the file at +path+.
97
+
98
+ def parse_file path
99
+ self.filename = path
100
+ open path do |f|
101
+ parse f.read
102
+ end
103
+ end
104
+
105
+ ##
106
+ # The current location in the parse.
107
+
108
+ def location
109
+ [
110
+ (filename || "<input>"),
111
+ ].compact.join(":")
112
+ end
113
+
114
+ ##
115
+ # Lex the next token.
116
+
117
+ def next_token
118
+
119
+ token = nil
120
+
121
+ until ss.eos? or token do
122
+ token =
123
+ case state
124
+ when nil then
125
+ case
126
+ when ss.skip(/\s+/) then
127
+ # do nothing
128
+ when text = ss.scan(/,/) then
129
+ action { [:tCOMMA, text] }
130
+ when text = ss.scan(/:has/) then
131
+ action { [:tPSEUDO_CLASS, text[1..-1]] }
132
+ when text = ss.scan(/:not_has/) then
133
+ action { [:tPSEUDO_CLASS, text[1..-1]] }
134
+ when text = ss.scan(/#{NODE_TYPE}/) then
135
+ action { [:tNODE_TYPE, text[1..]] }
136
+ when text = ss.scan(/#{IDENTIFIER}/) then
137
+ action { [:tGOTO_SCOPE, text] }
138
+ when text = ss.scan(/>/) then
139
+ action { [:tRELATIONSHIP, text] }
140
+ when text = ss.scan(/~/) then
141
+ action { [:tRELATIONSHIP, text] }
142
+ when text = ss.scan(/\+/) then
143
+ action { [:tRELATIONSHIP, text] }
144
+ when text = ss.scan(/#{OPEN_SELECTOR}/) then
145
+ action { [:tOPEN_SELECTOR, text] }
146
+ when text = ss.scan(/#{CLOSE_SELECTOR}/) then
147
+ action { [:tCLOSE_SELECTOR, text] }
148
+ when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
149
+ action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
150
+ else
151
+ text = ss.string[ss.pos .. -1]
152
+ raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
153
+ end
154
+ when :KEY then
155
+ case
156
+ when ss.skip(/\s+/) then
157
+ # do nothing
158
+ when ss.skip(/\^=/) then
159
+ action { @state = :VALUE; [:tOPERATOR, '^='] }
160
+ when ss.skip(/\$=/) then
161
+ action { @state = :VALUE; [:tOPERATOR, '$='] }
162
+ when ss.skip(/\*=/) then
163
+ action { @state = :VALUE; [:tOPERATOR, '*='] }
164
+ when ss.skip(/!=/) then
165
+ action { @state = :VALUE; [:tOPERATOR, '!='] }
166
+ when ss.skip(/=~/) then
167
+ action { @state = :VALUE; [:tOPERATOR, '=~'] }
168
+ when ss.skip(/!~/) then
169
+ action { @state = :VALUE; [:tOPERATOR, '!~'] }
170
+ when ss.skip(/>=/) then
171
+ action { @state = :VALUE; [:tOPERATOR, '>='] }
172
+ when ss.skip(/<=/) then
173
+ action { @state = :VALUE; [:tOPERATOR, '<='] }
174
+ when ss.skip(/>/) then
175
+ action { @state = :VALUE; [:tOPERATOR, '>'] }
176
+ when ss.skip(/</) then
177
+ action { @state = :VALUE; [:tOPERATOR, '<'] }
178
+ when ss.skip(/=/) then
179
+ action { @state = :VALUE; [:tOPERATOR, '=='] }
180
+ when ss.skip(/includes/i) then
181
+ action { @state = :VALUE; [:tOPERATOR, 'includes'] }
182
+ when ss.skip(/not in/i) then
183
+ action { @state = :VALUE; [:tOPERATOR, 'not_in'] }
184
+ when ss.skip(/in/i) then
185
+ action { @state = :VALUE; [:tOPERATOR, 'in'] }
186
+ when text = ss.scan(/#{IDENTIFIER}/) then
187
+ action { [:tKEY, text] }
188
+ else
189
+ text = ss.string[ss.pos .. -1]
190
+ raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
191
+ end
192
+ when :VALUE then
193
+ case
194
+ when ss.skip(/\s+/) then
195
+ # do nothing
196
+ when text = ss.scan(/\[\]=/) then
197
+ action { [:tIDENTIFIER_VALUE, text] }
198
+ when text = ss.scan(/\[\]/) then
199
+ action { [:tIDENTIFIER_VALUE, text] }
200
+ when text = ss.scan(/:\[\]=/) then
201
+ action { [:tSYMBOL, text[1..-1].to_sym] }
202
+ when text = ss.scan(/:\[\]/) then
203
+ action { [:tSYMBOL, text[1..-1].to_sym] }
204
+ when text = ss.scan(/{{#{IDENTIFIER}}}/) then
205
+ action { [:tDYNAMIC_ATTRIBUTE, text[2..-3]] }
206
+ when text = ss.scan(/#{OPEN_ARRAY}/) then
207
+ action { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
208
+ when text = ss.scan(/#{CLOSE_ATTRIBUTE}/) then
209
+ action { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
210
+ when text = ss.scan(/#{NIL}\?/) then
211
+ action { [:tIDENTIFIER_VALUE, text] }
212
+ when ss.skip(/#{NIL}/) then
213
+ action { [:tNIL, nil] }
214
+ when ss.skip(/#{TRUE}/) then
215
+ action { [:tBOOLEAN, true] }
216
+ when ss.skip(/#{FALSE}/) then
217
+ action { [:tBOOLEAN, false] }
218
+ when text = ss.scan(/#{SYMBOL}/) then
219
+ action { [:tSYMBOL, text[1..-1].to_sym] }
220
+ when text = ss.scan(/#{FLOAT}/) then
221
+ action { [:tFLOAT, text.to_f] }
222
+ when text = ss.scan(/#{INTEGER}/) then
223
+ action { [:tINTEGER, text.to_i] }
224
+ when text = ss.scan(/#{REGEXP}/) then
225
+ action { [:tREGEXP, eval(text)] }
226
+ when text = ss.scan(/#{DOUBLE_QUOTE_STRING}/) then
227
+ action { [:tSTRING, text[1...-1]] }
228
+ when text = ss.scan(/#{SINGLE_QUOTE_STRING}/) then
229
+ action { [:tSTRING, text[1...-1]] }
230
+ when text = ss.scan(/#{NODE_TYPE}/) then
231
+ action { [:tNODE_TYPE, text[1..]] }
232
+ when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
233
+ action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
234
+ when text = ss.scan(/#{IDENTIFIER_VALUE}/) then
235
+ action { [:tIDENTIFIER_VALUE, text] }
236
+ else
237
+ text = ss.string[ss.pos .. -1]
238
+ raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
239
+ end
240
+ when :ARRAY_VALUE then
241
+ case
242
+ when ss.skip(/\s+/) then
243
+ # do nothing
244
+ when text = ss.scan(/#{CLOSE_ARRAY}/) then
245
+ action { @state = :VALUE; [:tCLOSE_ARRAY, text] }
246
+ when text = ss.scan(/#{NIL}\?/) then
247
+ action { [:tIDENTIFIER_VALUE, text] }
248
+ when ss.skip(/#{NIL}/) then
249
+ action { [:tNIL, nil] }
250
+ when ss.skip(/#{TRUE}/) then
251
+ action { [:tBOOLEAN, true] }
252
+ when ss.skip(/#{FALSE}/) then
253
+ action { [:tBOOLEAN, false] }
254
+ when text = ss.scan(/#{SYMBOL}/) then
255
+ action { [:tSYMBOL, text[1..-1].to_sym] }
256
+ when text = ss.scan(/#{FLOAT}/) then
257
+ action { [:tFLOAT, text.to_f] }
258
+ when text = ss.scan(/#{INTEGER}/) then
259
+ action { [:tINTEGER, text.to_i] }
260
+ when text = ss.scan(/#{REGEXP}/) then
261
+ action { [:tREGEXP, eval(text)] }
262
+ when text = ss.scan(/#{DOUBLE_QUOTE_STRING}/) then
263
+ action { [:tSTRING, text[1...-1]] }
264
+ when text = ss.scan(/#{SINGLE_QUOTE_STRING}/) then
265
+ action { [:tSTRING, text[1...-1]] }
266
+ when text = ss.scan(/#{IDENTIFIER_VALUE}/) then
267
+ action { [:tIDENTIFIER_VALUE, text] }
268
+ else
269
+ text = ss.string[ss.pos .. -1]
270
+ raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
271
+ end
272
+ else
273
+ raise ScanError, "undefined state at #{location}: '#{state}'"
274
+ end # token = case state
275
+
276
+ next unless token # allow functions to trigger redo w/ nil
277
+ end # while
278
+
279
+ raise LexerError, "bad lexical result at #{location}: #{token.inspect}" unless
280
+ token.nil? || (Array === token && token.size >= 2)
281
+
282
+ # auto-switch state
283
+ self.state = token.last if token && token.first == :state
284
+
285
+ token
286
+ end # def next_token
287
+ def initialize
288
+ @nested_count = 0
289
+ end
290
+ def do_parse; end
291
+ end # class
@@ -0,0 +1,309 @@
1
+ #
2
+ # DO NOT MODIFY!!!!
3
+ # This file is automatically generated by Racc 1.6.0
4
+ # from Racc grammar file "".
5
+ #
6
+
7
+ require 'racc/parser.rb'
8
+ class NodeQueryParser < Racc::Parser
9
+
10
+ def initialize
11
+ @lexer = NodeQueryLexer.new
12
+ end
13
+
14
+ def parse string
15
+ @lexer.parse string
16
+ do_parse
17
+ end
18
+
19
+ def next_token
20
+ @lexer.next_token
21
+ end
22
+ ##### State transition tables begin ###
23
+
24
+ racc_action_table = [
25
+ 8, 8, 7, 9, 10, 37, 12, 5, 6, 16,
26
+ 27, 17, 21, 22, 23, 24, 29, 30, 31, 32,
27
+ 33, 34, 35, 36, 8, 16, 41, 8, 7, 37,
28
+ nil, nil, 8, 5, 6, 38, nil, 37, nil, nil,
29
+ 29, 30, 31, 32, 33, 34, 35, 36, 29, 30,
30
+ 31, 32, 33, 34, 35, 36, 8, 7, 8, 7,
31
+ 8, 7, 5, 6, 5, 6, 5, 6, 8, 7,
32
+ nil, nil, nil, nil, 5, 6 ]
33
+
34
+ racc_action_check = [
35
+ 24, 0, 0, 1, 2, 24, 5, 0, 0, 8,
36
+ 24, 9, 16, 19, 20, 21, 24, 24, 24, 24,
37
+ 24, 24, 24, 24, 27, 23, 39, 3, 3, 27,
38
+ nil, nil, 40, 3, 3, 27, nil, 40, nil, nil,
39
+ 27, 27, 27, 27, 27, 27, 27, 27, 40, 40,
40
+ 40, 40, 40, 40, 40, 40, 6, 6, 7, 7,
41
+ 10, 10, 6, 6, 7, 7, 10, 10, 12, 12,
42
+ nil, nil, nil, nil, 12, 12 ]
43
+
44
+ racc_action_pointer = [
45
+ -2, 3, 2, 24, nil, -9, 53, 55, -2, 11,
46
+ 57, nil, 65, nil, nil, nil, 6, nil, nil, -3,
47
+ 2, -2, nil, 14, -3, nil, nil, 21, nil, nil,
48
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 12,
49
+ 29, nil, nil ]
50
+
51
+ racc_action_default = [
52
+ -28, -28, -2, -4, -5, -28, -28, -28, -9, -28,
53
+ -28, -3, -28, -7, -8, -10, -28, 43, -1, -28,
54
+ -28, -28, -6, -12, -28, -11, -13, -28, -18, -19,
55
+ -20, -21, -22, -23, -24, -25, -26, -27, -14, -28,
56
+ -17, -15, -16 ]
57
+
58
+ racc_goto_table = [
59
+ 28, 39, 15, 28, 11, 1, 13, 14, 20, 26,
60
+ nil, nil, 19, nil, 42, 18, 28, 25 ]
61
+
62
+ racc_goto_check = [
63
+ 4, 8, 5, 4, 2, 1, 3, 3, 6, 7,
64
+ nil, nil, 3, nil, 8, 1, 4, 5 ]
65
+
66
+ racc_goto_pointer = [
67
+ nil, 5, 1, 0, -24, -6, -8, -15, -26 ]
68
+
69
+ racc_goto_default = [
70
+ nil, nil, 2, 3, 4, nil, nil, 40, nil ]
71
+
72
+ racc_reduce_table = [
73
+ 0, 0, :racc_error,
74
+ 3, 28, :_reduce_1,
75
+ 1, 28, :_reduce_2,
76
+ 2, 29, :_reduce_3,
77
+ 1, 29, :_reduce_4,
78
+ 1, 30, :_reduce_5,
79
+ 4, 30, :_reduce_6,
80
+ 2, 30, :_reduce_7,
81
+ 2, 30, :_reduce_8,
82
+ 1, 31, :_reduce_9,
83
+ 2, 31, :_reduce_10,
84
+ 4, 32, :_reduce_11,
85
+ 3, 32, :_reduce_12,
86
+ 3, 33, :_reduce_13,
87
+ 4, 33, :_reduce_14,
88
+ 5, 33, :_reduce_15,
89
+ 2, 35, :_reduce_16,
90
+ 1, 35, :_reduce_17,
91
+ 1, 34, :_reduce_none,
92
+ 1, 34, :_reduce_19,
93
+ 1, 34, :_reduce_20,
94
+ 1, 34, :_reduce_21,
95
+ 1, 34, :_reduce_22,
96
+ 1, 34, :_reduce_23,
97
+ 1, 34, :_reduce_24,
98
+ 1, 34, :_reduce_25,
99
+ 1, 34, :_reduce_26,
100
+ 1, 34, :_reduce_27 ]
101
+
102
+ racc_reduce_n = 28
103
+
104
+ racc_shift_n = 43
105
+
106
+ racc_token_table = {
107
+ false => 0,
108
+ :error => 1,
109
+ :tCOMMA => 2,
110
+ :tNODE_TYPE => 3,
111
+ :tGOTO_SCOPE => 4,
112
+ :tATTRIBUTE => 5,
113
+ :tKEY => 6,
114
+ :tIDENTIFIER => 7,
115
+ :tIDENTIFIER_VALUE => 8,
116
+ :tPSEUDO_CLASS => 9,
117
+ :tRELATIONSHIP => 10,
118
+ :tOPEN_ATTRIBUTE => 11,
119
+ :tCLOSE_ATTRIBUTE => 12,
120
+ :tOPEN_ARRAY => 13,
121
+ :tCLOSE_ARRAY => 14,
122
+ :tOPEN_SELECTOR => 15,
123
+ :tCLOSE_SELECTOR => 16,
124
+ :tOPERATOR => 17,
125
+ :tARRAY_VALUE => 18,
126
+ :tDYNAMIC_ATTRIBUTE => 19,
127
+ :tBOOLEAN => 20,
128
+ :tFLOAT => 21,
129
+ :tINTEGER => 22,
130
+ :tNIL => 23,
131
+ :tREGEXP => 24,
132
+ :tSTRING => 25,
133
+ :tSYMBOL => 26 }
134
+
135
+ racc_nt_base = 27
136
+
137
+ racc_use_result_var = false
138
+
139
+ Racc_arg = [
140
+ racc_action_table,
141
+ racc_action_check,
142
+ racc_action_default,
143
+ racc_action_pointer,
144
+ racc_goto_table,
145
+ racc_goto_check,
146
+ racc_goto_default,
147
+ racc_goto_pointer,
148
+ racc_nt_base,
149
+ racc_reduce_table,
150
+ racc_token_table,
151
+ racc_shift_n,
152
+ racc_reduce_n,
153
+ racc_use_result_var ]
154
+
155
+ Racc_token_to_s_table = [
156
+ "$end",
157
+ "error",
158
+ "tCOMMA",
159
+ "tNODE_TYPE",
160
+ "tGOTO_SCOPE",
161
+ "tATTRIBUTE",
162
+ "tKEY",
163
+ "tIDENTIFIER",
164
+ "tIDENTIFIER_VALUE",
165
+ "tPSEUDO_CLASS",
166
+ "tRELATIONSHIP",
167
+ "tOPEN_ATTRIBUTE",
168
+ "tCLOSE_ATTRIBUTE",
169
+ "tOPEN_ARRAY",
170
+ "tCLOSE_ARRAY",
171
+ "tOPEN_SELECTOR",
172
+ "tCLOSE_SELECTOR",
173
+ "tOPERATOR",
174
+ "tARRAY_VALUE",
175
+ "tDYNAMIC_ATTRIBUTE",
176
+ "tBOOLEAN",
177
+ "tFLOAT",
178
+ "tINTEGER",
179
+ "tNIL",
180
+ "tREGEXP",
181
+ "tSTRING",
182
+ "tSYMBOL",
183
+ "$start",
184
+ "expression_list",
185
+ "expression",
186
+ "selector",
187
+ "basic_selector",
188
+ "attribute_list",
189
+ "attribute",
190
+ "value",
191
+ "array_value" ]
192
+
193
+ Racc_debug_parser = false
194
+
195
+ ##### State transition tables end #####
196
+
197
+ # reduce 0 omitted
198
+
199
+ def _reduce_1(val, _values)
200
+ NodeQuery::Compiler::ExpressionList.new(expression: val[0], rest: val[2])
201
+ end
202
+
203
+ def _reduce_2(val, _values)
204
+ NodeQuery::Compiler::ExpressionList.new(expression: val[0])
205
+ end
206
+
207
+ def _reduce_3(val, _values)
208
+ NodeQuery::Compiler::Expression.new(selector: val[0], rest: val[1])
209
+ end
210
+
211
+ def _reduce_4(val, _values)
212
+ NodeQuery::Compiler::Expression.new(selector: val[0])
213
+ end
214
+
215
+ def _reduce_5(val, _values)
216
+ NodeQuery::Compiler::Selector.new(basic_selector: val[0])
217
+ end
218
+
219
+ def _reduce_6(val, _values)
220
+ NodeQuery::Compiler::Selector.new(pseudo_class: val[0], pseudo_selector: val[2])
221
+ end
222
+
223
+ def _reduce_7(val, _values)
224
+ NodeQuery::Compiler::Selector.new(relationship: val[0], rest: val[1])
225
+ end
226
+
227
+ def _reduce_8(val, _values)
228
+ NodeQuery::Compiler::Selector.new(goto_scope: val[0], rest: val[1])
229
+ end
230
+
231
+ def _reduce_9(val, _values)
232
+ NodeQuery::Compiler::BasicSelector.new(node_type: val[0])
233
+ end
234
+
235
+ def _reduce_10(val, _values)
236
+ NodeQuery::Compiler::BasicSelector.new(node_type: val[0], attribute_list: val[1])
237
+ end
238
+
239
+ def _reduce_11(val, _values)
240
+ NodeQuery::Compiler::AttributeList.new(attribute: val[1], rest: val[3])
241
+ end
242
+
243
+ def _reduce_12(val, _values)
244
+ NodeQuery::Compiler::AttributeList.new(attribute: val[1])
245
+ end
246
+
247
+ def _reduce_13(val, _values)
248
+ NodeQuery::Compiler::Attribute.new(key: val[0], value: val[2], operator: val[1])
249
+ end
250
+
251
+ def _reduce_14(val, _values)
252
+ NodeQuery::Compiler::Attribute.new(key: val[0], value: NodeQuery::Compiler::Array.new, operator: val[1])
253
+ end
254
+
255
+ def _reduce_15(val, _values)
256
+ NodeQuery::Compiler::Attribute.new(key: val[0], value: val[3], operator: val[1])
257
+ end
258
+
259
+ def _reduce_16(val, _values)
260
+ NodeQuery::Compiler::ArrayValue.new(value: val[0], rest: val[1])
261
+ end
262
+
263
+ def _reduce_17(val, _values)
264
+ NodeQuery::Compiler::ArrayValue.new(value: val[0])
265
+ end
266
+
267
+ # reduce 18 omitted
268
+
269
+ def _reduce_19(val, _values)
270
+ NodeQuery::Compiler::EvaluatedValue.new(value: val[0])
271
+ end
272
+
273
+ def _reduce_20(val, _values)
274
+ NodeQuery::Compiler::Boolean.new(value: val[0])
275
+ end
276
+
277
+ def _reduce_21(val, _values)
278
+ NodeQuery::Compiler::Float.new(value: val[0])
279
+ end
280
+
281
+ def _reduce_22(val, _values)
282
+ NodeQuery::Compiler::Integer.new(value: val[0])
283
+ end
284
+
285
+ def _reduce_23(val, _values)
286
+ NodeQuery::Compiler::Nil.new(value: val[0])
287
+ end
288
+
289
+ def _reduce_24(val, _values)
290
+ NodeQuery::Compiler::Regexp.new(value: val[0])
291
+ end
292
+
293
+ def _reduce_25(val, _values)
294
+ NodeQuery::Compiler::String.new(value: val[0])
295
+ end
296
+
297
+ def _reduce_26(val, _values)
298
+ NodeQuery::Compiler::Symbol.new(value: val[0])
299
+ end
300
+
301
+ def _reduce_27(val, _values)
302
+ NodeQuery::Compiler::Identifier.new(value: val[0])
303
+ end
304
+
305
+ def _reduce_none(val, _values)
306
+ val[0]
307
+ end
308
+
309
+ end # class NodeQueryParser
data/node_query.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.metadata["homepage_uri"] = spec.homepage
17
17
  spec.metadata["source_code_uri"] = "https://github.com/xinminlabs/node-query-ruby"
18
- spec.metadata["changelog_uri"] = "https://github.com/xinminlabs/node-query-ruby/CHANGELOG.md"
18
+ spec.metadata["changelog_uri"] = "https://github.com/xinminlabs/node-query-ruby/blob/master/CHANGELOG.md"
19
19
 
20
20
  # Specify which files should be added to the gem when it is released.
21
21
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  `git ls-files -z`.split("\x0").reject do |f|
24
24
  (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
25
25
  end
26
- end
26
+ end + %w[lib/node_query_lexer.rex.rb lib/node_query_parser.racc.rb]
27
27
  spec.bindir = "exe"
28
28
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]
@@ -0,0 +1,11 @@
1
+ class NodeQuery::Adapter
2
+ def is_node?: (node: Node) -> Boolean
3
+
4
+ def get_node_type: (node: Node) -> String
5
+
6
+ def get_source: (node: Node) -> String
7
+
8
+ def get_children: (node: Node) -> Array[Node]
9
+
10
+ def get_siblings: (node: Node) -> Array[Node]
11
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: node_query
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-06-26 00:00:00.000000000 Z
11
+ date: 2022-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -64,15 +64,18 @@ files:
64
64
  - lib/node_query/parser_adapter.rb
65
65
  - lib/node_query/version.rb
66
66
  - lib/node_query_lexer.rex
67
+ - lib/node_query_lexer.rex.rb
68
+ - lib/node_query_parser.racc.rb
67
69
  - lib/node_query_parser.y
68
70
  - node_query.gemspec
69
71
  - sig/node_query.rbs
72
+ - sig/node_query/adapter.rbs
70
73
  homepage: https://github.com/xinminlabs/node-query-ruby
71
74
  licenses: []
72
75
  metadata:
73
76
  homepage_uri: https://github.com/xinminlabs/node-query-ruby
74
77
  source_code_uri: https://github.com/xinminlabs/node-query-ruby
75
- changelog_uri: https://github.com/xinminlabs/node-query-ruby/CHANGELOG.md
78
+ changelog_uri: https://github.com/xinminlabs/node-query-ruby/blob/master/CHANGELOG.md
76
79
  post_install_message:
77
80
  rdoc_options: []
78
81
  require_paths: