racc 1.7.1-java → 1.7.3-java

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