3
3
module CodeRay
4
4
module Scanners
5
5
module SimpleScannerDSL
6
+ NoStatesError = Class . new StandardError
7
+
6
8
Pattern = Struct . new :pattern
7
9
Groups = Struct . new :token_kinds
8
10
Kind = Struct . new :token_kind
@@ -26,7 +28,7 @@ def initialize(*)
26
28
def eval
27
29
@first = true
28
30
29
- @code = ""
31
+ @code = ''
30
32
instance_eval ( &block )
31
33
end
32
34
@@ -111,115 +113,119 @@ def on *pattern_and_actions
111
113
end
112
114
end
113
115
114
- @code << "#{ 'els' unless @first } if #{ condition_expressions . join ( ' && ' ) } \n "
116
+ condition_code = "#{ 'els' unless @first } if #{ condition_expressions . join ( ' && ' ) } \n "
117
+ action_code = ''
115
118
116
119
for action in actions
117
120
case action
118
121
when String
119
122
raise
120
- @code << "p 'evaluate #{ action . inspect } '\n " if $DEBUG
121
- @code << "#{ action } \n "
123
+ action_code << "p 'evaluate #{ action . inspect } '\n " if $DEBUG
124
+ action_code << "#{ action } \n "
122
125
123
126
when Symbol
124
- @code << "p 'text_token %p %p' % [match, #{ action . inspect } ]\n " if $DEBUG
125
- @code << "encoder.text_token match, #{ action . inspect } \n "
127
+ action_code << "p 'text_token %p %p' % [match, #{ action . inspect } ]\n " if $DEBUG
128
+ action_code << "encoder.text_token match, #{ action . inspect } \n "
126
129
when Kind
127
130
case action . token_kind
128
131
when Proc
129
- @code << "encoder.text_token match, kind = #{ dsl . add_callback ( action . token_kind ) } \n "
132
+ action_code << "encoder.text_token match, kind = #{ dsl . add_callback ( action . token_kind ) } \n "
130
133
else
131
134
raise "I don't know how to evaluate this kind: %p" % [ action . token_kind ]
132
135
end
133
136
when Groups
134
- @code << "p 'text_tokens %p in groups %p' % [match, #{ action . token_kinds . inspect } ]\n " if $DEBUG
137
+ action_code << "p 'text_tokens %p in groups %p' % [match, #{ action . token_kinds . inspect } ]\n " if $DEBUG
135
138
action . token_kinds . each_with_index do |kind , i |
136
- @code << "encoder.text_token self[#{ i + 1 } ], #{ kind . inspect } if self[#{ i + 1 } ]\n "
139
+ action_code << "encoder.text_token self[#{ i + 1 } ], #{ kind . inspect } if self[#{ i + 1 } ]\n "
137
140
end
138
141
139
142
when Push , PushState
140
143
case action . state
141
144
when String
142
145
raise
143
- @code << "p 'push %p' % [#{ action . state } ]\n " if $DEBUG
144
- @code << "state = #{ action . state } \n "
145
- @code << "states << state\n "
146
+ action_code << "p 'push %p' % [#{ action . state } ]\n " if $DEBUG
147
+ action_code << "state = #{ action . state } \n "
148
+ action_code << "states << state\n "
146
149
when Symbol
147
- @code << "p 'push %p' % [#{ action . state . inspect } ]\n " if $DEBUG
148
- @code << "state = #{ action . state . inspect } \n "
149
- @code << "states << state\n "
150
+ action_code << "p 'push %p' % [#{ action . state . inspect } ]\n " if $DEBUG
151
+ action_code << "state = #{ action . state . inspect } \n "
152
+ action_code << "states << state\n "
150
153
when Proc
151
- @code << "if new_state = #{ dsl . add_callback ( action . state ) } \n "
152
- @code << " state = new_state\n "
153
- @code << " states << new_state\n "
154
- @code << "end\n "
154
+ action_code << "if new_state = #{ dsl . add_callback ( action . state ) } \n "
155
+ action_code << " state = new_state\n "
156
+ action_code << " states << new_state\n "
157
+ action_code << "end\n "
155
158
else
156
159
raise "I don't know how to evaluate this push state: %p" % [ action . state ]
157
160
end
158
161
if action . is_a? Push
159
162
if action . state == action . group
160
- @code << "encoder.begin_group state\n "
163
+ action_code << "encoder.begin_group state\n "
161
164
else
162
165
case action . state
163
166
when Symbol
164
- @code << "p 'begin group %p' % [#{ action . group . inspect } ]\n " if $DEBUG
165
- @code << "encoder.begin_group #{ action . group . inspect } \n "
167
+ action_code << "p 'begin group %p' % [#{ action . group . inspect } ]\n " if $DEBUG
168
+ action_code << "encoder.begin_group #{ action . group . inspect } \n "
166
169
when Proc
167
- @code << "encoder.begin_group #{ dsl . add_callback ( action . group ) } \n "
170
+ action_code << "encoder.begin_group #{ dsl . add_callback ( action . group ) } \n "
168
171
else
169
172
raise "I don't know how to evaluate this push state: %p" % [ action . state ]
170
173
end
171
174
end
172
175
end
173
176
when Pop , PopState
174
- @code << "p 'pop %p' % [states.last]\n " if $DEBUG
177
+ action_code << "p 'pop %p' % [states.last]\n " if $DEBUG
175
178
if action . is_a? Pop
176
179
if action . group
177
180
case action . group
178
181
when Symbol
179
- @code << "encoder.end_group #{ action . group . inspect } \n "
182
+ action_code << "encoder.end_group #{ action . group . inspect } \n "
180
183
else
181
184
raise "I don't know how to evaluate this pop group: %p" % [ action . group ]
182
185
end
183
- @code << "states.pop\n "
186
+ action_code << "states.pop\n "
184
187
else
185
- @code << "encoder.end_group states.pop\n "
188
+ action_code << "encoder.end_group states.pop\n "
186
189
end
187
190
else
188
- @code << "states.pop\n "
191
+ action_code << "states.pop\n "
189
192
end
190
- @code << "state = states.last\n "
193
+ action_code << "state = states.last\n "
191
194
192
195
when ValueSetter
193
196
case action . value
194
197
when Proc
195
- @code << "#{ action . targets . join ( ' = ' ) } = #{ dsl . add_callback ( action . value ) } \n "
198
+ action_code << "#{ action . targets . join ( ' = ' ) } = #{ dsl . add_callback ( action . value ) } \n "
196
199
when Symbol
197
- @code << "#{ action . targets . join ( ' = ' ) } = #{ action . value } \n "
200
+ action_code << "#{ action . targets . join ( ' = ' ) } = #{ action . value } \n "
198
201
else
199
- @code << "#{ action . targets . join ( ' = ' ) } = #{ action . value . inspect } \n "
202
+ action_code << "#{ action . targets . join ( ' = ' ) } = #{ action . value . inspect } \n "
200
203
end
201
204
202
205
when Increment
203
206
case action . value
204
207
when Proc
205
- @code << "#{ action . targets . join ( ' = ' ) } #{ action . operation } = #{ dsl . add_callback ( action . value ) } \n "
208
+ action_code << "#{ action . targets . join ( ' = ' ) } #{ action . operation } = #{ dsl . add_callback ( action . value ) } \n "
206
209
when Symbol
207
- @code << "#{ action . targets . join ( ' = ' ) } #{ action . operation } = #{ action . value } \n "
210
+ action_code << "#{ action . targets . join ( ' = ' ) } #{ action . operation } = #{ action . value } \n "
208
211
else
209
- @code << "#{ action . targets . join ( ' = ' ) } #{ action . operation } = #{ action . value . inspect } \n "
212
+ action_code << "#{ action . targets . join ( ' = ' ) } #{ action . operation } = #{ action . value . inspect } \n "
210
213
end
211
214
212
215
when Proc
213
- @code << "#{ dsl . add_callback ( action ) } \n "
216
+ action_code << "#{ dsl . add_callback ( action ) } \n "
214
217
215
218
when Continue
216
- @code << "next\n "
219
+ action_code << "next\n "
217
220
218
221
else
219
222
raise "I don't know how to evaluate this action: %p" % [ action ]
220
223
end
221
224
end
222
225
226
+ @code << condition_code
227
+ @code << action_code . gsub ( /^/ , ' ' )
228
+
223
229
@first = false
224
230
end
225
231
@@ -347,8 +353,7 @@ def scan_tokens_code
347
353
<<-"RUBY"
348
354
state = options[:state] || @state
349
355
states = [state]
350
- #{ restore_local_variables_code . chomp }
351
-
356
+ #{ restore_local_variables_code }
352
357
until eos?
353
358
case state
354
359
#{ states_code . chomp . gsub ( /^/ , ' ' ) }
@@ -359,7 +364,7 @@ def scan_tokens_code
359
364
360
365
@state = state if options[:keep_state]
361
366
362
- #{ close_groups_code . chomp }
367
+ close_groups(encoder, states)
363
368
364
369
encoder
365
370
RUBY
@@ -370,11 +375,11 @@ def restore_local_variables_code
370
375
end
371
376
372
377
def states_code
373
- @states . map ( &:code ) [ 0 , 1 ] . join
374
- end
378
+ unless defined? @states
379
+ raise NoStatesError , 'no states defined for %p' % [ self . class ]
380
+ end
375
381
376
- def close_groups_code
377
- 'close_groups(encoder, states)'
382
+ @states . map ( &:code ) . join
378
383
end
379
384
end
380
385
end
0 commit comments