Ruby
1.9.3p551(2014-11-13revision48407)
Main Page
Modules
Data Structures
Files
File List
Globals
ext
racc
cparse
cparse.c
Go to the documentation of this file.
1
/*
2
3
cparse.c -- Racc Runtime Core
4
5
Copyright (c) 1999-2006 Minero Aoki
6
7
This library is free software.
8
You can distribute/modify this program under the same terms of ruby.
9
10
$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $
11
12
*/
13
14
#include "
ruby/ruby.h
"
15
16
#ifndef FALSE
17
#define FALSE 0
18
#endif
19
#ifndef TRUE
20
#define TRUE 1
21
#endif
22
23
/* -----------------------------------------------------------------------
24
Important Constants
25
----------------------------------------------------------------------- */
26
27
#define RACC_VERSION "1.4.5"
28
29
#define DEFAULT_TOKEN -1
30
#define ERROR_TOKEN 1
31
#define FINAL_TOKEN 0
32
33
#define vDEFAULT_TOKEN INT2FIX(DEFAULT_TOKEN)
34
#define vERROR_TOKEN INT2FIX(ERROR_TOKEN)
35
#define vFINAL_TOKEN INT2FIX(FINAL_TOKEN)
36
37
/* -----------------------------------------------------------------------
38
File Local Variables
39
----------------------------------------------------------------------- */
40
41
static
VALUE
RaccBug
;
42
static
VALUE
CparseParams
;
43
44
static
ID
id_yydebug
;
45
static
ID
id_nexttoken
;
46
static
ID
id_onerror
;
47
static
ID
id_noreduce
;
48
static
ID
id_errstatus
;
49
50
static
ID
id_d_shift
;
51
static
ID
id_d_reduce
;
52
static
ID
id_d_accept
;
53
static
ID
id_d_read_token
;
54
static
ID
id_d_next_state
;
55
static
ID
id_d_e_pop
;
56
57
/* -----------------------------------------------------------------------
58
Utils
59
----------------------------------------------------------------------- */
60
61
/* For backward compatibility */
62
#ifndef ID2SYM
63
# define ID2SYM(i) ULONG2NUM(i)
64
#endif
65
#ifndef SYM2ID
66
# define SYM2ID(v) ((ID)NUM2ULONG(v))
67
#endif
68
#ifndef SYMBOL_P
69
# define SYMBOL_P(v) FIXNUM_P(v)
70
#endif
71
#ifndef LONG2NUM
72
# define LONG2NUM(i) INT2NUM(i)
73
#endif
74
75
static
ID
value_to_id
_
((
VALUE
v
));
76
static
inline
long
num_to_long
_
((
VALUE
n));
77
78
static
ID
79
value_to_id
(
VALUE
v
)
80
{
81
if
(!
SYMBOL_P
(v)) {
82
rb_raise
(
rb_eTypeError
,
"not symbol"
);
83
}
84
return
SYM2ID
(v);
85
}
86
87
static
inline
long
88
num_to_long
(
VALUE
n)
89
{
90
return
NUM2LONG
(n);
91
}
92
93
#define AREF(s, idx) \
94
((0 <= idx && idx < RARRAY_LEN(s)) ? RARRAY_PTR(s)[idx] : Qnil)
95
96
/* -----------------------------------------------------------------------
97
Parser Stack Interfaces
98
----------------------------------------------------------------------- */
99
100
static
VALUE
get_stack_tail
_
((
VALUE
stack,
long
len
));
101
static
void
cut_stack_tail
_
((
VALUE
stack,
long
len
));
102
103
static
VALUE
104
get_stack_tail
(
VALUE
stack,
long
len
)
105
{
106
if
(len < 0)
return
Qnil
;
/* system error */
107
if
(len >
RARRAY_LEN
(stack)) len =
RARRAY_LEN
(stack);
108
return
rb_ary_new4
(len,
RARRAY_PTR
(stack) +
RARRAY_LEN
(stack) - len);
109
}
110
111
static
void
112
cut_stack_tail
(
VALUE
stack,
long
len
)
113
{
114
while
(len > 0) {
115
rb_ary_pop
(stack);
116
len--;
117
}
118
}
119
120
#define STACK_INIT_LEN 64
121
#define NEW_STACK() rb_ary_new2(STACK_INIT_LEN)
122
#define PUSH(s, i) rb_ary_store(s, RARRAY_LEN(s), i)
123
#define POP(s) rb_ary_pop(s)
124
#define LAST_I(s) \
125
((RARRAY_LEN(s) > 0) ? RARRAY_PTR(s)[RARRAY_LEN(s) - 1] : Qnil)
126
#define GET_TAIL(s, len) get_stack_tail(s, len)
127
#define CUT_TAIL(s, len) cut_stack_tail(s, len)
128
129
/* -----------------------------------------------------------------------
130
struct cparse_params
131
----------------------------------------------------------------------- */
132
133
struct
cparse_params
{
134
VALUE
value_v
;
/* VALUE version of this struct */
135
136
VALUE
parser
;
/* parser object */
137
138
int
lex_is_iterator
;
139
VALUE
lexer
;
/* scanner object */
140
ID
lexmid
;
/* name of scanner method (must be an iterator) */
141
142
/* State transition tables (immutable)
143
Data structure is from Dragon Book 4.9 */
144
/* action table */
145
VALUE
action_table
;
146
VALUE
action_check
;
147
VALUE
action_default
;
148
VALUE
action_pointer
;
149
/* goto table */
150
VALUE
goto_table
;
151
VALUE
goto_check
;
152
VALUE
goto_default
;
153
VALUE
goto_pointer
;
154
155
long
nt_base
;
/* NonTerminal BASE index */
156
VALUE
reduce_table
;
/* reduce data table */
157
VALUE
token_table
;
/* token conversion table */
158
159
/* parser stacks and parameters */
160
VALUE
state
;
161
long
curstate
;
162
VALUE
vstack
;
163
VALUE
tstack
;
164
VALUE
t
;
165
long
shift_n
;
166
long
reduce_n
;
167
long
ruleno
;
168
169
long
errstatus
;
/* nonzero in error recovering mode */
170
long
nerr
;
/* number of error */
171
172
int
use_result_var
;
173
174
VALUE
retval
;
/* return value of parser routine */
175
long
fin
;
/* parse result status */
176
#define CP_FIN_ACCEPT 1
177
#define CP_FIN_EOT 2
178
#define CP_FIN_CANTPOP 3
179
180
int
debug
;
/* user level debug */
181
int
sys_debug
;
/* system level debug */
182
183
long
i
;
/* table index */
184
};
185
186
/* -----------------------------------------------------------------------
187
Parser Main Routines
188
----------------------------------------------------------------------- */
189
190
static
VALUE
racc_cparse
_
((
VALUE
parser,
VALUE
arg
,
VALUE
sysdebug));
191
static
VALUE
racc_yyparse
_
((
VALUE
parser,
VALUE
lexer,
VALUE
lexmid,
192
VALUE
arg
,
VALUE
sysdebug));
193
194
static
void
call_lexer
_
((
struct
cparse_params
*
v
));
195
static
VALUE
lexer_i
_
((
VALUE
block_args,
VALUE
data,
VALUE
self
));
196
197
static
VALUE
assert_array
_
((
VALUE
a));
198
static
long
assert_integer
_
((
VALUE
n));
199
static
VALUE
assert_hash
_
((
VALUE
h));
200
static
VALUE
initialize_params
_
((
VALUE
vparams,
VALUE
parser,
VALUE
arg
,
201
VALUE
lexer,
VALUE
lexmid));
202
static
void
cparse_params_mark
_
((
void
*ptr));
203
204
static
void
parse_main
_
((
struct
cparse_params
*
v
,
205
VALUE
tok
,
VALUE
val,
int
resume));
206
static
void
extract_user_token
_
((
struct
cparse_params
*
v
,
207
VALUE
block_args,
VALUE
*
tok
,
VALUE
*val));
208
static
void
shift
_
((
struct
cparse_params
*
v
,
long
act,
VALUE
tok
,
VALUE
val));
209
static
int
reduce
_
((
struct
cparse_params
*
v
,
long
act));
210
static
VALUE
reduce0
_
((
VALUE
block_args,
VALUE
data,
VALUE
self
));
211
212
#ifdef DEBUG
213
# define D_puts(msg) if (v->sys_debug) puts(msg)
214
# define D_printf(fmt,arg) if (v->sys_debug) printf(fmt,arg)
215
#else
216
# define D_puts(msg)
217
# define D_printf(fmt,arg)
218
#endif
219
220
static
VALUE
221
racc_cparse
(
VALUE
parser,
VALUE
arg
,
VALUE
sysdebug)
222
{
223
volatile
VALUE
vparams;
224
struct
cparse_params
*
v
;
225
226
vparams =
Data_Make_Struct
(
CparseParams
,
struct
cparse_params
,
227
cparse_params_mark
, -1, v);
228
D_puts
(
"starting cparse"
);
229
v->
sys_debug
=
RTEST
(sysdebug);
230
vparams =
initialize_params
(vparams, parser, arg,
Qnil
,
Qnil
);
231
v->
lex_is_iterator
=
FALSE
;
232
parse_main
(v,
Qnil
,
Qnil
, 0);
233
234
return
v->
retval
;
235
}
236
237
static
VALUE
238
racc_yyparse
(
VALUE
parser
,
VALUE
lexer
,
VALUE
lexmid
,
VALUE
arg
,
VALUE
sysdebug)
239
{
240
volatile
VALUE
vparams;
241
struct
cparse_params
*
v
;
242
243
vparams =
Data_Make_Struct
(
CparseParams
,
struct
cparse_params
,
244
cparse_params_mark
, -1, v);
245
v->
sys_debug
=
RTEST
(sysdebug);
246
D_puts
(
"start C yyparse"
);
247
vparams =
initialize_params
(vparams, parser, arg, lexer, lexmid);
248
v->
lex_is_iterator
=
TRUE
;
249
D_puts
(
"params initialized"
);
250
parse_main
(v,
Qnil
,
Qnil
, 0);
251
call_lexer
(v);
252
if
(!v->
fin
) {
253
rb_raise
(
rb_eArgError
,
"%s() is finished before EndOfToken"
,
254
rb_id2name
(v->
lexmid
));
255
}
256
257
return
v->
retval
;
258
}
259
260
#ifdef HAVE_RB_BLOCK_CALL
261
static
void
262
call_lexer
(
struct
cparse_params
*
v
)
263
{
264
rb_block_call
(v->
lexer
, v->
lexmid
, 0, NULL,
lexer_i
, v->
value_v
);
265
}
266
#else
267
static
VALUE
268
lexer_iter
(
VALUE
data)
269
{
270
struct
cparse_params
*
v
;
271
272
Data_Get_Struct
(data,
struct
cparse_params
, v);
273
rb_funcall
(v->
lexer
, v->
lexmid
, 0);
274
return
Qnil
;
275
}
276
277
static
void
278
call_lexer
(
struct
cparse_params
*
v
)
279
{
280
rb_iterate
(
lexer_iter
, v->
value_v
,
lexer_i
, v->
value_v
);
281
}
282
#endif
283
284
static
VALUE
285
lexer_i
(
VALUE
block_args,
VALUE
data,
VALUE
self
)
286
{
287
struct
cparse_params
*
v
;
288
VALUE
tok
, val;
289
290
Data_Get_Struct
(data,
struct
cparse_params
, v);
291
if
(v->
fin
)
292
rb_raise
(
rb_eArgError
,
"extra token after EndOfToken"
);
293
extract_user_token
(v, block_args, &tok, &val);
294
parse_main
(v, tok, val, 1);
295
if
(v->
fin
&& v->
fin
!=
CP_FIN_ACCEPT
)
296
rb_iter_break
();
297
return
Qnil
;
298
}
299
300
static
VALUE
301
assert_array
(
VALUE
a)
302
{
303
Check_Type
(a,
T_ARRAY
);
304
return
a;
305
}
306
307
static
VALUE
308
assert_hash
(
VALUE
h)
309
{
310
Check_Type
(h,
T_HASH
);
311
return
h;
312
}
313
314
static
long
315
assert_integer
(
VALUE
n)
316
{
317
return
NUM2LONG
(n);
318
}
319
320
static
VALUE
321
initialize_params
(
VALUE
vparams,
VALUE
parser
,
VALUE
arg
,
VALUE
lexer
,
VALUE
lexmid
)
322
{
323
struct
cparse_params
*
v
;
324
325
Data_Get_Struct
(vparams,
struct
cparse_params
, v);
326
v->
value_v
= vparams;
327
v->
parser
=
parser
;
328
v->
lexer
=
lexer
;
329
if
(!
NIL_P
(lexmid))
330
v->
lexmid
=
value_to_id
(lexmid);
331
332
v->
debug
=
RTEST
(
rb_ivar_get
(parser,
id_yydebug
));
333
334
Check_Type
(arg,
T_ARRAY
);
335
if
(!(13 <=
RARRAY_LEN
(arg) &&
RARRAY_LEN
(arg) <= 14))
336
rb_raise
(
RaccBug
,
"[Racc Bug] wrong arg.size %ld"
,
RARRAY_LEN
(arg));
337
v->
action_table
=
assert_array
(
RARRAY_PTR
(arg)[ 0]);
338
v->
action_check
=
assert_array
(
RARRAY_PTR
(arg)[ 1]);
339
v->
action_default
=
assert_array
(
RARRAY_PTR
(arg)[ 2]);
340
v->
action_pointer
=
assert_array
(
RARRAY_PTR
(arg)[ 3]);
341
v->
goto_table
=
assert_array
(
RARRAY_PTR
(arg)[ 4]);
342
v->
goto_check
=
assert_array
(
RARRAY_PTR
(arg)[ 5]);
343
v->
goto_default
=
assert_array
(
RARRAY_PTR
(arg)[ 6]);
344
v->
goto_pointer
=
assert_array
(
RARRAY_PTR
(arg)[ 7]);
345
v->
nt_base
=
assert_integer
(
RARRAY_PTR
(arg)[ 8]);
346
v->
reduce_table
=
assert_array
(
RARRAY_PTR
(arg)[ 9]);
347
v->
token_table
=
assert_hash
(
RARRAY_PTR
(arg)[10]);
348
v->
shift_n
=
assert_integer
(
RARRAY_PTR
(arg)[11]);
349
v->
reduce_n
=
assert_integer
(
RARRAY_PTR
(arg)[12]);
350
if
(
RARRAY_LEN
(arg) > 13) {
351
v->
use_result_var
=
RTEST
(
RARRAY_PTR
(arg)[13]);
352
}
353
else
{
354
v->
use_result_var
=
TRUE
;
355
}
356
357
v->
tstack
= v->
debug
?
NEW_STACK
() :
Qnil
;
358
v->
vstack
=
NEW_STACK
();
359
v->
state
=
NEW_STACK
();
360
v->
curstate
= 0;
361
PUSH
(v->
state
,
INT2FIX
(0));
362
v->
t
=
INT2FIX
(
FINAL_TOKEN
+ 1);
/* must not init to FINAL_TOKEN */
363
v->
nerr
= 0;
364
v->
errstatus
= 0;
365
rb_ivar_set
(parser,
id_errstatus
,
LONG2NUM
(v->
errstatus
));
366
367
v->
retval
=
Qnil
;
368
v->
fin
= 0;
369
370
v->
lex_is_iterator
=
FALSE
;
371
372
rb_iv_set
(parser,
"@vstack"
, v->
vstack
);
373
if
(v->
debug
) {
374
rb_iv_set
(parser,
"@tstack"
, v->
tstack
);
375
}
376
else
{
377
rb_iv_set
(parser,
"@tstack"
,
Qnil
);
378
}
379
380
return
vparams;
381
}
382
383
static
void
384
cparse_params_mark
(
void
*ptr)
385
{
386
struct
cparse_params
*
v
= (
struct
cparse_params
*)ptr;
387
388
rb_gc_mark
(v->
value_v
);
389
rb_gc_mark
(v->
parser
);
390
rb_gc_mark
(v->
lexer
);
391
rb_gc_mark
(v->
action_table
);
392
rb_gc_mark
(v->
action_check
);
393
rb_gc_mark
(v->
action_default
);
394
rb_gc_mark
(v->
action_pointer
);
395
rb_gc_mark
(v->
goto_table
);
396
rb_gc_mark
(v->
goto_check
);
397
rb_gc_mark
(v->
goto_default
);
398
rb_gc_mark
(v->
goto_pointer
);
399
rb_gc_mark
(v->
reduce_table
);
400
rb_gc_mark
(v->
token_table
);
401
rb_gc_mark
(v->
state
);
402
rb_gc_mark
(v->
vstack
);
403
rb_gc_mark
(v->
tstack
);
404
rb_gc_mark
(v->
t
);
405
rb_gc_mark
(v->
retval
);
406
}
407
408
static
void
409
extract_user_token
(
struct
cparse_params
*
v
,
VALUE
block_args,
410
VALUE
*
tok
,
VALUE
*val)
411
{
412
if
(
NIL_P
(block_args)) {
413
/* EOF */
414
*tok =
Qfalse
;
415
*val =
rb_str_new
(
"$"
, 1);
416
return
;
417
}
418
419
if
(
TYPE
(block_args) !=
T_ARRAY
) {
420
rb_raise
(
rb_eTypeError
,
421
"%s() %s %s (must be Array[2])"
,
422
v->
lex_is_iterator
?
rb_id2name
(v->
lexmid
) :
"next_token"
,
423
v->
lex_is_iterator
?
"yielded"
:
"returned"
,
424
rb_class2name
(
CLASS_OF
(block_args)));
425
}
426
if
(
RARRAY_LEN
(block_args) != 2) {
427
rb_raise
(
rb_eArgError
,
428
"%s() %s wrong size of array (%ld for 2)"
,
429
v->
lex_is_iterator
?
rb_id2name
(v->
lexmid
) :
"next_token"
,
430
v->
lex_is_iterator
?
"yielded"
:
"returned"
,
431
RARRAY_LEN
(block_args));
432
}
433
*tok =
AREF
(block_args, 0);
434
*val =
AREF
(block_args, 1);
435
}
436
437
#define SHIFT(v,act,tok,val) shift(v,act,tok,val)
438
#define REDUCE(v,act) do {\
439
switch (reduce(v,act)) { \
440
case 0:
/* normal */
\
441
break; \
442
case 1:
/* yyerror */
\
443
goto user_yyerror; \
444
case 2:
/* yyaccept */
\
445
D_puts("u accept"); \
446
goto accept; \
447
default: \
448
break; \
449
} \
450
} while (0)
451
452
static
void
453
parse_main
(
struct
cparse_params
*
v
,
VALUE
tok
,
VALUE
val,
int
resume)
454
{
455
long
i
;
/* table index */
456
long
act;
/* action type */
457
VALUE
act_value;
/* action type, VALUE version */
458
int
read_next = 1;
/* true if we need to read next token */
459
VALUE
tmp;
460
461
if
(resume)
462
goto
resume;
463
464
while
(1) {
465
D_puts
(
""
);
466
D_puts
(
"---- enter new loop ----"
);
467
D_puts
(
""
);
468
469
D_printf
(
"(act) k1=%ld\n"
, v->
curstate
);
470
tmp =
AREF
(v->
action_pointer
, v->
curstate
);
471
if
(
NIL_P
(tmp))
goto
notfound;
472
D_puts
(
"(act) pointer[k1] ok"
);
473
i =
NUM2LONG
(tmp);
474
475
D_printf
(
"read_next=%d\n"
, read_next);
476
if
(read_next && (v->
t
!=
vFINAL_TOKEN
)) {
477
if
(v->
lex_is_iterator
) {
478
D_puts
(
"resuming..."
);
479
if
(v->
fin
)
rb_raise
(
rb_eArgError
,
"token given after EOF"
);
480
v->
i
=
i
;
/* save i */
481
return
;
482
resume:
483
D_puts
(
"resumed"
);
484
i = v->
i
;
/* load i */
485
}
486
else
{
487
D_puts
(
"next_token"
);
488
tmp =
rb_funcall
(v->
parser
,
id_nexttoken
, 0);
489
extract_user_token
(v, tmp, &tok, &val);
490
}
491
/* convert token */
492
v->
t
=
rb_hash_aref
(v->
token_table
, tok);
493
if
(
NIL_P
(v->
t
)) {
494
v->
t
=
vERROR_TOKEN
;
495
}
496
D_printf
(
"(act) t(k2)=%ld\n"
,
NUM2LONG
(v->
t
));
497
if
(v->
debug
) {
498
rb_funcall
(v->
parser
,
id_d_read_token
,
499
3, v->
t
, tok, val);
500
}
501
}
502
read_next = 0;
503
504
i +=
NUM2LONG
(v->
t
);
505
D_printf
(
"(act) i=%ld\n"
, i);
506
if
(i < 0)
goto
notfound;
507
508
act_value =
AREF
(v->
action_table
, i);
509
if
(
NIL_P
(act_value))
goto
notfound;
510
act =
NUM2LONG
(act_value);
511
D_printf
(
"(act) table[i]=%ld\n"
, act);
512
513
tmp =
AREF
(v->
action_check
, i);
514
if
(
NIL_P
(tmp))
goto
notfound;
515
if
(
NUM2LONG
(tmp) != v->
curstate
)
goto
notfound;
516
D_printf
(
"(act) check[i]=%ld\n"
,
NUM2LONG
(tmp));
517
518
D_puts
(
"(act) found"
);
519
act_fixed:
520
D_printf
(
"act=%ld\n"
, act);
521
goto
handle_act;
522
523
notfound:
524
D_puts
(
"(act) not found: use default"
);
525
act_value =
AREF
(v->
action_default
, v->
curstate
);
526
act =
NUM2LONG
(act_value);
527
goto
act_fixed;
528
529
530
handle_act:
531
if
(act > 0 && act < v->
shift_n
) {
532
D_puts
(
"shift"
);
533
if
(v->
errstatus
> 0) {
534
v->
errstatus
--;
535
rb_ivar_set
(v->
parser
,
id_errstatus
,
LONG2NUM
(v->
errstatus
));
536
}
537
SHIFT
(v, act, v->
t
, val);
538
read_next = 1;
539
}
540
else
if
(act < 0 && act > -(v->
reduce_n
)) {
541
D_puts
(
"reduce"
);
542
REDUCE
(v, act);
543
}
544
else
if
(act == -(v->
reduce_n
)) {
545
goto
error;
546
error_recovered:
547
;
/* goto label requires stmt */
548
}
549
else
if
(act == v->
shift_n
) {
550
D_puts
(
"accept"
);
551
goto
accept;
552
}
553
else
{
554
rb_raise
(
RaccBug
,
"[Racc Bug] unknown act value %ld"
, act);
555
}
556
557
if
(v->
debug
) {
558
rb_funcall
(v->
parser
,
id_d_next_state
,
559
2,
LONG2NUM
(v->
curstate
), v->
state
);
560
}
561
}
562
/* not reach */
563
564
565
accept:
566
if
(v->
debug
)
rb_funcall
(v->
parser
,
id_d_accept
, 0);
567
v->
retval
=
RARRAY_PTR
(v->
vstack
)[0];
568
v->
fin
=
CP_FIN_ACCEPT
;
569
return
;
570
571
572
error:
573
D_printf
(
"error detected, status=%ld\n"
, v->
errstatus
);
574
if
(v->
errstatus
== 0) {
575
v->
nerr
++;
576
rb_funcall
(v->
parser
,
id_onerror
,
577
3, v->
t
, val, v->
vstack
);
578
}
579
user_yyerror:
580
if
(v->
errstatus
== 3) {
581
if
(v->
t
==
vFINAL_TOKEN
) {
582
v->
retval
=
Qfalse
;
583
v->
fin
=
CP_FIN_EOT
;
584
return
;
585
}
586
read_next = 1;
587
}
588
v->
errstatus
= 3;
589
rb_ivar_set
(v->
parser
,
id_errstatus
,
LONG2NUM
(v->
errstatus
));
590
591
/* check if we can shift/reduce error token */
592
D_printf
(
"(err) k1=%ld\n"
, v->
curstate
);
593
D_printf
(
"(err) k2=%d (error)\n"
,
ERROR_TOKEN
);
594
while
(1) {
595
tmp =
AREF
(v->
action_pointer
, v->
curstate
);
596
if
(
NIL_P
(tmp))
goto
error_pop;
597
D_puts
(
"(err) pointer[k1] ok"
);
598
599
i =
NUM2LONG
(tmp) +
ERROR_TOKEN
;
600
D_printf
(
"(err) i=%ld\n"
, i);
601
if
(i < 0)
goto
error_pop;
602
603
act_value =
AREF
(v->
action_table
, i);
604
if
(
NIL_P
(act_value)) {
605
D_puts
(
"(err) table[i] == nil"
);
606
goto
error_pop;
607
}
608
act =
NUM2LONG
(act_value);
609
D_printf
(
"(err) table[i]=%ld\n"
, act);
610
611
tmp =
AREF
(v->
action_check
, i);
612
if
(
NIL_P
(tmp)) {
613
D_puts
(
"(err) check[i] == nil"
);
614
goto
error_pop;
615
}
616
if
(
NUM2LONG
(tmp) != v->
curstate
) {
617
D_puts
(
"(err) check[i] != k1"
);
618
goto
error_pop;
619
}
620
621
D_puts
(
"(err) found: can handle error token"
);
622
break
;
623
624
error_pop:
625
D_puts
(
"(err) act not found: can't handle error token; pop"
);
626
627
if
(
RARRAY_LEN
(v->
state
) <= 1) {
628
v->
retval
=
Qnil
;
629
v->
fin
=
CP_FIN_CANTPOP
;
630
return
;
631
}
632
POP
(v->
state
);
633
POP
(v->
vstack
);
634
v->
curstate
=
num_to_long
(
LAST_I
(v->
state
));
635
if
(v->
debug
) {
636
POP
(v->
tstack
);
637
rb_funcall
(v->
parser
,
id_d_e_pop
,
638
3, v->
state
, v->
tstack
, v->
vstack
);
639
}
640
}
641
642
/* shift/reduce error token */
643
if
(act > 0 && act < v->
shift_n
) {
644
D_puts
(
"e shift"
);
645
SHIFT
(v, act,
ERROR_TOKEN
, val);
646
}
647
else
if
(act < 0 && act > -(v->
reduce_n
)) {
648
D_puts
(
"e reduce"
);
649
REDUCE
(v, act);
650
}
651
else
if
(act == v->
shift_n
) {
652
D_puts
(
"e accept"
);
653
goto
accept;
654
}
655
else
{
656
rb_raise
(
RaccBug
,
"[Racc Bug] unknown act value %ld"
, act);
657
}
658
goto
error_recovered;
659
}
660
661
static
void
662
shift
(
struct
cparse_params
*
v
,
long
act,
VALUE
tok
,
VALUE
val)
663
{
664
PUSH
(v->
vstack
, val);
665
if
(v->
debug
) {
666
PUSH
(v->
tstack
, tok);
667
rb_funcall
(v->
parser
,
id_d_shift
,
668
3, tok, v->
tstack
, v->
vstack
);
669
}
670
v->
curstate
= act;
671
PUSH
(v->
state
,
LONG2NUM
(v->
curstate
));
672
}
673
674
static
int
675
reduce
(
struct
cparse_params
*
v
,
long
act)
676
{
677
VALUE
code;
678
v->
ruleno
= -act * 3;
679
code =
rb_catch
(
"racc_jump"
,
reduce0
, v->
value_v
);
680
v->
errstatus
=
num_to_long
(
rb_ivar_get
(v->
parser
,
id_errstatus
));
681
return
NUM2INT
(code);
682
}
683
684
static
VALUE
685
reduce0
(
VALUE
val,
VALUE
data,
VALUE
self
)
686
{
687
struct
cparse_params
*
v
;
688
VALUE
reduce_to, reduce_len, method_id;
689
long
len
;
690
ID
mid;
691
VALUE
tmp, tmp_t =
Qundef
, tmp_v =
Qundef
;
692
long
i
, k1, k2;
693
VALUE
goto_state;
694
695
Data_Get_Struct
(data,
struct
cparse_params
, v);
696
reduce_len =
RARRAY_PTR
(v->
reduce_table
)[v->
ruleno
];
697
reduce_to =
RARRAY_PTR
(v->
reduce_table
)[v->
ruleno
+1];
698
method_id =
RARRAY_PTR
(v->
reduce_table
)[v->
ruleno
+2];
699
len =
NUM2LONG
(reduce_len);
700
mid =
value_to_id
(method_id);
701
702
/* call action */
703
if
(len == 0) {
704
tmp =
Qnil
;
705
if
(mid !=
id_noreduce
)
706
tmp_v =
rb_ary_new
();
707
if
(v->
debug
)
708
tmp_t =
rb_ary_new
();
709
}
710
else
{
711
if
(mid !=
id_noreduce
) {
712
tmp_v =
GET_TAIL
(v->
vstack
, len);
713
tmp =
RARRAY_PTR
(tmp_v)[0];
714
}
715
else
{
716
tmp =
RARRAY_PTR
(v->
vstack
)[
RARRAY_LEN
(v->
vstack
) -
len
];
717
}
718
CUT_TAIL
(v->
vstack
, len);
719
if
(v->
debug
) {
720
tmp_t =
GET_TAIL
(v->
tstack
, len);
721
CUT_TAIL
(v->
tstack
, len);
722
}
723
CUT_TAIL
(v->
state
, len);
724
}
725
if
(mid !=
id_noreduce
) {
726
if
(v->
use_result_var
) {
727
tmp =
rb_funcall
(v->
parser
, mid,
728
3, tmp_v, v->
vstack
, tmp);
729
}
730
else
{
731
tmp =
rb_funcall
(v->
parser
, mid,
732
2, tmp_v, v->
vstack
);
733
}
734
}
735
736
/* then push result */
737
PUSH
(v->
vstack
, tmp);
738
if
(v->
debug
) {
739
PUSH
(v->
tstack
, reduce_to);
740
rb_funcall
(v->
parser
,
id_d_reduce
,
741
4, tmp_t, reduce_to, v->
tstack
, v->
vstack
);
742
}
743
744
/* calculate transition state */
745
if
(
RARRAY_LEN
(v->
state
) == 0)
746
rb_raise
(
RaccBug
,
"state stack unexpectedly empty"
);
747
k2 =
num_to_long
(
LAST_I
(v->
state
));
748
k1 =
num_to_long
(reduce_to) - v->
nt_base
;
749
D_printf
(
"(goto) k1=%ld\n"
, k1);
750
D_printf
(
"(goto) k2=%ld\n"
, k2);
751
752
tmp =
AREF
(v->
goto_pointer
, k1);
753
if
(
NIL_P
(tmp))
goto
notfound;
754
755
i =
NUM2LONG
(tmp) + k2;
756
D_printf
(
"(goto) i=%ld\n"
, i);
757
if
(i < 0)
goto
notfound;
758
759
goto_state =
AREF
(v->
goto_table
, i);
760
if
(
NIL_P
(goto_state)) {
761
D_puts
(
"(goto) table[i] == nil"
);
762
goto
notfound;
763
}
764
D_printf
(
"(goto) table[i]=%ld (goto_state)\n"
,
NUM2LONG
(goto_state));
765
766
tmp =
AREF
(v->
goto_check
, i);
767
if
(
NIL_P
(tmp)) {
768
D_puts
(
"(goto) check[i] == nil"
);
769
goto
notfound;
770
}
771
if
(tmp !=
LONG2NUM
(k1)) {
772
D_puts
(
"(goto) check[i] != table[i]"
);
773
goto
notfound;
774
}
775
D_printf
(
"(goto) check[i]=%ld\n"
,
NUM2LONG
(tmp));
776
777
D_puts
(
"(goto) found"
);
778
transit:
779
PUSH
(v->
state
, goto_state);
780
v->
curstate
=
NUM2LONG
(goto_state);
781
return
INT2FIX
(0);
782
783
notfound:
784
D_puts
(
"(goto) not found: use default"
);
785
/* overwrite `goto-state' by default value */
786
goto_state =
AREF
(v->
goto_default
, k1);
787
goto
transit;
788
}
789
790
/* -----------------------------------------------------------------------
791
Ruby Interface
792
----------------------------------------------------------------------- */
793
794
void
795
Init_cparse
(
void
)
796
{
797
VALUE
Racc, Parser;
798
ID
id_racc =
rb_intern
(
"Racc"
);
799
800
if
(
rb_const_defined
(
rb_cObject
, id_racc)) {
801
Racc =
rb_const_get
(
rb_cObject
, id_racc);
802
Parser =
rb_const_get_at
(Racc,
rb_intern
(
"Parser"
));
803
}
804
else
{
805
Racc =
rb_define_module
(
"Racc"
);
806
Parser =
rb_define_class_under
(Racc,
"Parser"
,
rb_cObject
);
807
}
808
rb_define_private_method
(Parser,
"_racc_do_parse_c"
,
racc_cparse
, 2);
809
rb_define_private_method
(Parser,
"_racc_yyparse_c"
,
racc_yyparse
, 4);
810
rb_define_const
(Parser,
"Racc_Runtime_Core_Version_C"
,
811
rb_str_new2
(
RACC_VERSION
));
812
rb_define_const
(Parser,
"Racc_Runtime_Core_Id_C"
,
813
rb_str_new2
(
"$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $"
));
814
815
CparseParams
=
rb_define_class_under
(Racc,
"CparseParams"
,
rb_cObject
);
816
817
RaccBug
=
rb_eRuntimeError
;
818
819
id_yydebug
=
rb_intern
(
"@yydebug"
);
820
id_nexttoken
=
rb_intern
(
"next_token"
);
821
id_onerror
=
rb_intern
(
"on_error"
);
822
id_noreduce
=
rb_intern
(
"_reduce_none"
);
823
id_errstatus
=
rb_intern
(
"@racc_error_status"
);
824
825
id_d_shift
=
rb_intern
(
"racc_shift"
);
826
id_d_reduce
=
rb_intern
(
"racc_reduce"
);
827
id_d_accept
=
rb_intern
(
"racc_accept"
);
828
id_d_read_token
=
rb_intern
(
"racc_read_token"
);
829
id_d_next_state
=
rb_intern
(
"racc_next_state"
);
830
id_d_e_pop
=
rb_intern
(
"racc_e_pop"
);
831
}
832
Generated on Fri Nov 14 2014 16:04:01 for Ruby by
1.8.3