1 | #
|
---|
2 | # $originalId: parser.rb,v 1.8 2006/07/06 11:42:07 aamine Exp $
|
---|
3 | #
|
---|
4 | # Copyright (c) 1999-2006 Minero Aoki
|
---|
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 |
|
---|
14 | unless defined?(NotImplementedError)
|
---|
15 | NotImplementedError = NotImplementError
|
---|
16 | end
|
---|
17 |
|
---|
18 | module Racc
|
---|
19 | class ParseError < StandardError; end
|
---|
20 | end
|
---|
21 | unless defined?(::ParseError)
|
---|
22 | ParseError = Racc::ParseError
|
---|
23 | end
|
---|
24 |
|
---|
25 | module Racc
|
---|
26 |
|
---|
27 | unless defined?(Racc_No_Extentions)
|
---|
28 | Racc_No_Extentions = false
|
---|
29 | end
|
---|
30 |
|
---|
31 | class Parser
|
---|
32 |
|
---|
33 | Racc_Runtime_Version = '1.4.5'
|
---|
34 | Racc_Runtime_Revision = '$originalRevision: 1.8 $'.split[1]
|
---|
35 |
|
---|
36 | Racc_Runtime_Core_Version_R = '1.4.5'
|
---|
37 | Racc_Runtime_Core_Revision_R = '$originalRevision: 1.8 $'.split[1]
|
---|
38 | begin
|
---|
39 | require 'racc/cparse'
|
---|
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'
|
---|
44 | end
|
---|
45 | if Racc_No_Extentions
|
---|
46 | raise LoadError, 'selecting ruby version of racc runtime core'
|
---|
47 | end
|
---|
48 |
|
---|
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'
|
---|
54 | rescue LoadError
|
---|
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'
|
---|
60 | end
|
---|
61 |
|
---|
62 | def Parser.racc_runtime_type
|
---|
63 | Racc_Runtime_Type
|
---|
64 | end
|
---|
65 |
|
---|
66 | private
|
---|
67 |
|
---|
68 | def _racc_setup
|
---|
69 | @yydebug = false unless self.class::Racc_debug_parser
|
---|
70 | @yydebug = false unless defined?(@yydebug)
|
---|
71 | if @yydebug
|
---|
72 | @racc_debug_out = $stderr unless defined?(@racc_debug_out)
|
---|
73 | @racc_debug_out ||= $stderr
|
---|
74 | end
|
---|
75 | arg = self.class::Racc_arg
|
---|
76 | arg[13] = true if arg.size < 14
|
---|
77 | arg
|
---|
78 | end
|
---|
79 |
|
---|
80 | def _racc_init_sysvars
|
---|
81 | @racc_state = [0]
|
---|
82 | @racc_tstack = []
|
---|
83 | @racc_vstack = []
|
---|
84 |
|
---|
85 | @racc_t = nil
|
---|
86 | @racc_val = nil
|
---|
87 |
|
---|
88 | @racc_read_next = true
|
---|
89 |
|
---|
90 | @racc_user_yyerror = false
|
---|
91 | @racc_error_status = 0
|
---|
92 | end
|
---|
93 |
|
---|
94 | ###
|
---|
95 | ### do_parse
|
---|
96 | ###
|
---|
97 |
|
---|
98 | def do_parse
|
---|
99 | __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
|
---|
100 | end
|
---|
101 |
|
---|
102 | def next_token
|
---|
103 | raise NotImplementedError, "#{self.class}\#next_token is not defined"
|
---|
104 | end
|
---|
105 |
|
---|
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
|
---|
111 |
|
---|
112 | _racc_init_sysvars
|
---|
113 | tok = act = i = nil
|
---|
114 | nerr = 0
|
---|
115 |
|
---|
116 | catch(:racc_end_parse) {
|
---|
117 | while true
|
---|
118 | if i = action_pointer[@racc_state[-1]]
|
---|
119 | if @racc_read_next
|
---|
120 | if @racc_t != 0 # not EOF
|
---|
121 | tok, @racc_val = next_token()
|
---|
122 | unless tok # EOF
|
---|
123 | @racc_t = 0
|
---|
124 | else
|
---|
125 | @racc_t = (token_table[tok] or 1) # error token
|
---|
126 | end
|
---|
127 | racc_read_token(@racc_t, tok, @racc_val) if @yydebug
|
---|
128 | @racc_read_next = false
|
---|
129 | end
|
---|
130 | end
|
---|
131 | i += @racc_t
|
---|
132 | unless i >= 0 and
|
---|
133 | act = action_table[i] and
|
---|
134 | action_check[i] == @racc_state[-1]
|
---|
135 | act = action_default[@racc_state[-1]]
|
---|
136 | end
|
---|
137 | else
|
---|
138 | act = action_default[@racc_state[-1]]
|
---|
139 | end
|
---|
140 | while act = _racc_evalact(act, arg)
|
---|
141 | ;
|
---|
142 | end
|
---|
143 | end
|
---|
144 | }
|
---|
145 | end
|
---|
146 |
|
---|
147 | ###
|
---|
148 | ### yyparse
|
---|
149 | ###
|
---|
150 |
|
---|
151 | def yyparse(recv, mid)
|
---|
152 | __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
|
---|
153 | end
|
---|
154 |
|
---|
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
|
---|
160 |
|
---|
161 | _racc_init_sysvars
|
---|
162 | tok = nil
|
---|
163 | act = nil
|
---|
164 | i = nil
|
---|
165 | nerr = 0
|
---|
166 |
|
---|
167 | catch(:racc_end_parse) {
|
---|
168 | until i = action_pointer[@racc_state[-1]]
|
---|
169 | while act = _racc_evalact(action_default[@racc_state[-1]], arg)
|
---|
170 | ;
|
---|
171 | end
|
---|
172 | end
|
---|
173 | recv.__send__(mid) do |tok, val|
|
---|
174 | unless tok
|
---|
175 | @racc_t = 0
|
---|
176 | else
|
---|
177 | @racc_t = (token_table[tok] or 1) # error token
|
---|
178 | end
|
---|
179 | @racc_val = val
|
---|
180 | @racc_read_next = false
|
---|
181 |
|
---|
182 | i += @racc_t
|
---|
183 | unless i >= 0 and
|
---|
184 | act = action_table[i] and
|
---|
185 | action_check[i] == @racc_state[-1]
|
---|
186 | act = action_default[@racc_state[-1]]
|
---|
187 | end
|
---|
188 | while act = _racc_evalact(act, arg)
|
---|
189 | ;
|
---|
190 | end
|
---|
191 |
|
---|
192 | while not (i = action_pointer[@racc_state[-1]]) or
|
---|
193 | not @racc_read_next or
|
---|
194 | @racc_t == 0 # $
|
---|
195 | unless i and i += @racc_t and
|
---|
196 | i >= 0 and
|
---|
197 | act = action_table[i] and
|
---|
198 | action_check[i] == @racc_state[-1]
|
---|
199 | act = action_default[@racc_state[-1]]
|
---|
200 | end
|
---|
201 | while act = _racc_evalact(act, arg)
|
---|
202 | ;
|
---|
203 | end
|
---|
204 | end
|
---|
205 | end
|
---|
206 | }
|
---|
207 | end
|
---|
208 |
|
---|
209 | ###
|
---|
210 | ### common
|
---|
211 | ###
|
---|
212 |
|
---|
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
|
---|
218 | nerr = 0 # tmp
|
---|
219 |
|
---|
220 | if act > 0 and act < shift_n
|
---|
221 | #
|
---|
222 | # shift
|
---|
223 | #
|
---|
224 | if @racc_error_status > 0
|
---|
225 | @racc_error_status -= 1 unless @racc_t == 1 # error token
|
---|
226 | end
|
---|
227 | @racc_vstack.push @racc_val
|
---|
228 | @racc_state.push act
|
---|
229 | @racc_read_next = true
|
---|
230 | if @yydebug
|
---|
231 | @racc_tstack.push @racc_t
|
---|
232 | racc_shift @racc_t, @racc_tstack, @racc_vstack
|
---|
233 | end
|
---|
234 |
|
---|
235 | elsif act < 0 and act > -reduce_n
|
---|
236 | #
|
---|
237 | # reduce
|
---|
238 | #
|
---|
239 | code = catch(:racc_jump) {
|
---|
240 | @racc_state.push _racc_do_reduce(arg, act)
|
---|
241 | false
|
---|
242 | }
|
---|
243 | if code
|
---|
244 | case code
|
---|
245 | when 1 # yyerror
|
---|
246 | @racc_user_yyerror = true # user_yyerror
|
---|
247 | return -reduce_n
|
---|
248 | when 2 # yyaccept
|
---|
249 | return shift_n
|
---|
250 | else
|
---|
251 | raise '[Racc Bug] unknown jump code'
|
---|
252 | end
|
---|
253 | end
|
---|
254 |
|
---|
255 | elsif act == shift_n
|
---|
256 | #
|
---|
257 | # accept
|
---|
258 | #
|
---|
259 | racc_accept if @yydebug
|
---|
260 | throw :racc_end_parse, @racc_vstack[0]
|
---|
261 |
|
---|
262 | elsif act == -reduce_n
|
---|
263 | #
|
---|
264 | # error
|
---|
265 | #
|
---|
266 | case @racc_error_status
|
---|
267 | when 0
|
---|
268 | unless arg[21] # user_yyerror
|
---|
269 | nerr += 1
|
---|
270 | on_error @racc_t, @racc_val, @racc_vstack
|
---|
271 | end
|
---|
272 | when 3
|
---|
273 | if @racc_t == 0 # is $
|
---|
274 | throw :racc_end_parse, nil
|
---|
275 | end
|
---|
276 | @racc_read_next = true
|
---|
277 | end
|
---|
278 | @racc_user_yyerror = false
|
---|
279 | @racc_error_status = 3
|
---|
280 | while true
|
---|
281 | if i = action_pointer[@racc_state[-1]]
|
---|
282 | i += 1 # error token
|
---|
283 | if i >= 0 and
|
---|
284 | (act = action_table[i]) and
|
---|
285 | action_check[i] == @racc_state[-1]
|
---|
286 | break
|
---|
287 | end
|
---|
288 | end
|
---|
289 | throw :racc_end_parse, nil if @racc_state.size <= 1
|
---|
290 | @racc_state.pop
|
---|
291 | @racc_vstack.pop
|
---|
292 | if @yydebug
|
---|
293 | @racc_tstack.pop
|
---|
294 | racc_e_pop @racc_state, @racc_tstack, @racc_vstack
|
---|
295 | end
|
---|
296 | end
|
---|
297 | return act
|
---|
298 |
|
---|
299 | else
|
---|
300 | raise "[Racc Bug] unknown action #{act.inspect}"
|
---|
301 | end
|
---|
302 |
|
---|
303 | racc_next_state(@racc_state[-1], @racc_state) if @yydebug
|
---|
304 |
|
---|
305 | nil
|
---|
306 | end
|
---|
307 |
|
---|
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
|
---|
313 | state = @racc_state
|
---|
314 | vstack = @racc_vstack
|
---|
315 | tstack = @racc_tstack
|
---|
316 |
|
---|
317 | i = act * -3
|
---|
318 | len = reduce_table[i]
|
---|
319 | reduce_to = reduce_table[i+1]
|
---|
320 | method_id = reduce_table[i+2]
|
---|
321 | void_array = []
|
---|
322 |
|
---|
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
|
---|
328 |
|
---|
329 | # tstack must be updated AFTER method call
|
---|
330 | if use_result
|
---|
331 | vstack.push __send__(method_id, tmp_v, vstack, tmp_v[0])
|
---|
332 | else
|
---|
333 | vstack.push __send__(method_id, tmp_v, vstack)
|
---|
334 | end
|
---|
335 | tstack.push reduce_to
|
---|
336 |
|
---|
337 | racc_reduce(tmp_t, reduce_to, tstack, vstack) if @yydebug
|
---|
338 |
|
---|
339 | k1 = reduce_to - nt_base
|
---|
340 | if i = goto_pointer[k1]
|
---|
341 | i += state[-1]
|
---|
342 | if i >= 0 and (curstate = goto_table[i]) and goto_check[i] == k1
|
---|
343 | return curstate
|
---|
344 | end
|
---|
345 | end
|
---|
346 | goto_default[k1]
|
---|
347 | end
|
---|
348 |
|
---|
349 | def on_error(t, val, vstack)
|
---|
350 | raise ParseError, sprintf("\nparse error on value %s (%s)",
|
---|
351 | val.inspect, token_to_str(t) || '?')
|
---|
352 | end
|
---|
353 |
|
---|
354 | def yyerror
|
---|
355 | throw :racc_jump, 1
|
---|
356 | end
|
---|
357 |
|
---|
358 | def yyaccept
|
---|
359 | throw :racc_jump, 2
|
---|
360 | end
|
---|
361 |
|
---|
362 | def yyerrok
|
---|
363 | @racc_error_status = 0
|
---|
364 | end
|
---|
365 |
|
---|
366 | #
|
---|
367 | # for debugging output
|
---|
368 | #
|
---|
369 |
|
---|
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
|
---|
374 | @racc_debug_out.puts
|
---|
375 | end
|
---|
376 |
|
---|
377 | def racc_shift(tok, tstack, vstack)
|
---|
378 | @racc_debug_out.puts "shift #{racc_token2str tok}"
|
---|
379 | racc_print_stacks tstack, vstack
|
---|
380 | @racc_debug_out.puts
|
---|
381 | end
|
---|
382 |
|
---|
383 | def racc_reduce(toks, sim, tstack, vstack)
|
---|
384 | out = @racc_debug_out
|
---|
385 | out.print 'reduce '
|
---|
386 | if toks.empty?
|
---|
387 | out.print ' <none>'
|
---|
388 | else
|
---|
389 | toks.each {|t| out.print ' ', racc_token2str(t) }
|
---|
390 | end
|
---|
391 | out.puts " --> #{racc_token2str(sim)}"
|
---|
392 |
|
---|
393 | racc_print_stacks tstack, vstack
|
---|
394 | @racc_debug_out.puts
|
---|
395 | end
|
---|
396 |
|
---|
397 | def racc_accept
|
---|
398 | @racc_debug_out.puts 'accept'
|
---|
399 | @racc_debug_out.puts
|
---|
400 | end
|
---|
401 |
|
---|
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
|
---|
406 | @racc_debug_out.puts
|
---|
407 | end
|
---|
408 |
|
---|
409 | def racc_next_state(curstate, state)
|
---|
410 | @racc_debug_out.puts "goto #{curstate}"
|
---|
411 | racc_print_states state
|
---|
412 | @racc_debug_out.puts
|
---|
413 | end
|
---|
414 |
|
---|
415 | def racc_print_stacks(t, v)
|
---|
416 | out = @racc_debug_out
|
---|
417 | out.print ' ['
|
---|
418 | t.each_index do |i|
|
---|
419 | out.print ' (', racc_token2str(t[i]), ' ', v[i].inspect, ')'
|
---|
420 | end
|
---|
421 | out.puts ' ]'
|
---|
422 | end
|
---|
423 |
|
---|
424 | def racc_print_states(s)
|
---|
425 | out = @racc_debug_out
|
---|
426 | out.print ' ['
|
---|
427 | s.each {|st| out.print ' ', st }
|
---|
428 | out.puts ' ]'
|
---|
429 | end
|
---|
430 |
|
---|
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"
|
---|
434 | end
|
---|
435 |
|
---|
436 | def token_to_str(t)
|
---|
437 | self.class::Racc_token_to_s_table[t]
|
---|
438 | end
|
---|
439 |
|
---|
440 | end
|
---|
441 |
|
---|
442 | end
|
---|