gd-racc 1.4.11

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