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 +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/lib/node_query/adapter.rb +6 -0
- data/lib/node_query/compiler/comparable.rb +10 -2
- data/lib/node_query/helper.rb +9 -4
- data/lib/node_query/parser_adapter.rb +6 -2
- data/lib/node_query/version.rb +1 -1
- data/lib/node_query_lexer.rex +1 -1
- data/lib/node_query_lexer.rex.rb +291 -0
- data/lib/node_query_parser.racc.rb +309 -0
- data/node_query.gemspec +2 -2
- data/sig/node_query/adapter.rbs +11 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 937481646456841ca565042544794aa91a0339c40790f14233d721f45b0531fa
|
4
|
+
data.tar.gz: 807b2709a6350489229a86febb0d6d7eb9684f8ce4fb712603d6bcd6cb62f192
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9bff7b923a263ad1817226f7fbb095cb9275b1f0e6f27dadd5562202c04aa2ba7bebb0c5b4659484dfeafc5adff268a7f8cd09e7c1f628b17d9c638fbc280c41
|
7
|
+
data.tar.gz: 102c406278c8b752c6ead8856247678f79a5ca2fb178f625a746030c330f9310a6f3d4decdb860a12cad8ae95982d014b102704c5afe60edfe95c066ad26dc3f
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/lib/node_query/adapter.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/node_query/helper.rb
CHANGED
@@ -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
|
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
|
-
|
32
|
-
|
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.
|
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
|
data/lib/node_query/version.rb
CHANGED
data/lib/node_query_lexer.rex
CHANGED
@@ -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.
|
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-
|
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:
|