2
# $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $
4
# Copyright (c) 1999-2006 Minero Aoki
6
# This program is free software.
7
# You can distribute/modify this program under the same terms of ruby.
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.
14
unless defined?(NotImplementedError)
15
NotImplementedError = NotImplementError
19
class ParseError < StandardError; end
21
unless defined?(::ParseError)
22
ParseError = Racc::ParseError
27
unless defined?(Racc_No_Extentions)
28
Racc_No_Extentions = false
33
Racc_Runtime_Version = '1.4.5'
34
Racc_Runtime_Revision = '$originalRevision: 1.8 $'.split[1]
36
Racc_Runtime_Core_Version_R = '1.4.5'
37
Racc_Runtime_Core_Revision_R = '$originalRevision: 1.8 $'.split[1]
40
# Racc_Runtime_Core_Version_C = (defined in extention)
41
Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
42
unless new.respond_to?(:_racc_do_parse_c, true)
43
raise LoadError, 'old cparse.so'
46
raise LoadError, 'selecting ruby version of racc runtime core'
49
Racc_Main_Parsing_Routine = :_racc_do_parse_c
50
Racc_YY_Parse_Method = :_racc_yyparse_c
51
Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_C
52
Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_C
53
Racc_Runtime_Type = 'c'
55
Racc_Main_Parsing_Routine = :_racc_do_parse_rb
56
Racc_YY_Parse_Method = :_racc_yyparse_rb
57
Racc_Runtime_Core_Version = Racc_Runtime_Core_Version_R
58
Racc_Runtime_Core_Revision = Racc_Runtime_Core_Revision_R
59
Racc_Runtime_Type = 'ruby'
62
def Parser.racc_runtime_type
69
@yydebug = false unless self.class::Racc_debug_parser
70
@yydebug = false unless defined?(@yydebug)
72
@racc_debug_out = $stderr unless defined?(@racc_debug_out)
73
@racc_debug_out ||= $stderr
75
arg = self.class::Racc_arg
76
arg[13] = true if arg.size < 14
80
def _racc_init_sysvars
88
@racc_read_next = true
90
@racc_user_yyerror = false
91
@racc_error_status = 0
99
__send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
103
raise NotImplementedError, "#{self.class}\#next_token is not defined"
106
def _racc_do_parse_rb(arg, in_debug)
107
action_table, action_check, action_default, action_pointer,
108
goto_table, goto_check, goto_default, goto_pointer,
109
nt_base, reduce_table, token_table, shift_n,
110
reduce_n, use_result, * = arg
116
catch(:racc_end_parse) {
118
if i = action_pointer[@racc_state[-1]]
120
if @racc_t != 0 # not EOF
121
tok, @racc_val = next_token()
125
@racc_t = (token_table[tok] or 1) # error token
127
racc_read_token(@racc_t, tok, @racc_val) if @yydebug
128
@racc_read_next = false
133
act = action_table[i] and
134
action_check[i] == @racc_state[-1]
135
act = action_default[@racc_state[-1]]
138
act = action_default[@racc_state[-1]]
140
while act = _racc_evalact(act, arg)
151
def yyparse(recv, mid)
152
__send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
155
def _racc_yyparse_rb(recv, mid, arg, c_debug)
156
action_table, action_check, action_default, action_pointer,
157
goto_table, goto_check, goto_default, goto_pointer,
158
nt_base, reduce_table, token_table, shift_n,
159
reduce_n, use_result, * = arg
167
catch(:racc_end_parse) {
168
until i = action_pointer[@racc_state[-1]]
169
while act = _racc_evalact(action_default[@racc_state[-1]], arg)
173
recv.__send__(mid) do |tok, val|
177
@racc_t = (token_table[tok] or 1) # error token
180
@racc_read_next = false
184
act = action_table[i] and
185
action_check[i] == @racc_state[-1]
186
act = action_default[@racc_state[-1]]
188
while act = _racc_evalact(act, arg)
192
while not (i = action_pointer[@racc_state[-1]]) or
193
not @racc_read_next or
195
unless i and i += @racc_t and
197
act = action_table[i] and
198
action_check[i] == @racc_state[-1]
199
act = action_default[@racc_state[-1]]
201
while act = _racc_evalact(act, arg)
213
def _racc_evalact(act, arg)
214
action_table, action_check, action_default, action_pointer,
215
goto_table, goto_check, goto_default, goto_pointer,
216
nt_base, reduce_table, token_table, shift_n,
217
reduce_n, use_result, * = arg
220
if act > 0 and act < shift_n
224
if @racc_error_status > 0
225
@racc_error_status -= 1 unless @racc_t == 1 # error token
227
@racc_vstack.push @racc_val
229
@racc_read_next = true
231
@racc_tstack.push @racc_t
232
racc_shift @racc_t, @racc_tstack, @racc_vstack
235
elsif act < 0 and act > -reduce_n
239
code = catch(:racc_jump) {
240
@racc_state.push _racc_do_reduce(arg, act)
246
@racc_user_yyerror = true # user_yyerror
251
raise '[Racc Bug] unknown jump code'
259
racc_accept if @yydebug
260
throw :racc_end_parse, @racc_vstack[0]
262
elsif act == -reduce_n
266
case @racc_error_status
268
unless arg[21] # user_yyerror
270
on_error @racc_t, @racc_val, @racc_vstack
273
if @racc_t == 0 # is $
274
throw :racc_end_parse, nil
276
@racc_read_next = true
278
@racc_user_yyerror = false
279
@racc_error_status = 3
281
if i = action_pointer[@racc_state[-1]]
284
(act = action_table[i]) and
285
action_check[i] == @racc_state[-1]
289
throw :racc_end_parse, nil if @racc_state.size <= 1
294
racc_e_pop @racc_state, @racc_tstack, @racc_vstack
300
raise "[Racc Bug] unknown action #{act.inspect}"
303
racc_next_state(@racc_state[-1], @racc_state) if @yydebug
308
def _racc_do_reduce(arg, act)
309
action_table, action_check, action_default, action_pointer,
310
goto_table, goto_check, goto_default, goto_pointer,
311
nt_base, reduce_table, token_table, shift_n,
312
reduce_n, use_result, * = arg
314
vstack = @racc_vstack
315
tstack = @racc_tstack
318
len = reduce_table[i]
319
reduce_to = reduce_table[i+1]
320
method_id = reduce_table[i+2]
323
tmp_t = tstack[-len, len] if @yydebug
324
tmp_v = vstack[-len, len]
325
tstack[-len, len] = void_array if @yydebug
326
vstack[-len, len] = void_array
327
state[-len, len] = void_array
329
# tstack must be updated AFTER method call
331
vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
333
vstack.push __send__(method_id, tmp_v, vstack)
335
tstack.push reduce_to
337
racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
339
k1 = reduce_to - nt_base
340
if i = goto_pointer[k1]
342
if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
349
def on_error(t, val, vstack)
350
raise ParseError, sprintf("\nparse error on value %s (%s)",
351
val.inspect, token_to_str(t) || '?')
363
@racc_error_status = 0
367
# for debugging output
370
def racc_read_token(t, tok, val)
371
@racc_debug_out.print 'read '
372
@racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
373
@racc_debug_out.puts val.inspect
377
def racc_shift(tok, tstack, vstack)
378
@racc_debug_out.puts "shift #{racc_token2str tok}"
379
racc_print_stacks tstack, vstack
383
def racc_reduce(toks, sim, tstack, vstack)
384
out = @racc_debug_out
389
toks.each {|t| out.print ' ', racc_token2str(t) }
391
out.puts " --> #{racc_token2str(sim)}"
393
racc_print_stacks tstack, vstack
398
@racc_debug_out.puts 'accept'
402
def racc_e_pop(state, tstack, vstack)
403
@racc_debug_out.puts 'error recovering mode: pop token'
404
racc_print_states state
405
racc_print_stacks tstack, vstack
409
def racc_next_state(curstate, state)
410
@racc_debug_out.puts "goto #{curstate}"
411
racc_print_states state
415
def racc_print_stacks(t, v)
416
out = @racc_debug_out
419
out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
424
def racc_print_states(s)
425
out = @racc_debug_out
427
s.each {|st| out.print ' ', st }
431
def racc_token2str(tok)
432
self.class::Racc_token_to_s_table[tok] or
433
raise "[Racc Bug] can't convert token #{tok} to string"
437
self.class::Racc_token_to_s_table[t]