synvert-core 0.64.0 → 1.0.1
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/.github/workflows/main.yml +1 -1
- data/.gitignore +4 -0
- data/CHANGELOG.md +5 -0
- data/Guardfile +11 -2
- data/README.md +2 -2
- data/Rakefile +15 -1
- data/lib/synvert/core/array_ext.rb +41 -0
- data/lib/synvert/core/engine/erb.rb +9 -8
- data/lib/synvert/core/node_ext.rb +47 -44
- data/lib/synvert/core/node_query/compiler/array.rb +34 -0
- data/lib/synvert/core/node_query/compiler/attribute.rb +51 -0
- data/lib/synvert/core/node_query/compiler/attribute_list.rb +24 -0
- data/lib/synvert/core/node_query/compiler/boolean.rb +23 -0
- data/lib/synvert/core/node_query/compiler/comparable.rb +79 -0
- data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +51 -0
- data/lib/synvert/core/node_query/compiler/expression.rb +88 -0
- data/lib/synvert/core/node_query/compiler/float.rb +23 -0
- data/lib/synvert/core/node_query/compiler/identifier.rb +41 -0
- data/lib/synvert/core/node_query/compiler/integer.rb +23 -0
- data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +7 -0
- data/lib/synvert/core/node_query/compiler/nil.rb +23 -0
- data/lib/synvert/core/node_query/compiler/parse_error.rb +7 -0
- data/lib/synvert/core/node_query/compiler/regexp.rb +37 -0
- data/lib/synvert/core/node_query/compiler/selector.rb +51 -0
- data/lib/synvert/core/node_query/compiler/string.rb +34 -0
- data/lib/synvert/core/node_query/compiler/symbol.rb +23 -0
- data/lib/synvert/core/node_query/compiler.rb +24 -0
- data/lib/synvert/core/node_query/lexer.rex +96 -0
- data/lib/synvert/core/node_query/lexer.rex.rb +293 -0
- data/lib/synvert/core/node_query/parser.racc.rb +518 -0
- data/lib/synvert/core/node_query/parser.y +84 -0
- data/lib/synvert/core/node_query.rb +36 -0
- data/lib/synvert/core/rewriter/action/delete_action.rb +4 -2
- data/lib/synvert/core/rewriter/action/replace_action.rb +4 -2
- data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +2 -2
- data/lib/synvert/core/rewriter/action/wrap_action.rb +3 -2
- data/lib/synvert/core/rewriter/action.rb +2 -1
- data/lib/synvert/core/rewriter/helper.rb +5 -2
- data/lib/synvert/core/rewriter/instance.rb +25 -13
- data/lib/synvert/core/rewriter/scope/query_scope.rb +36 -0
- data/lib/synvert/core/rewriter/scope/within_scope.rb +1 -1
- data/lib/synvert/core/rewriter.rb +1 -0
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +22 -5
- data/spec/synvert/core/engine/erb_spec.rb +2 -2
- data/spec/synvert/core/node_ext_spec.rb +36 -5
- data/spec/synvert/core/node_query/lexer_spec.rb +512 -0
- data/spec/synvert/core/node_query/parser_spec.rb +270 -0
- data/spec/synvert/core/rewriter/condition/if_only_exist_condition_spec.rb +1 -6
- data/spec/synvert/core/rewriter/helper_spec.rb +4 -1
- data/spec/synvert/core/rewriter/instance_spec.rb +24 -3
- data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +74 -0
- data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +12 -9
- data/spec/synvert/core/rewriter_spec.rb +4 -2
- data/synvert-core-ruby.gemspec +5 -1
- metadata +75 -2
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Expression represents a node query expression.
|
5
|
+
class Expression
|
6
|
+
# Initialize a Expression.
|
7
|
+
# @param selector [Synvert::Core::NodeQuery::Compiler::Selector] the selector
|
8
|
+
# @param rest [Synvert::Core::NodeQuery::Compiler::Expression] the rest expression
|
9
|
+
# @param relationship [Symbol] the relationship between the selector and rest expression, it can be <code>:descendant</code>, <code>:child</code>, <code>:next_sibling</code>, <code>:subsequent_sibling</code> or <code>nil</code>.
|
10
|
+
def initialize(selector: nil, rest: nil, relationship: nil)
|
11
|
+
@selector = selector
|
12
|
+
@rest = rest
|
13
|
+
@relationship = relationship
|
14
|
+
end
|
15
|
+
|
16
|
+
# Check if the node matches the expression.
|
17
|
+
# @param node [Parser::AST::Node] the node
|
18
|
+
# @return [Boolean]
|
19
|
+
def match?(node)
|
20
|
+
!query_nodes(node).empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Query nodes by the expression.
|
24
|
+
#
|
25
|
+
# * If relationship is nil, it will match in all recursive child nodes and return matching nodes.
|
26
|
+
# * If relationship is :decendant, it will match in all recursive child nodes.
|
27
|
+
# * If relationship is :child, it will match in direct child nodes.
|
28
|
+
# * If relationship is :next_sibling, it try to match next sibling node.
|
29
|
+
# * If relationship is :subsequent_sibling, it will match in all sibling nodes.
|
30
|
+
# @param node [Parser::AST::Node] node to match
|
31
|
+
# @param descendant_match [Boolean] whether to match in descendant node
|
32
|
+
# @return [Array<Parser::AST::Node>] matching nodes.
|
33
|
+
def query_nodes(node, descendant_match: true)
|
34
|
+
matching_nodes = find_nodes_without_relationship(node, descendant_match: descendant_match)
|
35
|
+
if @relationship.nil?
|
36
|
+
return matching_nodes
|
37
|
+
end
|
38
|
+
|
39
|
+
expression_nodes = matching_nodes.map do |matching_node|
|
40
|
+
case @relationship
|
41
|
+
when :descendant
|
42
|
+
nodes = []
|
43
|
+
matching_node.recursive_children { |child_node|
|
44
|
+
nodes += @rest.query_nodes(child_node, descendant_match: false)
|
45
|
+
}
|
46
|
+
nodes
|
47
|
+
when :child
|
48
|
+
matching_node.children.map { |child_node| @rest.query_nodes(child_node, descendant_match: false) }
|
49
|
+
.flatten
|
50
|
+
when :next_sibling
|
51
|
+
@rest.query_nodes(matching_node.siblings.first, descendant_match: false)
|
52
|
+
when :subsequent_sibling
|
53
|
+
matching_node.siblings.map { |sibling_node| @rest.query_nodes(sibling_node, descendant_match: false) }
|
54
|
+
.flatten
|
55
|
+
end
|
56
|
+
end.flatten
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_s
|
60
|
+
return @selector.to_s unless @rest
|
61
|
+
|
62
|
+
result = []
|
63
|
+
result << @selector if @selector
|
64
|
+
case @relationship
|
65
|
+
when :child then result << '>'
|
66
|
+
when :subsequent_sibling then result << '~'
|
67
|
+
when :next_sibling then result << '+'
|
68
|
+
end
|
69
|
+
result << @rest
|
70
|
+
result.map(&:to_s).join(' ')
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def find_nodes_without_relationship(node, descendant_match: true)
|
76
|
+
return [node] unless @selector
|
77
|
+
|
78
|
+
nodes = []
|
79
|
+
nodes << node if @selector.match?(node)
|
80
|
+
if descendant_match
|
81
|
+
node.recursive_children do |child_node|
|
82
|
+
nodes << child_node if @selector.match?(child_node)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
@selector.filter(nodes)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Float represents a ruby float value.
|
5
|
+
class Float
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# Initialize a Float.
|
9
|
+
# @param value [Float] the float value
|
10
|
+
def initialize(value:)
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get valid operators.
|
15
|
+
def valid_operators
|
16
|
+
NUMBER_VALID_OPERATORS
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
@value.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Identifier represents a ruby identifier value.
|
5
|
+
# e.g. code is `class Synvert; end`, `Synvert` is an identifier.
|
6
|
+
class Identifier
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
# Initialize an Identifier.
|
10
|
+
# @param value [String] the identifier value
|
11
|
+
def initialize(value:)
|
12
|
+
@value = value
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get the actual value.
|
16
|
+
#
|
17
|
+
# @param node the node
|
18
|
+
# @return [String|Array]
|
19
|
+
# If the node is a {Parser::AST::Node}, return the node source code,
|
20
|
+
# if the node is an Array, return the array of each element's actual value,
|
21
|
+
# otherwise, return the String value.
|
22
|
+
def actual_value(node)
|
23
|
+
if node.is_a?(::Parser::AST::Node)
|
24
|
+
node.to_source
|
25
|
+
elsif node.is_a?(::Array)
|
26
|
+
node.map { |n| actual_value(n) }
|
27
|
+
else
|
28
|
+
node.to_s
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Get valid operators.
|
33
|
+
def valid_operators
|
34
|
+
SIMPLE_VALID_OPERATORS
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
@value
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Integer represents a ruby integer value.
|
5
|
+
class Integer
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# Initialize a Integer.
|
9
|
+
# @param value [Integer] the integer value
|
10
|
+
def initialize(value:)
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get valid operators.
|
15
|
+
def valid_operators
|
16
|
+
NUMBER_VALID_OPERATORS
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
@value.to_s
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Nil represents a ruby nil value.
|
5
|
+
class Nil
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# Initialize a Nil.
|
9
|
+
# @param value [nil] the nil value
|
10
|
+
def initialize(value:)
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get valid operators.
|
15
|
+
def valid_operators
|
16
|
+
SIMPLE_VALID_OPERATORS
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
'nil'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Regexp represents a ruby regexp value.
|
5
|
+
class Regexp
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# Initialize a Regexp.
|
9
|
+
# @param value [Regexp] the regexp value
|
10
|
+
def initialize(value:)
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
# Check if the regexp value matches the node value.
|
15
|
+
# @param node [Parser::AST::Node] the node
|
16
|
+
# @param operator [Symbol] the operator
|
17
|
+
# @return [Boolean] true if the regexp value matches the node value, otherwise, false.
|
18
|
+
def match?(node, operator = :=~)
|
19
|
+
match =
|
20
|
+
if node.is_a?(::Parser::AST::Node)
|
21
|
+
@value.match(node.to_source)
|
22
|
+
else
|
23
|
+
@value.match(node.to_s)
|
24
|
+
end
|
25
|
+
operator == :=~ ? match : !match
|
26
|
+
end
|
27
|
+
|
28
|
+
# Get valid operators.
|
29
|
+
def valid_operators
|
30
|
+
REGEXP_VALID_OPERATORS
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
@value.to_s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Selector used to match nodes, it combines by node type and/or attribute list, plus index or has expression.
|
5
|
+
class Selector
|
6
|
+
# Initialize a Selector.
|
7
|
+
# @param node_type [String] the node type
|
8
|
+
# @param attribute_list [Synvert::Core::NodeQuery::Compiler::AttributeList] the attribute list
|
9
|
+
# @param index [Integer] the index
|
10
|
+
# @param has_expression [Synvert::Core::NodeQuery::Compiler::Expression] the has expression
|
11
|
+
def initialize(node_type: nil, attribute_list: nil, index: nil, has_expression: nil)
|
12
|
+
@node_type = node_type
|
13
|
+
@attribute_list = attribute_list
|
14
|
+
@index = index
|
15
|
+
@has_expression = has_expression
|
16
|
+
end
|
17
|
+
|
18
|
+
# Filter nodes by index.
|
19
|
+
def filter(nodes)
|
20
|
+
return nodes if @index.nil?
|
21
|
+
|
22
|
+
nodes[@index] ? [nodes[@index]] : []
|
23
|
+
end
|
24
|
+
|
25
|
+
# Check if node matches the selector.
|
26
|
+
# @param node [Parser::AST::Node] the node
|
27
|
+
def match?(node, _operator = :==)
|
28
|
+
(!@node_type || (node.is_a?(::Parser::AST::Node) && @node_type.to_sym == node.type)) &&
|
29
|
+
(!@attribute_list || @attribute_list.match?(node)) &&
|
30
|
+
(!@has_expression || @has_expression.match?(node))
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_s
|
34
|
+
str = ".#{@node_type}#{@attribute_list}"
|
35
|
+
return str if !@index && !@has_expression
|
36
|
+
|
37
|
+
return "#{str}:has(#{@has_expression})" if @has_expression
|
38
|
+
|
39
|
+
case @index
|
40
|
+
when 0
|
41
|
+
str + ':first-child'
|
42
|
+
when -1
|
43
|
+
str + ':last-child'
|
44
|
+
when (1..)
|
45
|
+
str + ":nth-child(#{@index + 1})"
|
46
|
+
else # ...-1
|
47
|
+
str + ":nth-last-child(#{-@index})"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# String represents a ruby string value.
|
5
|
+
class String
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# Initialize a String.
|
9
|
+
# @param value [String] the string value
|
10
|
+
def initialize(value:)
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get valid operators.
|
15
|
+
def valid_operators
|
16
|
+
SIMPLE_VALID_OPERATORS
|
17
|
+
end
|
18
|
+
|
19
|
+
# Get the actual value of a node.
|
20
|
+
# @param node [Parser::AST::Node] the node
|
21
|
+
# @return [String] if node is a Parser::AST::Node, return the node source code, otherwise, return the string value.
|
22
|
+
def actual_value(node)
|
23
|
+
if node.is_a?(::Parser::AST::Node)
|
24
|
+
node.to_source
|
25
|
+
else
|
26
|
+
node.to_s
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
"\"#{@value}\""
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
# Symbol represents a ruby symbol value.
|
5
|
+
class Symbol
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# Initliaze a Symobol.
|
9
|
+
# @param value [Symbol] the symbol value
|
10
|
+
def initialize(value:)
|
11
|
+
@value = value
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get valid operators.
|
15
|
+
def valid_operators
|
16
|
+
SIMPLE_VALID_OPERATORS
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
":#{@value}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Synvert::Core::NodeQuery::Compiler
|
4
|
+
autoload :InvalidOperatorError, 'synvert/core/node_query/compiler/invalid_operator_error'
|
5
|
+
autoload :ParseError, 'synvert/core/node_query/compiler/parse_error'
|
6
|
+
|
7
|
+
autoload :Comparable, 'synvert/core/node_query/compiler/comparable'
|
8
|
+
|
9
|
+
autoload :Expression, 'synvert/core/node_query/compiler/expression'
|
10
|
+
autoload :Selector, 'synvert/core/node_query/compiler/selector'
|
11
|
+
autoload :AttributeList, 'synvert/core/node_query/compiler/attribute_list'
|
12
|
+
autoload :Attribute, 'synvert/core/node_query/compiler/attribute'
|
13
|
+
|
14
|
+
autoload :Array, 'synvert/core/node_query/compiler/array'
|
15
|
+
autoload :Boolean, 'synvert/core/node_query/compiler/boolean'
|
16
|
+
autoload :DynamicAttribute, 'synvert/core/node_query/compiler/dynamic_attribute'
|
17
|
+
autoload :Float, 'synvert/core/node_query/compiler/float'
|
18
|
+
autoload :Identifier, 'synvert/core/node_query/compiler/identifier'
|
19
|
+
autoload :Integer, 'synvert/core/node_query/compiler/integer'
|
20
|
+
autoload :Nil, 'synvert/core/node_query/compiler/nil'
|
21
|
+
autoload :Regexp, 'synvert/core/node_query/compiler/regexp'
|
22
|
+
autoload :String, 'synvert/core/node_query/compiler/string'
|
23
|
+
autoload :Symbol, 'synvert/core/node_query/compiler/symbol'
|
24
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
class Synvert::Core::NodeQuery::Lexer
|
2
|
+
|
3
|
+
macros
|
4
|
+
OPEN_ATTRIBUTE /\[/
|
5
|
+
CLOSE_ATTRIBUTE /\]/
|
6
|
+
OPEN_ARRAY /\(/
|
7
|
+
CLOSE_ARRAY /\)/
|
8
|
+
OPEN_SELECTOR /\(/
|
9
|
+
CLOSE_SELECTOR /\)/
|
10
|
+
OPEN_DYNAMIC_ATTRIBUTE /{{/
|
11
|
+
CLOSE_DYNAMIC_ATTRIBUTE /}}/
|
12
|
+
NODE_TYPE /\.[a-z]+/
|
13
|
+
IDENTIFIER /[\.\w]+/
|
14
|
+
IDENTIFIER_VALUE /[\.\w!&:]+/
|
15
|
+
FALSE /false/
|
16
|
+
FLOAT /\d+\.\d+/
|
17
|
+
INTEGER /\d+/
|
18
|
+
NIL /nil/
|
19
|
+
REGEXP_BODY /(?:[^\/]|\\\/)*/
|
20
|
+
REGEXP /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
|
21
|
+
SYMBOL /:[\w!]+/
|
22
|
+
TRUE /true/
|
23
|
+
SINGLE_QUOTE_STRING /'(.+?)'/
|
24
|
+
DOUBLE_QUOTE_STRING /"(.+?)"/
|
25
|
+
|
26
|
+
rules
|
27
|
+
|
28
|
+
# [:state] pattern [actions]
|
29
|
+
/\s+/
|
30
|
+
/:first-child/ { [:tINDEX, 0] }
|
31
|
+
/:last-child/ { [:tINDEX, -1] }
|
32
|
+
/:nth-child\(\d+\)/ { [:tINDEX, text.sub(':nth-child(', '').to_i - 1] }
|
33
|
+
/:nth-last-child\(\d+\)/ { [:tINDEX, -text.sub(':nth-last-child(', '').to_i] }
|
34
|
+
/:has/ { [:tHAS, text[1..-1]] }
|
35
|
+
/#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
|
36
|
+
/>/ { [:tCHILD, text] }
|
37
|
+
/~/ { [:tSUBSEQUENT_SIBLING, text] }
|
38
|
+
/\+/ { [:tNEXT_SIBLING, text] }
|
39
|
+
/#{OPEN_SELECTOR}/ { [:tOPEN_SELECTOR, text] }
|
40
|
+
/#{CLOSE_SELECTOR}/ { [:tCLOSE_SELECTOR, text] }
|
41
|
+
/#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
42
|
+
:KEY /\s+/
|
43
|
+
:KEY /!=/ { @state = :VALUE; [:tNOT_EQUAL, text] }
|
44
|
+
:KEY /=~/ { @state = :VALUE; [:tMATCH, text] }
|
45
|
+
:KEY /!~/ { @state = :VALUE; [:tNOT_MATCH, text] }
|
46
|
+
:KEY />=/ { @state = :VALUE; [:tGREATER_THAN_OR_EQUAL, text] }
|
47
|
+
:KEY /<=/ { @state = :VALUE; [:tLESS_THAN_OR_EQUAL, text] }
|
48
|
+
:KEY />/ { @state = :VALUE; [:tGREATER_THAN, text] }
|
49
|
+
:KEY /</ { @state = :VALUE; [:tLESS_THAN, text] }
|
50
|
+
:KEY /=/ { @state = :VALUE; [:tEQUAL, text] }
|
51
|
+
:KEY /includes/i { @state = :VALUE; [:tINCLUDES, text] }
|
52
|
+
:KEY /not in/i { @state = :VALUE; [:tNOT_IN, text] }
|
53
|
+
:KEY /in/i { @state = :VALUE; [:tIN, text] }
|
54
|
+
:KEY /#{IDENTIFIER}/ { [:tKEY, text] }
|
55
|
+
:VALUE /\s+/
|
56
|
+
:VALUE /#{OPEN_DYNAMIC_ATTRIBUTE}/ { @state = :DYNAMIC_ATTRIBUTE; [:tOPEN_DYNAMIC_ATTRIBUTE, text] }
|
57
|
+
:VALUE /#{OPEN_ARRAY}/ { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
|
58
|
+
:VALUE /#{CLOSE_ATTRIBUTE}/ { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
|
59
|
+
:VALUE /#{NIL}/ { [:tNIL, nil] }
|
60
|
+
:VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
|
61
|
+
:VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
|
62
|
+
:VALUE /#{SYMBOL}/ { [:tSYMBOL, text[1..-1].to_sym] }
|
63
|
+
:VALUE /#{FLOAT}/ { [:tFLOAT, text.to_f] }
|
64
|
+
:VALUE /#{INTEGER}/ { [:tINTEGER, text.to_i] }
|
65
|
+
:VALUE /#{REGEXP}/ { [:tREGEXP, eval(text)] }
|
66
|
+
:VALUE /#{DOUBLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
67
|
+
:VALUE /#{SINGLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
68
|
+
:VALUE /#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
|
69
|
+
:VALUE />/ { [:tCHILD, text] }
|
70
|
+
:VALUE /~/ { [:tSUBSEQUENT_SIBLING, text] }
|
71
|
+
:VALUE /\+/ { [:tNEXT_SIBLING, text] }
|
72
|
+
:VALUE /#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
73
|
+
:VALUE /#{IDENTIFIER_VALUE}/ { [:tIDENTIFIER_VALUE, text] }
|
74
|
+
:DYNAMIC_ATTRIBUTE /#{CLOSE_DYNAMIC_ATTRIBUTE}/ { @state = :VALUE; [:tCLOSE_DYNAMIC_ATTRIBUTE, text] }
|
75
|
+
:DYNAMIC_ATTRIBUTE /#{IDENTIFIER}/ { [:tDYNAMIC_ATTRIBUTE, text] }
|
76
|
+
:ARRAY_VALUE /\s+/
|
77
|
+
:ARRAY_VALUE /,/ { [:tCOMMA, text] }
|
78
|
+
:ARRAY_VALUE /#{CLOSE_ARRAY}/ { @state = :VALUE; [:tCLOSE_ARRAY, text] }
|
79
|
+
:ARRAY_VALUE /#{NIL}/ { [:tNIL, nil] }
|
80
|
+
:ARRAY_VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
|
81
|
+
:ARRAY_VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
|
82
|
+
:ARRAY_VALUE /#{SYMBOL}/ { [:tSYMBOL, text[1..-1].to_sym] }
|
83
|
+
:ARRAY_VALUE /#{FLOAT}/ { [:tFLOAT, text.to_f] }
|
84
|
+
:ARRAY_VALUE /#{INTEGER}/ { [:tINTEGER, text.to_i] }
|
85
|
+
:ARRAY_VALUE /#{REGEXP}/ { [:tREGEXP, eval(text)] }
|
86
|
+
:ARRAY_VALUE /#{DOUBLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
87
|
+
:ARRAY_VALUE /#{SINGLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
88
|
+
:ARRAY_VALUE /#{IDENTIFIER_VALUE}/ { [:tIDENTIFIER_VALUE, text] }
|
89
|
+
|
90
|
+
inner
|
91
|
+
def initialize
|
92
|
+
@nested_count = 0
|
93
|
+
end
|
94
|
+
|
95
|
+
def do_parse; end
|
96
|
+
end
|