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 +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:
|