node_query 1.0.0 → 1.1.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 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: