racc 1.4.9-java → 1.4.12-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b64b7450f28cdca4e407bd597d64e6a8b635e5f3
4
+ data.tar.gz: 5faf2ea06a588cc579f9339cdf299b29357af6cc
5
+ SHA512:
6
+ metadata.gz: 8a416cc7f06502eeb0677ddd5bd6f5e75c29702df58d3a0009de8ab36b38e68492a4429158b063c5bd82ece0e753b2cfdfc54bb9b46de980aa1f9cc3578195d0
7
+ data.tar.gz: 8dc5911addde1f6d98ee6bc2bc20ab78711e5d2e60bd424e584fb079d7525ec6c5b988876b13391ea82db5dea1b40355f42234a32e5fb5c2e06f2426907bd12f
data/Manifest.txt CHANGED
@@ -13,6 +13,7 @@ ext/racc/MANIFEST
13
13
  ext/racc/cparse.c
14
14
  ext/racc/depend
15
15
  ext/racc/extconf.rb
16
+ ext/racc/com/headius/racc/Cparse.java
16
17
  fastcache/extconf.rb
17
18
  fastcache/fastcache.c
18
19
  lib/racc.rb
@@ -34,12 +35,7 @@ lib/racc/statetransitiontable.rb
34
35
  lib/racc/static.rb
35
36
  misc/dist.sh
36
37
  rdoc/en/NEWS.en.rdoc
37
- rdoc/en/command.en.html
38
- rdoc/en/debug.en.rdoc
39
38
  rdoc/en/grammar.en.rdoc
40
- rdoc/en/index.en.html
41
- rdoc/en/parser.en.rdoc
42
- rdoc/en/usage.en.rdoc
43
39
  rdoc/ja/NEWS.ja.rdoc
44
40
  rdoc/ja/command.ja.html
45
41
  rdoc/ja/debug.ja.rdoc
data/Rakefile CHANGED
@@ -4,32 +4,48 @@ require 'rubygems'
4
4
  require 'hoe'
5
5
 
6
6
  gem 'rake-compiler', '>= 0.4.1'
7
- require "rake/extensiontask"
8
7
 
9
- Hoe.plugin :debugging, :doofus, :git, :isolate
8
+ Hoe.plugin :debugging, :doofus, :git, :isolate, :gemspec
10
9
 
11
- Hoe.spec 'racc' do
10
+ def java?
11
+ /java/ === RUBY_PLATFORM
12
+ end
13
+ def jruby?
14
+ 'jruby' == RUBY_ENGINE
15
+ end
16
+
17
+ HOE = Hoe.spec 'racc' do
12
18
  developer 'Aaron Patterson', 'aaron@tenderlovemaking.com'
19
+ license "MIT"
13
20
 
14
21
  self.extra_rdoc_files = Dir['*.rdoc']
15
22
  self.history_file = 'ChangeLog'
16
23
  self.readme_file = 'README.rdoc'
17
- self.testlib = :testunit
18
24
 
19
- extra_dev_deps << ['rake-compiler', '>= 0.4.1']
25
+ dependency 'rake-compiler', '>= 0.4.1', :developer
26
+ dependency 'minitest', '~> 4.7', :developer # stick to stdlib's version
20
27
 
21
- if RUBY_PLATFORM =~ /java/
22
- self.spec_extras = { :platform => 'java' }
28
+ if java?
29
+ self.spec_extras[:platform] = 'java'
23
30
  else
24
- self.spec_extras = {
25
- :extensions => ["ext/racc/extconf.rb"]
26
- }
31
+ self.spec_extras[:extensions] = %w[ext/racc/extconf.rb]
27
32
  end
28
33
 
29
- Rake::ExtensionTask.new "cparse", spec do |ext|
30
- ext.lib_dir = File.join 'lib', 'racc'
31
- ext.ext_dir = File.join 'ext', 'racc'
32
- end
34
+ self.clean_globs << "lib/#{self.name}/*.{so,bundle,dll,jar}" # from hoe/compiler
35
+
36
+ end
37
+
38
+ def add_file_to_gem relative_path
39
+ target_path = File.join gem_build_path, relative_path
40
+ target_dir = File.dirname(target_path)
41
+ mkdir_p target_dir unless File.directory?(target_dir)
42
+ rm_f target_path
43
+ safe_ln relative_path, target_path
44
+ HOE.spec.files += [relative_path]
45
+ end
46
+
47
+ def gem_build_path
48
+ File.join 'pkg', HOE.spec.full_name
33
49
  end
34
50
 
35
51
  file 'lib/racc/parser-text.rb' => ['lib/racc/parser.rb'] do |t|
@@ -46,6 +62,39 @@ end
46
62
  }
47
63
  end
48
64
 
