synvert-core 1.3.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -4
- data/CHANGELOG.md +16 -0
- data/Gemfile +0 -3
- data/Guardfile +0 -9
- data/README.md +30 -12
- data/Rakefile +1 -15
- data/lib/synvert/core/engine/erb.rb +1 -1
- data/lib/synvert/core/engine.rb +1 -1
- data/lib/synvert/core/node_ext.rb +0 -466
- data/lib/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action.rb +20 -17
- data/lib/synvert/core/rewriter/condition/if_exist_condition.rb +1 -1
- data/lib/synvert/core/rewriter/condition/unless_exist_condition.rb +1 -1
- data/lib/synvert/core/rewriter/instance.rb +89 -135
- data/lib/synvert/core/rewriter/scope/query_scope.rb +2 -2
- data/lib/synvert/core/rewriter/scope/within_scope.rb +4 -4
- data/lib/synvert/core/rewriter.rb +0 -10
- data/lib/synvert/core/version.rb +1 -1
- data/lib/synvert/core.rb +4 -6
- data/spec/synvert/core/engine/erb_spec.rb +3 -3
- data/spec/synvert/core/node_ext_spec.rb +0 -795
- data/spec/synvert/core/rewriter/action/replace_erb_stmt_with_expr_action_spec.rb +21 -1
- data/spec/synvert/core/rewriter/instance_spec.rb +49 -112
- data/spec/synvert/core/rewriter/scope/goto_scope_spec.rb +1 -4
- data/spec/synvert/core/rewriter/scope/query_scope_spec.rb +8 -4
- data/spec/synvert/core/rewriter/scope/within_scope_spec.rb +1 -4
- data/synvert-core-ruby.gemspec +4 -2
- metadata +44 -61
- data/lib/synvert/core/array_ext.rb +0 -48
- data/lib/synvert/core/node_query/compiler/array.rb +0 -34
- data/lib/synvert/core/node_query/compiler/attribute.rb +0 -39
- data/lib/synvert/core/node_query/compiler/attribute_list.rb +0 -24
- data/lib/synvert/core/node_query/compiler/boolean.rb +0 -23
- data/lib/synvert/core/node_query/compiler/comparable.rb +0 -86
- data/lib/synvert/core/node_query/compiler/dynamic_attribute.rb +0 -51
- data/lib/synvert/core/node_query/compiler/expression.rb +0 -58
- data/lib/synvert/core/node_query/compiler/float.rb +0 -23
- data/lib/synvert/core/node_query/compiler/identifier.rb +0 -41
- data/lib/synvert/core/node_query/compiler/integer.rb +0 -23
- data/lib/synvert/core/node_query/compiler/invalid_operator_error.rb +0 -7
- data/lib/synvert/core/node_query/compiler/nil.rb +0 -23
- data/lib/synvert/core/node_query/compiler/parse_error.rb +0 -7
- data/lib/synvert/core/node_query/compiler/regexp.rb +0 -37
- data/lib/synvert/core/node_query/compiler/selector.rb +0 -138
- data/lib/synvert/core/node_query/compiler/simple_selector.rb +0 -29
- data/lib/synvert/core/node_query/compiler/string.rb +0 -23
- data/lib/synvert/core/node_query/compiler/symbol.rb +0 -23
- data/lib/synvert/core/node_query/compiler.rb +0 -25
- data/lib/synvert/core/node_query/lexer.rex +0 -108
- data/lib/synvert/core/node_query/lexer.rex.rb +0 -321
- data/lib/synvert/core/node_query/parser.racc.rb +0 -322
- data/lib/synvert/core/node_query/parser.y +0 -62
- data/lib/synvert/core/node_query.rb +0 -37
- data/lib/synvert/core/rewriter/action/append_action.rb +0 -28
- data/lib/synvert/core/rewriter/action/delete_action.rb +0 -32
- data/lib/synvert/core/rewriter/action/insert_action.rb +0 -34
- data/lib/synvert/core/rewriter/action/insert_after_action.rb +0 -22
- data/lib/synvert/core/rewriter/action/prepend_action.rb +0 -44
- data/lib/synvert/core/rewriter/action/remove_action.rb +0 -53
- data/lib/synvert/core/rewriter/action/replace_action.rb +0 -33
- data/lib/synvert/core/rewriter/action/replace_with_action.rb +0 -36
- data/lib/synvert/core/rewriter/action/wrap_action.rb +0 -37
- data/lib/synvert/core/rewriter/action.rb +0 -102
- data/spec/synvert/core/node_query/lexer_spec.rb +0 -640
- data/spec/synvert/core/node_query/parser_spec.rb +0 -382
- data/spec/synvert/core/rewriter/action/append_action_spec.rb +0 -70
- data/spec/synvert/core/rewriter/action/delete_action_spec.rb +0 -26
- data/spec/synvert/core/rewriter/action/insert_action_spec.rb +0 -70
- data/spec/synvert/core/rewriter/action/insert_after_action_spec.rb +0 -26
- data/spec/synvert/core/rewriter/action/prepend_action_spec.rb +0 -175
- data/spec/synvert/core/rewriter/action/remove_action_spec.rb +0 -26
- data/spec/synvert/core/rewriter/action/replace_action_spec.rb +0 -28
- data/spec/synvert/core/rewriter/action/replace_with_action_spec.rb +0 -59
- data/spec/synvert/core/rewriter/action/wrap_action_spec.rb +0 -31
- data/spec/synvert/core/rewriter/action_spec.rb +0 -14
@@ -1,108 +0,0 @@
|
|
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_GOTO_SCOPE /</
|
11
|
-
CLOSE_GOTO_SCOPE />/
|
12
|
-
OPEN_DYNAMIC_ATTRIBUTE /{{/
|
13
|
-
CLOSE_DYNAMIC_ATTRIBUTE /}}/
|
14
|
-
NODE_TYPE /\.[a-z]+/
|
15
|
-
IDENTIFIER /[\.\w]+/
|
16
|
-
IDENTIFIER_VALUE /[\.\w!&:\?<>=]+/
|
17
|
-
FALSE /false/
|
18
|
-
FLOAT /\d+\.\d+/
|
19
|
-
INTEGER /\d+/
|
20
|
-
NIL /nil/
|
21
|
-
REGEXP_BODY /(?:[^\/]|\\\/)*/
|
22
|
-
REGEXP /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
|
23
|
-
SYMBOL /:[\w!\?<>=]+/
|
24
|
-
TRUE /true/
|
25
|
-
SINGLE_QUOTE_STRING /'.*?'/
|
26
|
-
DOUBLE_QUOTE_STRING /".*?"/
|
27
|
-
|
28
|
-
rules
|
29
|
-
|
30
|
-
# [:state] pattern [actions]
|
31
|
-
/\s+/
|
32
|
-
/:first-child/ { [:tINDEX, 0] }
|
33
|
-
/:last-child/ { [:tINDEX, -1] }
|
34
|
-
/:nth-child\(\d+\)/ { [:tINDEX, text.sub(':nth-child(', '').to_i - 1] }
|
35
|
-
/:nth-last-child\(\d+\)/ { [:tINDEX, -text.sub(':nth-last-child(', '').to_i] }
|
36
|
-
/:has/ { [:tPSEUDO_CLASS, text[1..-1]] }
|
37
|
-
/:not_has/ { [:tPSEUDO_CLASS, text[1..-1]] }
|
38
|
-
/#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
|
39
|
-
/>/ { [:tRELATIONSHIP, text] }
|
40
|
-
/~/ { [:tRELATIONSHIP, text] }
|
41
|
-
/\+/ { [:tRELATIONSHIP, text] }
|
42
|
-
/#{OPEN_SELECTOR}/ { [:tOPEN_SELECTOR, text] }
|
43
|
-
/#{CLOSE_SELECTOR}/ { [:tCLOSE_SELECTOR, text] }
|
44
|
-
/#{OPEN_GOTO_SCOPE}/ { @state = :GOTO_SCOPE; [:tOPEN_GOTO_SCOPE, text] }
|
45
|
-
/#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
46
|
-
:GOTO_SCOPE /\s+/
|
47
|
-
:GOTO_SCOPE /#{IDENTIFIER}/ { [:tIDENTIFIER, text] }
|
48
|
-
:GOTO_SCOPE /#{CLOSE_GOTO_SCOPE}/ { @state = nil; [:tCLOSE_GOTO_SCOPE, text] }
|
49
|
-
:KEY /\s+/
|
50
|
-
:KEY /\^=/ { @state = :VALUE; [:tOPERATOR, '^='] }
|
51
|
-
:KEY /\$=/ { @state = :VALUE; [:tOPERATOR, '$='] }
|
52
|
-
:KEY /\*=/ { @state = :VALUE; [:tOPERATOR, '*='] }
|
53
|
-
:KEY /!=/ { @state = :VALUE; [:tOPERATOR, '!='] }
|
54
|
-
:KEY /=~/ { @state = :VALUE; [:tOPERATOR, '=~'] }
|
55
|
-
:KEY /!~/ { @state = :VALUE; [:tOPERATOR, '!~'] }
|
56
|
-
:KEY />=/ { @state = :VALUE; [:tOPERATOR, '>='] }
|
57
|
-
:KEY /<=/ { @state = :VALUE; [:tOPERATOR, '<='] }
|
58
|
-
:KEY />/ { @state = :VALUE; [:tOPERATOR, '>'] }
|
59
|
-
:KEY /</ { @state = :VALUE; [:tOPERATOR, '<'] }
|
60
|
-
:KEY /=/ { @state = :VALUE; [:tOPERATOR, '=='] }
|
61
|
-
:KEY /includes/i { @state = :VALUE; [:tOPERATOR, 'includes'] }
|
62
|
-
:KEY /not in/i { @state = :VALUE; [:tOPERATOR, 'not_in'] }
|
63
|
-
:KEY /in/i { @state = :VALUE; [:tOPERATOR, 'in'] }
|
64
|
-
:KEY /#{IDENTIFIER}/ { [:tKEY, text] }
|
65
|
-
:VALUE /\s+/
|
66
|
-
:VALUE /\[\]=/ { [:tIDENTIFIER_VALUE, text] }
|
67
|
-
:VALUE /\[\]/ { [:tIDENTIFIER_VALUE, text] }
|
68
|
-
:VALUE /:\[\]=/ { [:tSYMBOL, text[1..-1].to_sym] }
|
69
|
-
:VALUE /:\[\]/ { [:tSYMBOL, text[1..-1].to_sym] }
|
70
|
-
:VALUE /#{OPEN_DYNAMIC_ATTRIBUTE}/ { @state = :DYNAMIC_ATTRIBUTE; [:tOPEN_DYNAMIC_ATTRIBUTE, text] }
|
71
|
-
:VALUE /#{OPEN_ARRAY}/ { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
|
72
|
-
:VALUE /#{CLOSE_ATTRIBUTE}/ { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
|
73
|
-
:VALUE /#{NIL}\?/ { [:tIDENTIFIER_VALUE, text] }
|
74
|
-
:VALUE /#{NIL}/ { [:tNIL, nil] }
|
75
|
-
:VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
|
76
|
-
:VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
|
77
|
-
:VALUE /#{SYMBOL}/ { [:tSYMBOL, text[1..-1].to_sym] }
|
78
|
-
:VALUE /#{FLOAT}/ { [:tFLOAT, text.to_f] }
|
79
|
-
:VALUE /#{INTEGER}/ { [:tINTEGER, text.to_i] }
|
80
|
-
:VALUE /#{REGEXP}/ { [:tREGEXP, eval(text)] }
|
81
|
-
:VALUE /#{DOUBLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
82
|
-
:VALUE /#{SINGLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
83
|
-
:VALUE /#{NODE_TYPE}/ { [:tNODE_TYPE, text[1..]] }
|
84
|
-
:VALUE /#{OPEN_ATTRIBUTE}/ { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
85
|
-
:VALUE /#{IDENTIFIER_VALUE}/ { [:tIDENTIFIER_VALUE, text] }
|
86
|
-
:DYNAMIC_ATTRIBUTE /#{CLOSE_DYNAMIC_ATTRIBUTE}/ { @state = :VALUE; [:tCLOSE_DYNAMIC_ATTRIBUTE, text] }
|
87
|
-
:DYNAMIC_ATTRIBUTE /#{IDENTIFIER}/ { [:tDYNAMIC_ATTRIBUTE, text] }
|
88
|
-
:ARRAY_VALUE /\s+/
|
89
|
-
:ARRAY_VALUE /#{CLOSE_ARRAY}/ { @state = :VALUE; [:tCLOSE_ARRAY, text] }
|
90
|
-
:ARRAY_VALUE /#{NIL}\?/ { [:tIDENTIFIER_VALUE, text] }
|
91
|
-
:ARRAY_VALUE /#{NIL}/ { [:tNIL, nil] }
|
92
|
-
:ARRAY_VALUE /#{TRUE}/ { [:tBOOLEAN, true] }
|
93
|
-
:ARRAY_VALUE /#{FALSE}/ { [:tBOOLEAN, false] }
|
94
|
-
:ARRAY_VALUE /#{SYMBOL}/ { [:tSYMBOL, text[1..-1].to_sym] }
|
95
|
-
:ARRAY_VALUE /#{FLOAT}/ { [:tFLOAT, text.to_f] }
|
96
|
-
:ARRAY_VALUE /#{INTEGER}/ { [:tINTEGER, text.to_i] }
|
97
|
-
:ARRAY_VALUE /#{REGEXP}/ { [:tREGEXP, eval(text)] }
|
98
|
-
:ARRAY_VALUE /#{DOUBLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
99
|
-
:ARRAY_VALUE /#{SINGLE_QUOTE_STRING}/ { [:tSTRING, text[1...-1]] }
|
100
|
-
:ARRAY_VALUE /#{IDENTIFIER_VALUE}/ { [:tIDENTIFIER_VALUE, text] }
|
101
|
-
|
102
|
-
inner
|
103
|
-
def initialize
|
104
|
-
@nested_count = 0
|
105
|
-
end
|
106
|
-
|
107
|
-
def do_parse; end
|
108
|
-
end
|
@@ -1,321 +0,0 @@
|
|
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/synvert/core/node_query/lexer.rex
|
7
|
-
#++
|
8
|
-
|
9
|
-
|
10
|
-
##
|
11
|
-
# The generated lexer Synvert::Core::NodeQuery::Lexer
|
12
|
-
|
13
|
-
class Synvert::Core::NodeQuery::Lexer
|
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_GOTO_SCOPE = /</
|
24
|
-
CLOSE_GOTO_SCOPE = />/
|
25
|
-
OPEN_DYNAMIC_ATTRIBUTE = /{{/
|
26
|
-
CLOSE_DYNAMIC_ATTRIBUTE = /}}/
|
27
|
-
NODE_TYPE = /\.[a-z]+/
|
28
|
-
IDENTIFIER = /[\.\w]+/
|
29
|
-
IDENTIFIER_VALUE = /[\.\w!&:\?<>=]+/
|
30
|
-
FALSE = /false/
|
31
|
-
FLOAT = /\d+\.\d+/
|
32
|
-
INTEGER = /\d+/
|
33
|
-
NIL = /nil/
|
34
|
-
REGEXP_BODY = /(?:[^\/]|\\\/)*/
|
35
|
-
REGEXP = /\/(#{REGEXP_BODY})(?<!\\)\/([imxo]*)/
|
36
|
-
SYMBOL = /:[\w!\?<>=]+/
|
37
|
-
TRUE = /true/
|
38
|
-
SINGLE_QUOTE_STRING = /'.*?'/
|
39
|
-
DOUBLE_QUOTE_STRING = /".*?"/
|
40
|
-
# :startdoc:
|
41
|
-
# :stopdoc:
|
42
|
-
class LexerError < StandardError ; end
|
43
|
-
class ScanError < LexerError ; end
|
44
|
-
# :startdoc:
|
45
|
-
|
46
|
-
##
|
47
|
-
# The file name / path
|
48
|
-
|
49
|
-
attr_accessor :filename
|
50
|
-
|
51
|
-
##
|
52
|
-
# The StringScanner for this lexer.
|
53
|
-
|
54
|
-
attr_accessor :ss
|
55
|
-
|
56
|
-
##
|
57
|
-
# The current lexical state.
|
58
|
-
|
59
|
-
attr_accessor :state
|
60
|
-
|
61
|
-
alias :match :ss
|
62
|
-
|
63
|
-
##
|
64
|
-
# The match groups for the current scan.
|
65
|
-
|
66
|
-
def matches
|
67
|
-
m = (1..9).map { |i| ss[i] }
|
68
|
-
m.pop until m[-1] or m.empty?
|
69
|
-
m
|
70
|
-
end
|
71
|
-
|
72
|
-
##
|
73
|
-
# Yields on the current action.
|
74
|
-
|
75
|
-
def action
|
76
|
-
yield
|
77
|
-
end
|
78
|
-
|
79
|
-
|
80
|
-
##
|
81
|
-
# The current scanner class. Must be overridden in subclasses.
|
82
|
-
|
83
|
-
def scanner_class
|
84
|
-
StringScanner
|
85
|
-
end unless instance_methods(false).map(&:to_s).include?("scanner_class")
|
86
|
-
|
87
|
-
##
|
88
|
-
# Parse the given string.
|
89
|
-
|
90
|
-
def parse str
|
91
|
-
self.ss = scanner_class.new str
|
92
|
-
self.state ||= nil
|
93
|
-
|
94
|
-
do_parse
|
95
|
-
end
|
96
|
-
|
97
|
-
##
|
98
|
-
# Read in and parse the file at +path+.
|
99
|
-
|
100
|
-
def parse_file path
|
101
|
-
self.filename = path
|
102
|
-
open path do |f|
|
103
|
-
parse f.read
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
##
|
108
|
-
# The current location in the parse.
|
109
|
-
|
110
|
-
def location
|
111
|
-
[
|
112
|
-
(filename || "<input>"),
|
113
|
-
].compact.join(":")
|
114
|
-
end
|
115
|
-
|
116
|
-
##
|
117
|
-
# Lex the next token.
|
118
|
-
|
119
|
-
def next_token
|
120
|
-
|
121
|
-
token = nil
|
122
|
-
|
123
|
-
until ss.eos? or token do
|
124
|
-
token =
|
125
|
-
case state
|
126
|
-
when nil then
|
127
|
-
case
|
128
|
-
when ss.skip(/\s+/) then
|
129
|
-
# do nothing
|
130
|
-
when ss.skip(/:first-child/) then
|
131
|
-
action { [:tINDEX, 0] }
|
132
|
-
when ss.skip(/:last-child/) then
|
133
|
-
action { [:tINDEX, -1] }
|
134
|
-
when text = ss.scan(/:nth-child\(\d+\)/) then
|
135
|
-
action { [:tINDEX, text.sub(':nth-child(', '').to_i - 1] }
|
136
|
-
when text = ss.scan(/:nth-last-child\(\d+\)/) then
|
137
|
-
action { [:tINDEX, -text.sub(':nth-last-child(', '').to_i] }
|
138
|
-
when text = ss.scan(/:has/) then
|
139
|
-
action { [:tPSEUDO_CLASS, text[1..-1]] }
|
140
|
-
when text = ss.scan(/:not_has/) then
|
141
|
-
action { [:tPSEUDO_CLASS, text[1..-1]] }
|
142
|
-
when text = ss.scan(/#{NODE_TYPE}/) then
|
143
|
-
action { [:tNODE_TYPE, text[1..]] }
|
144
|
-
when text = ss.scan(/>/) then
|
145
|
-
action { [:tRELATIONSHIP, text] }
|
146
|
-
when text = ss.scan(/~/) then
|
147
|
-
action { [:tRELATIONSHIP, text] }
|
148
|
-
when text = ss.scan(/\+/) then
|
149
|
-
action { [:tRELATIONSHIP, text] }
|
150
|
-
when text = ss.scan(/#{OPEN_SELECTOR}/) then
|
151
|
-
action { [:tOPEN_SELECTOR, text] }
|
152
|
-
when text = ss.scan(/#{CLOSE_SELECTOR}/) then
|
153
|
-
action { [:tCLOSE_SELECTOR, text] }
|
154
|
-
when text = ss.scan(/#{OPEN_GOTO_SCOPE}/) then
|
155
|
-
action { @state = :GOTO_SCOPE; [:tOPEN_GOTO_SCOPE, text] }
|
156
|
-
when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
|
157
|
-
action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
158
|
-
else
|
159
|
-
text = ss.string[ss.pos .. -1]
|
160
|
-
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
161
|
-
end
|
162
|
-
when :GOTO_SCOPE then
|
163
|
-
case
|
164
|
-
when ss.skip(/\s+/) then
|
165
|
-
# do nothing
|
166
|
-
when text = ss.scan(/#{IDENTIFIER}/) then
|
167
|
-
action { [:tIDENTIFIER, text] }
|
168
|
-
when text = ss.scan(/#{CLOSE_GOTO_SCOPE}/) then
|
169
|
-
action { @state = nil; [:tCLOSE_GOTO_SCOPE, text] }
|
170
|
-
else
|
171
|
-
text = ss.string[ss.pos .. -1]
|
172
|
-
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
173
|
-
end
|
174
|
-
when :KEY then
|
175
|
-
case
|
176
|
-
when ss.skip(/\s+/) then
|
177
|
-
# do nothing
|
178
|
-
when ss.skip(/\^=/) then
|
179
|
-
action { @state = :VALUE; [:tOPERATOR, '^='] }
|
180
|
-
when ss.skip(/\$=/) then
|
181
|
-
action { @state = :VALUE; [:tOPERATOR, '$='] }
|
182
|
-
when ss.skip(/\*=/) then
|
183
|
-
action { @state = :VALUE; [:tOPERATOR, '*='] }
|
184
|
-
when ss.skip(/!=/) then
|
185
|
-
action { @state = :VALUE; [:tOPERATOR, '!='] }
|
186
|
-
when ss.skip(/=~/) then
|
187
|
-
action { @state = :VALUE; [:tOPERATOR, '=~'] }
|
188
|
-
when ss.skip(/!~/) then
|
189
|
-
action { @state = :VALUE; [:tOPERATOR, '!~'] }
|
190
|
-
when ss.skip(/>=/) then
|
191
|
-
action { @state = :VALUE; [:tOPERATOR, '>='] }
|
192
|
-
when ss.skip(/<=/) then
|
193
|
-
action { @state = :VALUE; [:tOPERATOR, '<='] }
|
194
|
-
when ss.skip(/>/) then
|
195
|
-
action { @state = :VALUE; [:tOPERATOR, '>'] }
|
196
|
-
when ss.skip(/</) then
|
197
|
-
action { @state = :VALUE; [:tOPERATOR, '<'] }
|
198
|
-
when ss.skip(/=/) then
|
199
|
-
action { @state = :VALUE; [:tOPERATOR, '=='] }
|
200
|
-
when ss.skip(/includes/i) then
|
201
|
-
action { @state = :VALUE; [:tOPERATOR, 'includes'] }
|
202
|
-
when ss.skip(/not in/i) then
|
203
|
-
action { @state = :VALUE; [:tOPERATOR, 'not_in'] }
|
204
|
-
when ss.skip(/in/i) then
|
205
|
-
action { @state = :VALUE; [:tOPERATOR, 'in'] }
|
206
|
-
when text = ss.scan(/#{IDENTIFIER}/) then
|
207
|
-
action { [:tKEY, text] }
|
208
|
-
else
|
209
|
-
text = ss.string[ss.pos .. -1]
|
210
|
-
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
211
|
-
end
|
212
|
-
when :VALUE then
|
213
|
-
case
|
214
|
-
when ss.skip(/\s+/) then
|
215
|
-
# do nothing
|
216
|
-
when text = ss.scan(/\[\]=/) then
|
217
|
-
action { [:tIDENTIFIER_VALUE, text] }
|
218
|
-
when text = ss.scan(/\[\]/) then
|
219
|
-
action { [:tIDENTIFIER_VALUE, text] }
|
220
|
-
when text = ss.scan(/:\[\]=/) then
|
221
|
-
action { [:tSYMBOL, text[1..-1].to_sym] }
|
222
|
-
when text = ss.scan(/:\[\]/) then
|
223
|
-
action { [:tSYMBOL, text[1..-1].to_sym] }
|
224
|
-
when text = ss.scan(/#{OPEN_DYNAMIC_ATTRIBUTE}/) then
|
225
|
-
action { @state = :DYNAMIC_ATTRIBUTE; [:tOPEN_DYNAMIC_ATTRIBUTE, text] }
|
226
|
-
when text = ss.scan(/#{OPEN_ARRAY}/) then
|
227
|
-
action { @state = :ARRAY_VALUE; [:tOPEN_ARRAY, text] }
|
228
|
-
when text = ss.scan(/#{CLOSE_ATTRIBUTE}/) then
|
229
|
-
action { @nested_count -= 1; @state = @nested_count == 0 ? nil : :VALUE; [:tCLOSE_ATTRIBUTE, text] }
|
230
|
-
when text = ss.scan(/#{NIL}\?/) then
|
231
|
-
action { [:tIDENTIFIER_VALUE, text] }
|
232
|
-
when ss.skip(/#{NIL}/) then
|
233
|
-
action { [:tNIL, nil] }
|
234
|
-
when ss.skip(/#{TRUE}/) then
|
235
|
-
action { [:tBOOLEAN, true] }
|
236
|
-
when ss.skip(/#{FALSE}/) then
|
237
|
-
action { [:tBOOLEAN, false] }
|
238
|
-
when text = ss.scan(/#{SYMBOL}/) then
|
239
|
-
action { [:tSYMBOL, text[1..-1].to_sym] }
|
240
|
-
when text = ss.scan(/#{FLOAT}/) then
|
241
|
-
action { [:tFLOAT, text.to_f] }
|
242
|
-
when text = ss.scan(/#{INTEGER}/) then
|
243
|
-
action { [:tINTEGER, text.to_i] }
|
244
|
-
when text = ss.scan(/#{REGEXP}/) then
|
245
|
-
action { [:tREGEXP, eval(text)] }
|
246
|
-
when text = ss.scan(/#{DOUBLE_QUOTE_STRING}/) then
|
247
|
-
action { [:tSTRING, text[1...-1]] }
|
248
|
-
when text = ss.scan(/#{SINGLE_QUOTE_STRING}/) then
|
249
|
-
action { [:tSTRING, text[1...-1]] }
|
250
|
-
when text = ss.scan(/#{NODE_TYPE}/) then
|
251
|
-
action { [:tNODE_TYPE, text[1..]] }
|
252
|
-
when text = ss.scan(/#{OPEN_ATTRIBUTE}/) then
|
253
|
-
action { @nested_count += 1; @state = :KEY; [:tOPEN_ATTRIBUTE, text] }
|
254
|
-
when text = ss.scan(/#{IDENTIFIER_VALUE}/) then
|
255
|
-
action { [:tIDENTIFIER_VALUE, text] }
|
256
|
-
else
|
257
|
-
text = ss.string[ss.pos .. -1]
|
258
|
-
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
259
|
-
end
|
260
|
-
when :DYNAMIC_ATTRIBUTE then
|
261
|
-
case
|
262
|
-
when text = ss.scan(/#{CLOSE_DYNAMIC_ATTRIBUTE}/) then
|
263
|
-
action { @state = :VALUE; [:tCLOSE_DYNAMIC_ATTRIBUTE, text] }
|
264
|
-
when text = ss.scan(/#{IDENTIFIER}/) then
|
265
|
-
action { [:tDYNAMIC_ATTRIBUTE, text] }
|
266
|
-
else
|
267
|
-
text = ss.string[ss.pos .. -1]
|
268
|
-
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
269
|
-
end
|
270
|
-
when :ARRAY_VALUE then
|
271
|
-
case
|
272
|
-
when ss.skip(/\s+/) then
|
273
|
-
# do nothing
|
274
|
-
when text = ss.scan(/#{CLOSE_ARRAY}/) then
|
275
|
-
action { @state = :VALUE; [:tCLOSE_ARRAY, text] }
|
276
|
-
when text = ss.scan(/#{NIL}\?/) then
|
277
|
-
action { [:tIDENTIFIER_VALUE, text] }
|
278
|
-
when ss.skip(/#{NIL}/) then
|
279
|
-
action { [:tNIL, nil] }
|
280
|
-
when ss.skip(/#{TRUE}/) then
|
281
|
-
action { [:tBOOLEAN, true] }
|
282
|
-
when ss.skip(/#{FALSE}/) then
|
283
|
-
action { [:tBOOLEAN, false] }
|
284
|
-
when text = ss.scan(/#{SYMBOL}/) then
|
285
|
-
action { [:tSYMBOL, text[1..-1].to_sym] }
|
286
|
-
when text = ss.scan(/#{FLOAT}/) then
|
287
|
-
action { [:tFLOAT, text.to_f] }
|
288
|
-
when text = ss.scan(/#{INTEGER}/) then
|
289
|
-
action { [:tINTEGER, text.to_i] }
|
290
|
-
when text = ss.scan(/#{REGEXP}/) then
|
291
|
-
action { [:tREGEXP, eval(text)] }
|
292
|
-
when text = ss.scan(/#{DOUBLE_QUOTE_STRING}/) then
|
293
|
-
action { [:tSTRING, text[1...-1]] }
|
294
|
-
when text = ss.scan(/#{SINGLE_QUOTE_STRING}/) then
|
295
|
-
action { [:tSTRING, text[1...-1]] }
|
296
|
-
when text = ss.scan(/#{IDENTIFIER_VALUE}/) then
|
297
|
-
action { [:tIDENTIFIER_VALUE, text] }
|
298
|
-
else
|
299
|
-
text = ss.string[ss.pos .. -1]
|
300
|
-
raise ScanError, "can not match (#{state.inspect}) at #{location}: '#{text}'"
|
301
|
-
end
|
302
|
-
else
|
303
|
-
raise ScanError, "undefined state at #{location}: '#{state}'"
|
304
|
-
end # token = case state
|
305
|
-
|
306
|
-
next unless token # allow functions to trigger redo w/ nil
|
307
|
-
end # while
|
308
|
-
|
309
|
-
raise LexerError, "bad lexical result at #{location}: #{token.inspect}" unless
|
310
|
-
token.nil? || (Array === token && token.size >= 2)
|
311
|
-
|
312
|
-
# auto-switch state
|
313
|
-
self.state = token.last if token && token.first == :state
|
314
|
-
|
315
|
-
token
|
316
|
-
end # def next_token
|
317
|
-
def initialize
|
318
|
-
@nested_count = 0
|
319
|
-
end
|
320
|
-
def do_parse; end
|
321
|
-
end # class
|