DEFINITIONS
This source file includes following functions.
1 #
2 # parser.rb
3 #
4 # Copyright (c) 1999-2002 Minero Aoki <aamine@loveruby.net>
5 #
6 # This program is free software.
7 # You can distribute/modify this program under the same terms of ruby.
8 #
9 # As a special exception, when this code is copied by Racc
10 # into a Racc output file, you may use that output file
11 # without restriction.
12 #
13 # $Id: parser.rb,v 1.1 2002/03/22 07:20:31 aamine Exp $
14 #
15
16 unless defined? NotImplementedError then
17 NotImplementedError = NotImplementError
18 end
19
20
21 module Racc
22 class ParseError < StandardError; end
23 end
24 unless defined? ::ParseError then
25 ParseError = Racc::ParseError
26 end
27
28
29 module Racc
30
31 unless defined? Racc_No_Extentions then
32 Racc_No_Extentions = false
33 end
34
35 class Parser
36
37 Racc_Runtime_Version = '1.4.2'
38 Racc_Runtime_Revision = '$Revision: 1.1 $'.split(/\s+/)[1]
39
40 Racc_Runtime_Core_Version_R = '1.4.2'
41 Racc_Runtime_Core_Revision_R = '$Revision: 1.1 $'.split(/\s+/)[1]
42 begin
43 require 'racc/cparse'
44 # Racc_Runtime_Core_Version_C = (defined in extention)
45 Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split(/\s+/)[2]
46 unless new.respond_to? :_racc_do_parse_c, true then
47 raise LoadError, 'old cparse.so'
48 end
49 if Racc_No_Extentions then
50 raise LoadError, 'selecting ruby version of racc runtime core'
51 end
52
53 Racc_Main_Parsing_Routine = :_racc_do_parse_c
54 Racc_YY_Parse_Method = :_racc_yyparse_c
55 Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C
56 Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C
57 Racc_Runtime_Type = 'c'
58 rescue LoadError
59 Racc_Main_Parsing_Routine = :_racc_do_parse_rb
60 Racc_YY_Parse_Method = :_racc_yyparse_rb
61 Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
62 Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
63 Racc_Runtime_Type = 'ruby'
64 end
65
66 def self.racc_runtime_type
67 Racc_Runtime_Type
68 end
69
70
71 private
72
73
74 def _racc_setup
75 t = self.type
76
77 unless t::Racc_debug_parser then
78 @yydebug = false
79 end
80 @yydebug = false unless defined? @yydebug
81
82 if @yydebug then
83 @racc_debug_out = $stderr unless defined? @racc_debug_out
84 @racc_debug_out ||= $stderr
85 end
86
87 arg = t::Racc_arg
88 if arg.size < 14 then
89 arg[13] = true
90 end
91 arg
92 end
93
94 def _racc_init_sysvars
95 @racc_state = [ 0 ]
96 @racc_tstack = []
97 @racc_vstack = []
98
99 @racc_t = nil
100 @racc_val = nil
101
102 @racc_read_next = true
103
104 @racc_user_yyerror = false
105 @racc_error_status = 0
106 end
107
108
109 ###
110 ### do_parse
111 ###
112
113 def do_parse
114 __send__ Racc_Main_Parsing_Routine, _racc_setup(), false
115 end
116
117 def next_token
118 raise NotImplementedError, "#{self.type}\#next_token is not defined"
119 end
120
121 def _racc_do_parse_rb( arg, in_debug )
122 action_table, action_check, action_default, action_pointer,
123 goto_table, goto_check, goto_default, goto_pointer,
124 nt_base, reduce_table, token_table, shift_n,
125 reduce_n, use_result, * = arg
126
127 _racc_init_sysvars
128 tok = act = i = nil
129 nerr = 0
130
131
132 catch( :racc_end_parse ) {
133 while true do
134
135 if i = action_pointer[ @racc_state[-1] ] then
136 if @racc_read_next then
137 if @racc_t != 0 then # not EOF
138 tok, @racc_val = next_token()
139 unless tok then # EOF
140 @racc_t = 0
141 else
142 @racc_t = (token_table[tok] or 1) # error token
143 end
144 racc_read_token( @racc_t, tok, @racc_val ) if @yydebug
145
146 @racc_read_next = false
147 end
148 end
149 i += @racc_t
150 if i >= 0 and act = action_table[i] and
151 action_check[i] == @racc_state[-1] then
152 ;
153 else
154 act = action_default[ @racc_state[-1] ]
155 end
156 else
157 act = action_default[ @racc_state[-1] ]
158 end
159
160 while act = _racc_evalact( act, arg ) do end
161
162 end
163 }
164 end
165
166
167 ###
168 ### yyparse
169 ###
170
171 def yyparse( recv, mid )
172 __send__ Racc_YY_Parse_Method, recv, mid, _racc_setup(), true
173 end
174
175 def _racc_yyparse_rb( recv, mid, arg, c_debug )
176 action_table, action_check, action_default, action_pointer,
177 goto_table, goto_check, goto_default, goto_pointer,
178 nt_base, reduce_table, token_table, shift_n,
179 reduce_n, use_result, * = arg
180
181 _racc_init_sysvars
182 tok = nil
183 act = nil
184 i = nil
185 nerr = 0
186
187
188 catch( :racc_end_parse ) {
189 until i = action_pointer[ @racc_state[-1] ] do
190 while act = _racc_evalact(
191 action_default[ @racc_state[-1] ], arg ) do end
192 end
193
194 recv.__send__( mid ) do |tok, val|
195 # $stderr.puts "rd: tok=#{tok}, val=#{val}"
196 unless tok then
197 @racc_t = 0
198 else
199 @racc_t = (token_table[tok] or 1) # error token
200 end
201 @racc_val = val
202 @racc_read_next = false
203
204 i += @racc_t
205 if i >= 0 and act = action_table[i] and
206 action_check[i] == @racc_state[-1] then
207 # $stderr.puts "01: act=#{act}"
208 else
209 act = action_default[ @racc_state[-1] ]
210 # $stderr.puts "02: act=#{act}"
211 # $stderr.puts "curstate=#{@racc_state[-1]}"
212 end
213
214 while act = _racc_evalact( act, arg ) do end
215
216 while not (i = action_pointer[ @racc_state[-1] ]) or
217 not @racc_read_next or
218 @racc_t == 0 do # $
219 if i and i += @racc_t and
220 i >= 0 and
221 act = action_table[i] and
222 action_check[i] == @racc_state[-1] then
223 # $stderr.puts "03: act=#{act}"
224 ;
225 else
226 # $stderr.puts "04: act=#{act}"
227 act = action_default[ @racc_state[-1] ]
228 end
229
230 while act = _racc_evalact( act, arg ) do end
231 end
232 end
233 }
234 end
235
236
237 ###
238 ### common
239 ###
240
241 def _racc_evalact( act, arg )
242 # $stderr.puts "ea: act=#{act}"
243 action_table, action_check, action_default, action_pointer,
244 goto_table, goto_check, goto_default, goto_pointer,
245 nt_base, reduce_table, token_table, shift_n,
246 reduce_n, use_result, * = arg
247 nerr = 0 # tmp
248
249 if act > 0 and act < shift_n then
250 #
251 # shift
252 #
253
254 if @racc_error_status > 0 then
255 @racc_error_status -= 1 unless @racc_t == 1 # error token
256 end
257
258 @racc_vstack.push @racc_val
259 @racc_state.push act
260 @racc_read_next = true
261
262 if @yydebug then
263 @racc_tstack.push @racc_t
264 racc_shift( @racc_t, @racc_tstack, @racc_vstack )
265 end
266
267 elsif act < 0 and act > -reduce_n then
268 #
269 # reduce
270 #
271
272 code = catch( :racc_jump ) {
273 @racc_state.push _racc_do_reduce( arg, act )
274 false
275 }
276 if code then
277 case code
278 when 1 # yyerror
279 @racc_user_yyerror = true # user_yyerror
280 return -reduce_n
281 when 2 # yyaccept
282 return shift_n
283 else
284 raise RuntimeError, '[Racc Bug] unknown jump code'
285 end
286 end
287
288 elsif act == shift_n then
289 #
290 # accept
291 #
292
293 racc_accept if @yydebug
294 throw :racc_end_parse, @racc_vstack[0]
295
296 elsif act == -reduce_n then
297 #
298 # error
299 #
300
301 case @racc_error_status
302 when 0
303 unless arg[21] then # user_yyerror
304 nerr += 1
305 on_error @racc_t, @racc_val, @racc_vstack
306 end
307 when 3
308 if @racc_t == 0 then # is $
309 throw :racc_end_parse, nil
310 end
311 @racc_read_next = true
312 end
313 @racc_user_yyerror = false
314 @racc_error_status = 3
315
316 while true do
317 if i = action_pointer[ @racc_state[-1] ] then
318 i += 1 # error token
319 if i >= 0 and
320 (act = action_table[i]) and
321 action_check[i] == @racc_state[-1] then
322 break
323 end
324 end
325
326 throw :racc_end_parse, nil if @racc_state.size < 2
327 @racc_state.pop
328 @racc_vstack.pop
329 if @yydebug then
330 @racc_tstack.pop
331 racc_e_pop( @racc_state, @racc_tstack, @racc_vstack )
332 end
333 end
334
335 return act
336
337 else
338 raise RuntimeError, "[Racc Bug] unknown action #{act.inspect}"
339 end
340
341 racc_next_state( @racc_state[-1], @racc_state ) if @yydebug
342
343 nil
344 end
345
346 def _racc_do_reduce( arg, act )
347 action_table, action_check, action_default, action_pointer,
348 goto_table, goto_check, goto_default, goto_pointer,
349 nt_base, reduce_table, token_table, shift_n,
350 reduce_n, use_result, * = arg
351 state = @racc_state
352 vstack = @racc_vstack
353 tstack = @racc_tstack
354
355 i = act * -3
356 len = reduce_table[i]
357 reduce_to = reduce_table[i+1]
358 method_id = reduce_table[i+2]
359 void_array = []
360
361 tmp_t = tstack[ -len, len ] if @yydebug
362 tmp_v = vstack[ -len, len ]
363 tstack[ -len, len ] = void_array if @yydebug
364 vstack[ -len, len ] = void_array
365 state[ -len, len ] = void_array
366
367 # tstack must be updated AFTER method call
368 if use_result then
369 vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
370 else
371 vstack.push __send__(method_id, tmp_v, vstack)
372 end
373 tstack.push reduce_to
374
375 racc_reduce( tmp_t, reduce_to, tstack, vstack ) if @yydebug
376
377 k1 = reduce_to - nt_base
378 if i = goto_pointer[ k1 ] then
379 i += state[-1]
380 if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1 then
381 return curstate
382 end
383 end
384 goto_default[ k1 ]
385 end
386
387 def on_error( t, val, vstack )
388 raise ParseError, sprintf("\nparse error on value %s (%s)",
389 val.inspect,
390 token_to_str(t) || '?')
391 end
392
393 def yyerror
394 throw :racc_jump, 1
395 end
396
397 def yyaccept
398 throw :racc_jump, 2
399 end
400
401 def yyerrok
402 @racc_error_status = 0
403 end
404
405
406 # for debugging output
407
408 def racc_read_token( t, tok, val )
409 @racc_debug_out.print 'read '
410 @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
411 @racc_debug_out.puts val.inspect
412 @racc_debug_out.puts
413 end
414
415 def racc_shift( tok, tstack, vstack )
416 @racc_debug_out.puts "shift #{racc_token2str tok}"
417 racc_print_stacks tstack, vstack
418 @racc_debug_out.puts
419 end
420
421 def racc_reduce( toks, sim, tstack, vstack )
422 out = @racc_debug_out
423 out.print 'reduce '
424 if toks.empty? then
425 out.print ' <none>'
426 else
427 toks.each {|t| out.print ' ', racc_token2str(t) }
428 end
429 out.puts " --> #{racc_token2str(sim)}"
430
431 racc_print_stacks tstack, vstack
432 @racc_debug_out.puts
433 end
434
435 def racc_accept
436 @racc_debug_out.puts 'accept'
437 @racc_debug_out.puts
438 end
439
440 def racc_e_pop( state, tstack, vstack )
441 @racc_debug_out.puts 'error recovering mode: pop token'
442 racc_print_states state
443 racc_print_stacks tstack, vstack
444 @racc_debug_out.puts
445 end
446
447 def racc_next_state( curstate, state )
448 @racc_debug_out.puts "goto #{curstate}"
449 racc_print_states state
450 @racc_debug_out.puts
451 end
452
453 def racc_print_stacks( t, v )
454 out = @racc_debug_out
455 out.print ' ['
456 t.each_index do |i|
457 out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
458 end
459 out.puts ' ]'
460 end
461
462 def racc_print_states( s )
463 out = @racc_debug_out
464 out.print ' ['
465 s.each {|st| out.print ' ', st }
466 out.puts ' ]'
467 end
468
469 def racc_token2str( tok )
470 type::Racc_token_to_s_table[tok] or
471 raise RuntimeError, "[Racc Bug] can't convert token #{tok} to string"
472 end
473
474 def token_to_str( t )
475 type::Racc_token_to_s_table[t]
476 end
477
478 end
479
480 end