49
- Hoe.add_include_dirs('.:lib/racc')
65
+ unless jruby?
66
+ # MRI
67
+ require "rake/extensiontask"
68
+ Rake::ExtensionTask.new "cparse", HOE.spec do |ext|
69
+ ext.lib_dir = File.join 'lib', 'racc'
70
+ ext.ext_dir = File.join 'ext', 'racc'
71
+ end
72
+
73
+ task :compile => 'lib/racc/parser-text.rb'
74
+ #
75
+ else
76
+ # JRUBY
77
+ require "rake/javaextensiontask"
78
+ Rake::JavaExtensionTask.new("cparse", HOE.spec) do |ext|
79
+ jruby_home = RbConfig::CONFIG['prefix']
80
+ ext.lib_dir = File.join 'lib', 'racc'
81
+ ext.ext_dir = File.join 'ext', 'racc'
82
+ # source/target jvm
83
+ ext.source_version = '1.6'
84
+ ext.target_version = '1.6'
85
+ jars = ["#{jruby_home}/lib/jruby.jar"] + FileList['lib/*.jar']
86
+ ext.classpath = jars.map { |x| File.expand_path x }.join( ':' )
87
+ ext.name = 'cparse-jruby'
88
+ end
89
+
90
+ task :compile => ['lib/racc/parser-text.rb']
50
91
 
51
- task :compile => 'lib/racc/parser-text.rb'
92
+ task gem_build_path => [:compile] do
93
+ add_file_to_gem 'lib/racc/cparse-jruby.jar'
94
+ end
95
+
96
+ end
97
+
98
+ task :test => :compile
99
+
100
+ Hoe.add_include_dirs('.:lib/racc')
@@ -0,0 +1,806 @@
1
+ package com.headius.racc;
2
+
3
+ import org.jruby.Ruby;
4
+ import org.jruby.RubyArray;
5
+ import org.jruby.RubyBasicObject;
6
+ import org.jruby.RubyClass;
7
+ import org.jruby.RubyContinuation;
8
+ import org.jruby.RubyFixnum;
9
+ import org.jruby.RubyHash;
10
+ import org.jruby.RubyModule;
11
+ import org.jruby.RubyNumeric;
12
+ import org.jruby.RubyObject;
13
+ import org.jruby.RubySymbol;
14
+ import org.jruby.anno.JRubyMethod;
15
+ import org.jruby.exceptions.JumpException;
16
+ import org.jruby.internal.runtime.methods.AttrReaderMethod;
17
+ import org.jruby.internal.runtime.methods.AttrWriterMethod;
18
+ import org.jruby.internal.runtime.methods.CallConfiguration;
19
+ import org.jruby.runtime.Arity;
20
+ import org.jruby.runtime.Block;
21
+ import org.jruby.runtime.BlockCallback;
22
+ import org.jruby.runtime.CallBlock19;
23
+ import org.jruby.runtime.CallSite;
24
+ import org.jruby.runtime.Helpers;
25
+ import org.jruby.runtime.MethodIndex;
26
+ import org.jruby.runtime.ObjectAllocator;
27
+ import org.jruby.runtime.ThreadContext;
28
+ import org.jruby.runtime.Visibility;
29
+ import org.jruby.runtime.builtin.IRubyObject;
30
+ import org.jruby.runtime.load.Library;
31
+
32
+ public class Cparse implements Library {
33
+ public static final String RACC_VERSION = "1.4.12"; // TODO: parse from Cparse.c
34
+
35
+ public enum TokenType {
36
+ DEFAULT(-1),
37
+ FINAL(0),
38
+ ERROR(1);
39
+
40
+ private final int id;
41
+ TokenType(int id) { this.id = id; }
42
+ }
43
+
44
+ private RubyFixnum vDEFAULT_TOKEN;
45
+ private RubyFixnum vERROR_TOKEN;
46
+ private RubyFixnum vFINAL_TOKEN;
47
+
48
+ private RubyClass RaccBug;
49
+ private RubyClass CparseParams;
50
+
51
+ private static final String ID_YYDEBUG = "@yydebug";
52
+ private static final String ID_NEXTTOKEN = "next_token";
53
+ private static final String ID_ONERROR = "on_error";
54
+ private static final String ID_NOREDUCE = "_reduce_none";
55
+ private static final String ID_ERRSTATUS = "@racc_error_status";
56
+
57
+ private static final String ID_D_SHIFT = "racc_shift";
58
+ private static final String ID_D_REDUCE = "racc_reduce";
59
+ private static final String ID_D_ACCEPT = "racc_accept";
60
+ private static final String ID_D_READ_TOKEN = "racc_read_token";
61
+ private static final String ID_D_NEXT_STATE = "racc_next_state";
62
+ private static final String ID_D_E_POP = "racc_e_pop";
63
+
64
+ private RubySymbol sym_noreduce;
65
+ private CallSite call_nexttoken;
66
+ private CallSite call_onerror;
67
+ private CallSite call_d_shift;
68
+ private CallSite call_d_reduce;
69
+ private CallSite call_d_accept;
70
+ private CallSite call_d_read_token;
71
+ private CallSite call_d_next_state;
72
+ private CallSite call_d_e_pop;
73
+ private AttrWriterMethod set_errstatus;
74
+ private AttrReaderMethod get_errstatus;
75
+
76
+ private static RubySymbol value_to_id(ThreadContext context, IRubyObject v) {
77
+ if (!(v instanceof RubySymbol)) {
78
+ throw context.runtime.newTypeError("not symbol");
79
+ }
80
+ return (RubySymbol)v;
81
+ }
82
+
83
+ private static int num_to_int(IRubyObject n) {
84
+ return assert_integer(n);
85
+ }
86
+
87
+ private static IRubyObject AREF(ThreadContext context, IRubyObject s, int idx) {
88
+ return ((0 <= idx && idx < ((RubyArray)s).size()) ? ((RubyArray)s).entry(idx) : context.nil);
89
+ }
90
+
91
+ private static IRubyObject get_stack_tail(ThreadContext context, RubyArray stack, int len) {
92
+ if (len < 0) return context.nil;
93
+ int size = stack.size();
94
+ len = Math.min(len, size);
95
+ return stack.subseq(size - len, len);
96
+ }
97
+
98
+ private static void cut_stack_tail(ThreadContext context, RubyArray stack, int len) {
99
+ while (len > 0) {
100
+ stack.pop(context);
101
+ len--;
102
+ }
103
+ }
104
+
105
+ private static final int STACK_INIT_LEN = 64;
106
+ private static RubyArray NEW_STACK(ThreadContext context) {
107
+ return context.runtime.newArray(STACK_INIT_LEN);
108
+ }
109
+ private static IRubyObject PUSH(RubyArray stack, IRubyObject i) {
110
+ return stack.append(i);
111
+ }
112
+ private static IRubyObject POP(ThreadContext context, RubyArray stack) {
113
+ return stack.pop(context);
114
+ }
115
+ private static IRubyObject LAST_I(ThreadContext context, RubyArray stack) {
116
+ return stack.size() > 0 ? stack.last() : context.nil;
117
+ }
118
+ private static IRubyObject GET_TAIL(ThreadContext context, RubyArray stack, int len) {
119
+ return get_stack_tail(context, stack, len);
120
+ }
121
+ private static void CUT_TAIL(ThreadContext context, RubyArray stack, int len) {
122
+ cut_stack_tail(context, stack, len);
123
+ }
124
+
125
+ static final int CP_FIN_ACCEPT = 1;
126
+ static final int CP_FIN_EOT = 2;
127
+ static final int CP_FIN_CANTPOP = 3;
128
+
129
+ public class CparseParams extends RubyObject {
130
+ public CparseParams(Ruby runtime, RubyClass rubyClass) {
131
+ super(runtime, rubyClass);
132
+ }
133
+
134
+ public void initialize_params(ThreadContext context, Parser parser, IRubyObject arg, IRubyObject lexer, IRubyObject lexmid) {
135
+ Ruby runtime = context.runtime;
136
+ this.parser = parser;
137
+ this.lexer = lexer;
138
+ if (!lexmid.isNil()) {
139
+ this.lexmid = value_to_id(context, lexmid);
140
+ this.call_lexmid = MethodIndex.getFunctionalCallSite(this.lexmid.toString());
141
+ }
142
+
143
+ this.debug = parser.getInstanceVariable(ID_YYDEBUG).isTrue();
144
+
145
+ RubyArray argAry = arg.convertToArray();
146
+ if (!(13 <= argAry.size() && argAry.size() <= 14)) {
147
+ throw runtime.newRaiseException(RaccBug, "[Racc Bug] wrong arg.size " + argAry.size());
148
+ }
149
+ this.action_table = assert_array(argAry.eltOk(0));
150
+ this.action_check = assert_array(argAry.eltOk(1));
151
+ this.action_default = assert_array(argAry.eltOk(2));
152
+ this.action_pointer = assert_array(argAry.eltOk(3));
153
+ this.goto_table = assert_array(argAry.eltOk(4));
154
+ this.goto_check = assert_array(argAry.eltOk(5));
155
+ this.goto_default = assert_array(argAry.eltOk(6));
156
+ this.goto_pointer = assert_array(argAry.eltOk(7));
157
+ this.nt_base = assert_integer(argAry.eltOk(8));
158
+ this.reduce_table = assert_array(argAry.eltOk(9));
159
+ this.token_table = assert_hash(argAry.eltOk(10));
160
+ this.shift_n = assert_integer(argAry.eltOk(11));
161
+ this.reduce_n = assert_integer(argAry.eltOk(12));
162
+ if (argAry.size() > 13) {
163
+ this.use_result_var = argAry.eltOk(13).isTrue();
164
+ } else {
165
+ this.use_result_var = true;
166
+ }
167
+
168
+ this.tstack = this.debug ? NEW_STACK(context) : null;
169
+ this.vstack = NEW_STACK(context);
170
+ this.state = NEW_STACK(context);
171
+ this.curstate = 0;
172
+ PUSH(this.state, RubyFixnum.zero(runtime));
173
+ this.t = runtime.newFixnum(TokenType.FINAL.id + 1); // must not init to FINAL_TOKEN
174
+ this.nerr = 0;
175
+ this.errstatus = 0;
176
+ set_errstatus.call(context, parser, parser.getMetaClass(), ID_ERRSTATUS, RubyNumeric.int2fix(runtime, this.errstatus));
177
+
178
+ this.retval = context.nil;
179
+ this.fin = 0;
180
+
181
+ this.lex_is_iterator = false;
182
+
183
+ parser.setInstanceVariable("@vstack", this.vstack);
184
+ if (this.debug) {
185
+ parser.setInstanceVariable("@tstack", this.tstack);
186
+ }
187
+ else {
188
+ parser.setInstanceVariable("@tstack", context.nil);
189
+ }
190
+ }
191
+
192
+ public void extract_user_token(ThreadContext context, IRubyObject block_args, IRubyObject[] tokVal) {
193
+ if (block_args.isNil()) {
194
+ /* EOF */
195
+ tokVal[0] = context.runtime.getFalse();
196
+ tokVal[1] = context.runtime.newString("$");
197
+ return;
198
+ }
199
+
200
+ if (!(block_args instanceof RubyArray)) {
201
+ throw context.runtime.newTypeError(
202
+ (lex_is_iterator ? lexmid.asJavaString() : "next_token") +
203
+ " " +
204
+ (lex_is_iterator ? "yielded" : "returned") +
205
+ " " +
206
+ block_args.getMetaClass().getName() +
207
+ " (must be Array[2])");
208
+ }
209
+ RubyArray block_args_ary = (RubyArray)block_args;
210
+ if (block_args_ary.size() != 2) {
211
+ throw context.runtime.newTypeError(
212
+ (lex_is_iterator ? lexmid.asJavaString() : "next_token") +
213
+ " " +
214
+ (lex_is_iterator ? "yielded" : "returned") +
215
+ " wrong size of array (" +
216
+ block_args_ary.size() +
217
+ " for 2)");
218
+ }
219
+ tokVal[0] = ((RubyArray) block_args).eltOk(0);
220
+ tokVal[1] = ((RubyArray) block_args).eltOk(1);
221
+ }
222
+
223
+ private static final int RESUME = 1;
224
+ private static final int NOTFOUND = 2;
225
+ private static final int ERROR_RECOVERED = 3;
226
+ private static final int ERROR = 4;
227
+ private static final int HANDLE_ACT = 5;
228
+ private static final int ACT_FIXED = 6;
229
+ private static final int ACCEPT = 7;
230
+ private static final int USER_YYERROR = 8;
231
+ private static final int ERROR_POP = 9;
232
+ private static final int TRANSIT = 9;
233
+
234
+ private void SHIFT(ThreadContext context, int act, IRubyObject tok, IRubyObject val) {
235
+ shift(context, act, tok, val);
236
+ }
237
+
238
+ private int REDUCE(ThreadContext context, int act) {
239
+ return reduce(context, act);
240
+ }
241
+
242
+ public void parse_main(ThreadContext context, IRubyObject tok, IRubyObject val, boolean resume) {
243
+ Ruby runtime = context.runtime;
244
+
245
+ int i = 0; /* table index */
246
+ int act = 0; /* action type */
247
+ IRubyObject act_value; /* action type, VALUE version */
248
+ boolean read_next = true; /* true if we need to read next token */
249
+ IRubyObject tmp;
250
+
251
+ int branch = 0;
252
+
253
+ if (resume) {
254
+ branch = RESUME;
255
+ }
256
+
257
+ BRANCH: while (true) {
258
+ switch (branch) {
259
+ case 0:
260
+
261
+ D_puts("");
262
+ D_puts("---- enter new loop ----");
263
+ D_puts("");
264
+
265
+ D_printf("(act) k1=%ld\n", this.curstate);
266
+ tmp = AREF(context, this.action_pointer, this.curstate);
267
+ if (tmp.isNil()) {branch = NOTFOUND; continue BRANCH;}
268
+ D_puts("(act) pointer[k1] ok");
269
+ i = assert_integer(tmp);
270
+
271
+ D_printf("read_next=%d\n", read_next);
272
+ if (read_next && (this.t != vFINAL_TOKEN)) {
273
+ if (this.lex_is_iterator) {
274
+ D_puts("resuming...");
275
+ if (this.fin != 0) throw runtime.newArgumentError("token given after EOF");
276
+ this.i = i; /* save i */
277
+ return;
278
+
279
+ // remainder of case duplicated from here for RESUME case
280
+ //D_puts(this, "resumed");
281
+ //i = this.i; /* load i */
282
+ }
283
+ else {
284
+ D_puts("next_token");
285
+ tmp = call_nexttoken.call(context, this.parser, this.parser);
286
+ IRubyObject[] tokVal = {tok, val};
287
+ extract_user_token(context, tmp, tokVal);
288
+ tok = tokVal[0];
289
+ val = tokVal[1];
290
+ }
291
+ /* convert token */
292
+ this.t = ((RubyHash)this.token_table).op_aref(context, tok);
293
+ if (this.t.isNil()) {
294
+ this.t = vERROR_TOKEN;
295
+ }
296
+ D_printf("(act) t(k2)=%ld\n", assert_integer(this.t));
297
+ if (this.debug) {
298
+ call_d_read_token.call(context, this.parser, this.parser, this.t, tok, val);
299
+ }
300
+ }
301
+
302
+ // duplicated logic from above for RESUME case
303
+ case RESUME:
304
+ if (branch == RESUME) {
305
+ D_puts("resumed");
306
+ i = this.i; /* load i */
307
+
308
+ /* convert token */
309
+ this.t = ((RubyHash)this.token_table).op_aref(context, tok);
310
+ if (this.t.isNil()) {
311
+ this.t = vERROR_TOKEN;
312
+ }
313
+ D_printf("(act) t(k2)=%ld\n", assert_integer(this.t));
314
+ if (this.debug) {
315
+ call_d_read_token.call(context, this.parser, this.parser, this.t, tok, val);
316
+ }
317
+ }
318
+
319
+ read_next = false;
320
+
321
+ i += assert_integer(this.t);
322
+ D_printf("(act) i=%ld\n", i);
323
+ if (i < 0) {branch = NOTFOUND; continue BRANCH;}
324
+
325
+ act_value = AREF(context, this.action_table, i);
326
+ if (act_value.isNil()) {branch = NOTFOUND; continue BRANCH;}
327
+ act = assert_integer(act_value);
328
+ D_printf("(act) table[i]=%ld\n", act);
329
+
330
+ tmp = AREF(context, this.action_check, i);
331
+ if (tmp.isNil()) {branch = NOTFOUND; continue BRANCH;}
332
+ if (assert_integer(tmp) != this.curstate) {branch = NOTFOUND; continue BRANCH;}
333
+ D_printf("(act) check[i]=%ld\n", assert_integer(tmp));
334
+
335
+ D_puts("(act) found");
336
+
337
+ case ACT_FIXED:
338
+ D_printf("act=%ld\n", act);
339
+ branch = HANDLE_ACT; continue BRANCH;
340
+
341
+ case NOTFOUND:
342
+ D_puts("(act) not found: use default");
343
+ act_value = AREF(context, this.action_default, this.curstate);
344
+ act = assert_integer(act_value);
345
+ branch = ACT_FIXED; continue BRANCH;
346
+
347
+ case HANDLE_ACT:
348
+ if (act > 0 && act < this.shift_n) {
349
+ D_puts("shift");
350
+ if (this.errstatus > 0) {
351
+ this.errstatus--;
352
+ set_errstatus.call(context, this.parser, this.parser.getMetaClass(), ID_ERRSTATUS, runtime.newFixnum(this.errstatus));
353
+ }
354
+ SHIFT(context, act, this.t, val);
355
+ read_next = true;
356
+ }
357
+ else if (act < 0 && act > -(this.reduce_n)) {
358
+ D_puts("reduce");
359
+ REDUCE(context, act);
360
+ }
361
+ else if (act == -(this.reduce_n)) {
362
+ branch = ERROR; continue BRANCH;
363
+ }
364
+ else if (act == this.shift_n) {
365
+ D_puts("accept");
366
+ branch = ACCEPT; continue BRANCH;
367
+ }
368
+ else {
369
+ throw runtime.newRaiseException(RaccBug, "[Cparse Bug] unknown act value " + act);
370
+ }
371
+
372
+ case ERROR_RECOVERED:
373
+
374
+ if (this.debug) {
375
+ call_d_next_state.call(context, this.parser, this.parser, runtime.newFixnum(this.curstate), this.state);
376
+ }
377
+ branch = 0; continue BRANCH;
378
+
379
+ /* not reach */
380
+
381
+ case ACCEPT:
382
+ if (this.debug) call_d_accept.call(context, this.parser, this.parser);
383
+ this.retval = this.vstack.eltOk(0);
384
+ this.fin = CP_FIN_ACCEPT;
385
+ return;
386
+
387
+ case ERROR:
388
+ D_printf("error detected, status=%ld\n", this.errstatus);
389
+ if (this.errstatus == 0) {
390
+ this.nerr++;
391
+ call_onerror.call(context, this.parser, this.parser, this.t, val, this.vstack);
392
+ }
393
+
394
+ case USER_YYERROR:
395
+ if (this.errstatus == 3) {
396
+ if (this.t == vFINAL_TOKEN) {
397
+ this.retval = runtime.getFalse();
398
+ this.fin = CP_FIN_EOT;
399
+ return;
400
+ }
401
+ read_next = true;
402
+ }
403
+ this.errstatus = 3;
404
+ set_errstatus.call(context, this.parser, this.parser.getMetaClass(), ID_ERRSTATUS, runtime.newFixnum(this.errstatus));
405
+
406
+ /* check if we can shift/reduce error token */
407
+ D_printf("(err) k1=%ld\n", this.curstate);
408
+ D_printf("(err) k2=%d (error)\n", TokenType.ERROR.id);
409
+
410
+ int branch2 = 0;
411
+
412
+ BRANCH2: while (true) {
413
+ switch (branch2) {
414
+ case 0:
415
+ tmp = AREF(context, this.action_pointer, this.curstate);
416
+ if (tmp.isNil()) {branch2 = ERROR_POP; continue BRANCH2;}
417
+ D_puts("(err) pointer[k1] ok");
418
+
419
+ i = assert_integer(tmp) + TokenType.ERROR.id;
420
+ D_printf("(err) i=%ld\n", i);
421
+ if (i < 0) {branch2 = ERROR_POP; continue BRANCH2;}
422
+
423
+ act_value = AREF(context, this.action_table, i);
424
+ if (act_value.isNil()) {
425
+ D_puts("(err) table[i] == nil");
426
+ branch2 = ERROR_POP; continue BRANCH2;
427
+ }
428
+ act = assert_integer(act_value);
429
+ D_printf("(err) table[i]=%ld\n", act);
430
+
431
+ tmp = AREF(context, this.action_check, i);
432
+ if (tmp.isNil()) {
433
+ D_puts("(err) check[i] == nil");
434
+ branch2 = ERROR_POP; continue BRANCH2;
435
+ }
436
+ if (assert_integer(tmp) != this.curstate) {
437
+ D_puts("(err) check[i] != k1");
438
+ branch2 = ERROR_POP; continue BRANCH2;
439
+ }
440
+
441
+ D_puts("(err) found: can handle error token");
442
+ break BRANCH2;
443
+
444
+ case ERROR_POP:
445
+ D_puts("(err) act not found: can't handle error token; pop");
446
+
447
+ if (this.state.size() <= 1) {
448
+ this.retval = context.nil;
449
+ this.fin = CP_FIN_CANTPOP;
450
+ return;
451
+ }
452
+ POP(context, this.state);
453
+ POP(context, this.vstack);
454
+ this.curstate = assert_integer(LAST_I(context, this.state));
455
+ if (this.debug) {
456
+ POP(context, this.tstack);
457
+ call_d_e_pop.call(context, this.parser, this.parser, this.state, this.tstack, this.vstack);
458
+ }
459
+ }
460
+ }
461
+
462
+ /* shift/reduce error token */
463
+ if (act > 0 && act < this.shift_n) {
464
+ D_puts("e shift");
465
+ SHIFT(context, act, runtime.newFixnum(TokenType.ERROR.id), val);
466
+ }
467
+ else if (act < 0 && act > -(this.reduce_n)) {
468
+ D_puts("e reduce");
469
+ REDUCE(context, act);
470
+ }
471
+ else if (act == this.shift_n) {
472
+ D_puts("e accept");
473
+ branch = ACCEPT; continue BRANCH;
474
+ }
475
+ else {
476
+ throw runtime.newRaiseException(RaccBug, "[Cparse Bug] unknown act value " + act);
477
+ }
478
+ branch = ERROR_RECOVERED; continue BRANCH;
479
+ }
480
+ }
481
+ }
482
+
483
+ private void shift(ThreadContext context, int act, IRubyObject tok, IRubyObject val) {
484
+ PUSH(vstack, val);
485
+ if (debug) {
486
+ PUSH(tstack, tok);
487
+ call_d_shift.call(context, this.parser, this.parser, tok, tstack, vstack);
488
+ }
489
+ curstate = act;
490
+ PUSH(state, context.runtime.newFixnum(curstate));
491
+ }
492
+
493
+ private int reduce(ThreadContext context, int act) {
494
+ IRubyObject code;
495
+ ruleno = -act * 3;
496
+ IRubyObject tag = context.runtime.newSymbol("racc_jump");
497
+ RubyContinuation rbContinuation = new RubyContinuation(context.runtime, context.runtime.newSymbol("racc_jump"));
498
+ try {
499
+ context.pushCatch(rbContinuation.getContinuation());
500
+ code = reduce0(context);
501
+ errstatus = assert_integer(get_errstatus.call(context, parser, parser.getMetaClass(), ID_ERRSTATUS));
502
+ } finally {
503
+ context.popCatch();
504
+ }
505
+ return assert_integer(code);
506
+ }
507
+
508
+ private IRubyObject reduce0(ThreadContext context) {
509
+ Ruby runtime = context.runtime;
510
+
511
+ IRubyObject reduce_to, reduce_len, method_id;
512
+ int len;
513
+ RubySymbol mid;
514
+ IRubyObject tmp, tmp_t = RubyBasicObject.UNDEF, tmp_v = RubyBasicObject.UNDEF;
515
+ int i, k1 = 0, k2;
516
+ IRubyObject goto_state = context.nil;
517
+
518
+ reduce_len = this.reduce_table.entry(this.ruleno);
519
+ reduce_to = this.reduce_table.entry(this.ruleno+1);
520
+ method_id = this.reduce_table.entry(this.ruleno+2);
521
+ len = assert_integer(reduce_len);
522
+ mid = value_to_id(context, method_id);
523
+
524
+ int branch = 0;
525
+ BRANCH: while (true) {
526
+ switch (branch) {
527
+ case 0:
528
+
529
+ /* call action */
530
+ if (len == 0) {
531
+ tmp = context.nil;
532
+ if (mid != sym_noreduce)
533
+ tmp_v = runtime.newArray();
534
+ if (this.debug)
535
+ tmp_t = runtime.newArray();
536
+ }
537
+ else {
538
+ if (mid != sym_noreduce) {
539
+ tmp_v = GET_TAIL(context, this.vstack, len);
540
+ tmp = ((RubyArray)tmp_v).entry(0);
541
+ }
542
+ else {
543
+ tmp = this.vstack.entry(this.vstack.size() - len);
544
+ }
545
+ CUT_TAIL(context, this.vstack, len);
546
+ if (this.debug) {
547
+ tmp_t = GET_TAIL(context, this.tstack, len);
548
+ CUT_TAIL(context, this.tstack, len);
549
+ }
550
+ CUT_TAIL(context, this.state, len);
551
+ }
552
+ if (mid != sym_noreduce) {
553
+ if (this.use_result_var) {
554
+ tmp = Helpers.invoke(context, this.parser, mid.toString(), tmp_v, this.vstack, tmp);
555
+ }
556
+ else {
557
+ tmp = Helpers.invoke(context, this.parser, mid.toString(), tmp_v, this.vstack);
558
+ }
559
+ }
560
+
561
+ /* then push result */
562
+ PUSH(this.vstack, tmp);
563
+ if (this.debug) {
564
+ PUSH(this.tstack, reduce_to);
565
+ call_d_reduce.call(context, this.parser, this.parser, tmp_t, reduce_to, this.tstack, this.vstack);
566
+ }
567
+
568
+ /* calculate transition state */
569
+ if (state.size() == 0)
570
+ throw runtime.newRaiseException(RaccBug, "state stack unexpectedly empty");
571
+ k2 = assert_integer(LAST_I(context, this.state));
572
+ k1 = assert_integer(reduce_to) - this.nt_base;
573
+ D_printf("(goto) k1=%ld\n", k1);
574
+ D_printf("(goto) k2=%ld\n", k2);
575
+
576
+ tmp = AREF(context, this.goto_pointer, k1);
577
+ if (tmp.isNil()) {branch = NOTFOUND; continue BRANCH;}
578
+
579
+ i = assert_integer(tmp) + k2;
580
+ D_printf("(goto) i=%ld\n", i);
581
+ if (i < 0) {branch = NOTFOUND; continue BRANCH;}
582
+
583
+ goto_state = AREF(context, this.goto_table, i);
584
+ if (goto_state.isNil()) {
585
+ D_puts("(goto) table[i] == nil");
586
+ branch = NOTFOUND; continue BRANCH;
587
+ }
588
+ D_printf("(goto) table[i]=%ld (goto_state)\n", goto_state.convertToInteger().getLongValue());
589
+
590
+ tmp = AREF(context, this.goto_check, i);
591
+ if (tmp.isNil()) {
592
+ D_puts("(goto) check[i] == nil");
593
+ branch = NOTFOUND; continue BRANCH;
594
+ }
595
+ if (tmp != runtime.newFixnum(k1)) {
596
+ D_puts("(goto) check[i] != table[i]");
597
+ branch = NOTFOUND; continue BRANCH;
598
+ }
599
+ D_printf("(goto) check[i]=%ld\n", tmp.convertToInteger().getLongValue());
600
+
601
+ D_puts("(goto) found");
602
+
603
+ case TRANSIT:
604
+ PUSH(this.state, goto_state);
605
+ this.curstate = assert_integer(goto_state);
606
+ return RubyFixnum.zero(runtime);
607
+
608
+ case NOTFOUND:
609
+ D_puts("(goto) not found: use default");
610
+ /* overwrite `goto-state' by default value */
611
+ goto_state = AREF(context, this.goto_default, k1);
612
+ branch = TRANSIT; continue BRANCH;
613
+ }
614
+ }
615
+ }
616
+
617
+ private void D_puts(String msg) {
618
+ if (sys_debug) {
619
+ System.out.println(msg);
620
+ }
621
+ }
622
+
623
+ private void D_printf(String fmt, long arg) {
624
+ if (sys_debug) {
625
+ System.out.println(fmt + ": " + arg);
626
+ }
627
+ }
628
+
629
+ private void D_printf(String fmt, boolean arg) {
630
+ if (sys_debug) {
631
+ System.out.println(fmt + ": " + arg);
632
+ }
633
+ }
634
+
635
+ Parser parser; /* parser object */
636
+
637
+ boolean lex_is_iterator;
638
+ IRubyObject lexer; /* scanner object */
639
+ RubySymbol lexmid; /* name of scanner method (must be an iterator) */
640
+ CallSite call_lexmid; /* call site for scanner method */
641
+
642
+ /* State transition tables (immutable)
643
+ Data structure is from Dragon Book 4.9 */
644
+ /* action table */
645
+ IRubyObject action_table;
646
+ IRubyObject action_check;
647
+ IRubyObject action_default;
648
+ IRubyObject action_pointer;
649
+ /* goto table */
650
+ IRubyObject goto_table;
651
+ IRubyObject goto_check;
652
+ IRubyObject goto_default;
653
+ IRubyObject goto_pointer;
654
+
655
+ int nt_base; /* NonTerminal BASE index */
656
+ RubyArray reduce_table; /* reduce data table */
657
+ IRubyObject token_table; /* token conversion table */
658
+
659
+ /* parser stacks and parameters */
660
+ RubyArray state;
661
+ int curstate;
662
+ RubyArray vstack;
663
+ RubyArray tstack;
664
+ IRubyObject t;
665
+ int shift_n;
666
+ int reduce_n;
667
+ int ruleno;
668
+
669
+ int errstatus; /* nonzero in error recovering mode */
670
+ int nerr; /* number of error */
671
+
672
+ boolean use_result_var;
673
+
674
+ IRubyObject retval; /* return IRubyObject of parser routine */
675
+ int fin; /* parse result status */
676
+
677
+ boolean debug; /* user level debug */
678
+ boolean sys_debug; /* system level debug */
679
+
680
+ int i; /* table index */
681
+ }
682
+
683
+ private static RubyArray assert_array(IRubyObject a) {
684
+ return a.convertToArray();
685
+ }
686
+
687
+ private static RubyHash assert_hash(IRubyObject h) {
688
+ return h.convertToHash();
689
+ }
690
+
691
+ private static int assert_integer(IRubyObject i) {
692
+ return (int)i.convertToInteger().getLongValue();
693
+ }
694
+
695
+ public class Parser extends RubyObject {
696
+ public Parser(Ruby runtime, RubyClass rubyClass) {
697
+ super(runtime, rubyClass);
698
+ }
699
+
700
+ public static final String Racc_Runtime_Core_Version_C = RACC_VERSION;
701
+ public static final String Racc_Runtime_Core_Id_C = "$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $";
702
+
703
+ @JRubyMethod(name = "_racc_do_parse_c", frame = true)
704
+ public IRubyObject racc_cparse(ThreadContext context, IRubyObject arg, IRubyObject sysdebug) {
705
+ CparseParams v = new CparseParams(context.runtime, CparseParams);
706
+
707
+ v.D_puts("starting cparse");
708
+ v.sys_debug = sysdebug.isTrue();
709
+ v.initialize_params(context, this, arg, context.nil, context.nil);
710
+ v.lex_is_iterator = false;
711
+ v.parse_main(context, context.nil, context.nil, false);
712
+
713
+ return v.retval;
714
+ }
715
+
716
+ @JRubyMethod(name = "_racc_yyparse_c", frame = true, required = 4)
717
+ public IRubyObject racc_yyparse(ThreadContext context, IRubyObject[] args) {
718
+ Ruby runtime = context.runtime;
719
+ CparseParams v = new CparseParams(context.runtime, CparseParams);
720
+
721
+ IRubyObject lexer = args[0], lexmid = args[1], arg = args[2], sysdebug = args[3];
722
+
723
+ v.sys_debug = sysdebug.isTrue();
724
+ v.D_puts("start C yyparse");
725
+ v.initialize_params(context, this, arg, lexer, lexmid);
726
+ v.lex_is_iterator = true;
727
+ v.D_puts("params initialized");
728
+ v.parse_main(context, context.nil, context.nil, false);
729
+ call_lexer(context, v);
730
+ if (v.fin == 0) {
731
+ throw runtime.newArgumentError(v.lexmid + " is finished before EndOfToken");
732
+ }
733
+
734
+ return v.retval;
735
+ }
736
+
737
+ private void call_lexer(ThreadContext context, final CparseParams v) {
738
+ final int frame = context.getFrameJumpTarget();
739
+ try {
740
+ v.call_lexmid.call(context, v.lexer, v.lexer, CallBlock19.newCallClosure(v, v.getMetaClass(), Arity.ONE_ARGUMENT, new BlockCallback() {
741
+ @Override
742
+ public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) {
743
+ Ruby runtime = context.getRuntime();
744
+ if (v.fin != 0) {
745
+ throw runtime.newArgumentError("extra token after EndOfToken");
746
+ }
747
+ IRubyObject[] tokVal = {null, null};
748
+ v.extract_user_token(context, args[0], tokVal);
749
+ v.parse_main(context, tokVal[0], tokVal[1], true);
750
+ if (v.fin != 0 && v.fin != CP_FIN_ACCEPT) {
751
+ throw new JumpException.BreakJump(frame, context.nil);
752
+ }
753
+
754
+ return context.nil;
755
+ }
756
+ }, context));
757
+ } catch (JumpException.BreakJump bj) {
758
+ if (bj.getTarget() == frame) {
759
+ return;
760
+ }
761
+ }
762
+ }
763
+ }
764
+
765
+ public void load(Ruby runtime, boolean wrap) {
766
+ RubyModule racc = runtime.getOrCreateModule("Racc");
767
+ RubyClass parser = racc.defineOrGetClassUnder("Parser", runtime.getObject());
768
+ parser.setAllocator(new ObjectAllocator() {
769
+ @Override
770
+ public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
771
+ return new Parser(ruby, rubyClass);
772
+ }
773
+ });
774
+
775
+ parser.defineAnnotatedMethods(Parser.class);
776
+
777
+ parser.defineConstant("Racc_Runtime_Core_Version_C", runtime.newString(Parser.Racc_Runtime_Core_Version_C));
778
+ parser.defineConstant("Racc_Runtime_Core_Id_C", runtime.newString(Parser.Racc_Runtime_Core_Id_C));
779
+
780
+ CparseParams = racc.defineClassUnder("CparseParams", runtime.getObject(), new ObjectAllocator() {
781
+ @Override
782
+ public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
783
+ return new CparseParams(ruby, rubyClass);
784
+ }
785
+ });
786
+
787
+ RaccBug = runtime.getRuntimeError();
788
+ sym_noreduce = runtime.newSymbol(ID_NOREDUCE);
789
+ call_nexttoken = MethodIndex.getFunctionalCallSite(ID_NEXTTOKEN);
790
+ call_onerror = MethodIndex.getFunctionalCallSite(ID_ONERROR);
791
+ call_d_shift = MethodIndex.getFunctionalCallSite(ID_D_SHIFT);
792
+ call_d_reduce = MethodIndex.getFunctionalCallSite(ID_D_REDUCE);
793
+ call_d_accept = MethodIndex.getFunctionalCallSite(ID_D_ACCEPT);
794
+ call_d_read_token = MethodIndex.getFunctionalCallSite(ID_D_READ_TOKEN);
795
+ call_d_next_state = MethodIndex.getFunctionalCallSite(ID_D_NEXT_STATE);
796
+ call_d_e_pop = MethodIndex.getFunctionalCallSite(ID_D_E_POP);
797
+
798
+ // hacky utility for caching instance var accessor
799
+ set_errstatus = new AttrWriterMethod(parser, Visibility.PUBLIC, CallConfiguration.FrameNoneScopeNone, ID_ERRSTATUS);
800
+ get_errstatus = new AttrReaderMethod(parser, Visibility.PUBLIC, CallConfiguration.FrameNoneScopeNone, ID_ERRSTATUS);
801
+
802
+ vDEFAULT_TOKEN = runtime.newFixnum(TokenType.DEFAULT.id);
803
+ vERROR_TOKEN = runtime.newFixnum(TokenType.ERROR.id);
804
+ vFINAL_TOKEN = runtime.newFixnum(TokenType.FINAL.id);
805
+ }
806
+ }