[DRE-commits] [racc] 01/09: Imported Upstream version 1.4.12

Sebastien Badia sbadia-guest at moszumanska.debian.org
Wed Aug 19 15:42:57 UTC 2015


This is an automated email from the git hooks/post-receive script.

sbadia-guest pushed a commit to branch master
in repository racc.

commit 6113622d9820cfca2e37d65b4fab2cefaaf20a69
Author: Sebastien Badia <seb at sebian.fr>
Date:   Wed Sep 3 21:13:52 2014 +0200

    Imported Upstream version 1.4.12
---
 Manifest.txt                          |   6 +-
 Rakefile                              |  81 +++-
 ext/racc/com/headius/racc/Cparse.java | 806 ++++++++++++++++++++++++++++++++++
 ext/racc/cparse.c                     |  52 ++-
 ext/racc/extconf.rb                   |   4 +-
 lib/racc/compat.rb                    |  10 +-
 lib/racc/grammarfileparser.rb         |   4 +-
 lib/racc/info.rb                      |   4 +-
 lib/racc/parser-text.rb               | 257 +++++++++--
 lib/racc/parser.rb                    | 257 +++++++++--
 lib/racc/parserfilegenerator.rb       |   4 +-
 metadata.yml                          |  83 ++--
 rdoc/en/command.en.html               |  78 ----
 rdoc/en/debug.en.rdoc                 |  20 -
 rdoc/en/index.en.html                 |  10 -
 rdoc/en/parser.en.rdoc                |  74 ----
 rdoc/en/usage.en.html                 |  92 ----
 test/helper.rb                        |  10 +-
 test/test_chk_y.rb                    |  14 +-
 test/test_scan_y.rb                   |  14 +-
 20 files changed, 1427 insertions(+), 453 deletions(-)

diff --git a/Manifest.txt b/Manifest.txt
index 63bad7b..d77dfca 100644
--- a/Manifest.txt
+++ b/Manifest.txt
@@ -13,6 +13,7 @@ ext/racc/MANIFEST
 ext/racc/cparse.c
 ext/racc/depend
 ext/racc/extconf.rb
+ext/racc/com/headius/racc/Cparse.java
 fastcache/extconf.rb
 fastcache/fastcache.c
 lib/racc.rb
@@ -34,12 +35,7 @@ lib/racc/statetransitiontable.rb
 lib/racc/static.rb
 misc/dist.sh
 rdoc/en/NEWS.en.rdoc
-rdoc/en/command.en.html
-rdoc/en/debug.en.rdoc
 rdoc/en/grammar.en.rdoc
-rdoc/en/index.en.html
-rdoc/en/parser.en.rdoc
-rdoc/en/usage.en.html
 rdoc/ja/NEWS.ja.rdoc
 rdoc/ja/command.ja.html
 rdoc/ja/debug.ja.rdoc
diff --git a/Rakefile b/Rakefile
index d456c3c..0edf695 100644
--- a/Rakefile
+++ b/Rakefile
@@ -4,28 +4,48 @@ require 'rubygems'
 require 'hoe'
 
 gem 'rake-compiler', '>= 0.4.1'
-require "rake/extensiontask"
 
-Hoe.plugin :debugging, :doofus, :git, :isolate
+Hoe.plugin :debugging, :doofus, :git, :isolate, :gemspec
 
-Hoe.spec 'racc' do
+def java?
+  /java/ === RUBY_PLATFORM
+end
+def jruby?
+  'jruby' == RUBY_ENGINE
+end
+
+HOE = Hoe.spec 'racc' do
   developer 'Aaron Patterson', 'aaron at tenderlovemaking.com'
+  license "MIT"
 
   self.extra_rdoc_files  = Dir['*.rdoc']
   self.history_file      = 'ChangeLog'
   self.readme_file       = 'README.rdoc'
-  self.testlib           = :minitest
 
-  extra_dev_deps << ['rake-compiler', '>= 0.4.1']
+  dependency 'rake-compiler', '>= 0.4.1', :developer
+  dependency 'minitest',      '~> 4.7',   :developer # stick to stdlib's version
 
-  self.spec_extras = {
-    :extensions            => ["ext/racc/extconf.rb"]
-  }
-
-  Rake::ExtensionTask.new "cparse", spec do |ext|
-    ext.lib_dir = File.join 'lib', 'racc'
-    ext.ext_dir = File.join 'ext', 'racc'
+  if java?
+    self.spec_extras[:platform]   = 'java'
+  else
+    self.spec_extras[:extensions] = %w[ext/racc/extconf.rb]
   end
+
+  self.clean_globs << "lib/#{self.name}/*.{so,bundle,dll,jar}" # from hoe/compiler
+
+end
+
+def add_file_to_gem relative_path
+  target_path = File.join gem_build_path, relative_path
+  target_dir = File.dirname(target_path)
+  mkdir_p target_dir unless File.directory?(target_dir)
+  rm_f target_path
+  safe_ln relative_path, target_path
+  HOE.spec.files += [relative_path]
+end
+
+def gem_build_path
+  File.join 'pkg', HOE.spec.full_name
 end
 
 file 'lib/racc/parser-text.rb' => ['lib/racc/parser.rb'] do |t|
@@ -42,6 +62,39 @@ end
   }
 end
 
-Hoe.add_include_dirs('.:lib/psych')
+unless jruby?
+  # MRI
+  require "rake/extensiontask"
+  Rake::ExtensionTask.new "cparse", HOE.spec do |ext|
+    ext.lib_dir = File.join 'lib', 'racc'
+    ext.ext_dir = File.join 'ext', 'racc'
+  end
+
+  task :compile => 'lib/racc/parser-text.rb'
+  #
+else
+  # JRUBY
+  require "rake/javaextensiontask"
+  Rake::JavaExtensionTask.new("cparse", HOE.spec) do |ext|
+    jruby_home = RbConfig::CONFIG['prefix']
+    ext.lib_dir = File.join 'lib', 'racc'
+    ext.ext_dir = File.join 'ext', 'racc'
+    # source/target jvm
+    ext.source_version = '1.6'
+    ext.target_version = '1.6'
+    jars = ["#{jruby_home}/lib/jruby.jar"] + FileList['lib/*.jar']
+    ext.classpath = jars.map { |x| File.expand_path x }.join( ':' )
+    ext.name = 'cparse-jruby'
+  end
+
+  task :compile => ['lib/racc/parser-text.rb']
+
+  task gem_build_path => [:compile] do
+    add_file_to_gem 'lib/racc/cparse-jruby.jar'
+  end
+
+end
+
+task :test => :compile
 
-task :compile => 'lib/racc/parser-text.rb'
+Hoe.add_include_dirs('.:lib/racc')
diff --git a/ext/racc/com/headius/racc/Cparse.java b/ext/racc/com/headius/racc/Cparse.java
new file mode 100644
index 0000000..714a72c
--- /dev/null
+++ b/ext/racc/com/headius/racc/Cparse.java
@@ -0,0 +1,806 @@
+package com.headius.racc;
+
+import org.jruby.Ruby;
+import org.jruby.RubyArray;
+import org.jruby.RubyBasicObject;
+import org.jruby.RubyClass;
+import org.jruby.RubyContinuation;
+import org.jruby.RubyFixnum;
+import org.jruby.RubyHash;
+import org.jruby.RubyModule;
+import org.jruby.RubyNumeric;
+import org.jruby.RubyObject;
+import org.jruby.RubySymbol;
+import org.jruby.anno.JRubyMethod;
+import org.jruby.exceptions.JumpException;
+import org.jruby.internal.runtime.methods.AttrReaderMethod;
+import org.jruby.internal.runtime.methods.AttrWriterMethod;
+import org.jruby.internal.runtime.methods.CallConfiguration;
+import org.jruby.runtime.Arity;
+import org.jruby.runtime.Block;
+import org.jruby.runtime.BlockCallback;
+import org.jruby.runtime.CallBlock19;
+import org.jruby.runtime.CallSite;
+import org.jruby.runtime.Helpers;
+import org.jruby.runtime.MethodIndex;
+import org.jruby.runtime.ObjectAllocator;
+import org.jruby.runtime.ThreadContext;
+import org.jruby.runtime.Visibility;
+import org.jruby.runtime.builtin.IRubyObject;
+import org.jruby.runtime.load.Library;
+
+public class Cparse implements Library {
+    public static final String RACC_VERSION = "1.4.12"; // TODO: parse from Cparse.c
+
+    public enum TokenType {
+        DEFAULT(-1),
+        FINAL(0),
+        ERROR(1);
+
+        private final int id;
+        TokenType(int id) { this.id = id; }
+    }
+
+    private RubyFixnum vDEFAULT_TOKEN;
+    private RubyFixnum vERROR_TOKEN;
+    private RubyFixnum vFINAL_TOKEN;
+
+    private RubyClass RaccBug;
+    private RubyClass CparseParams;
+
+    private static final String ID_YYDEBUG = "@yydebug";
+    private static final String ID_NEXTTOKEN = "next_token";
+    private static final String ID_ONERROR = "on_error";
+    private static final String ID_NOREDUCE = "_reduce_none";
+    private static final String ID_ERRSTATUS = "@racc_error_status";
+
+    private static final String ID_D_SHIFT = "racc_shift";
+    private static final String ID_D_REDUCE = "racc_reduce";
+    private static final String ID_D_ACCEPT = "racc_accept";
+    private static final String ID_D_READ_TOKEN = "racc_read_token";
+    private static final String ID_D_NEXT_STATE = "racc_next_state";
+    private static final String ID_D_E_POP = "racc_e_pop";
+
+    private RubySymbol sym_noreduce;
+    private CallSite call_nexttoken;
+    private CallSite call_onerror;
+    private CallSite call_d_shift;
+    private CallSite call_d_reduce;
+    private CallSite call_d_accept;
+    private CallSite call_d_read_token;
+    private CallSite call_d_next_state;
+    private CallSite call_d_e_pop;
+    private AttrWriterMethod set_errstatus;
+    private AttrReaderMethod get_errstatus;
+
+    private static RubySymbol value_to_id(ThreadContext context, IRubyObject v) {
+        if (!(v instanceof RubySymbol)) {
+            throw context.runtime.newTypeError("not symbol");
+        }
+        return (RubySymbol)v;
+    }
+
+    private static int num_to_int(IRubyObject n) {
+        return assert_integer(n);
+    }
+
+    private static IRubyObject AREF(ThreadContext context, IRubyObject s, int idx) {
+        return ((0 <= idx && idx < ((RubyArray)s).size()) ? ((RubyArray)s).entry(idx) : context.nil);
+    }
+
+    private static IRubyObject get_stack_tail(ThreadContext context, RubyArray stack, int len) {
+        if (len < 0) return context.nil;
+        int size = stack.size();
+        len = Math.min(len, size);
+        return stack.subseq(size - len, len);
+    }
+
+    private static void cut_stack_tail(ThreadContext context, RubyArray stack, int len) {
+        while (len > 0) {
+            stack.pop(context);
+            len--;
+        }
+    }
+
+    private static final int STACK_INIT_LEN = 64;
+    private static RubyArray NEW_STACK(ThreadContext context) {
+        return context.runtime.newArray(STACK_INIT_LEN);
+    }
+    private static IRubyObject PUSH(RubyArray stack, IRubyObject i) {
+        return stack.append(i);
+    }
+    private static IRubyObject POP(ThreadContext context, RubyArray stack) {
+        return stack.pop(context);
+    }
+    private static IRubyObject LAST_I(ThreadContext context, RubyArray stack) {
+        return stack.size() > 0 ? stack.last() : context.nil;
+    }
+    private static IRubyObject GET_TAIL(ThreadContext context, RubyArray stack, int len) {
+        return get_stack_tail(context, stack, len);
+    }
+    private static void CUT_TAIL(ThreadContext context, RubyArray stack, int len) {
+        cut_stack_tail(context, stack, len);
+    }
+
+    static final int CP_FIN_ACCEPT = 1;
+    static final int CP_FIN_EOT = 2;
+    static final int CP_FIN_CANTPOP = 3;
+
+    public class CparseParams extends RubyObject {
+        public CparseParams(Ruby runtime, RubyClass rubyClass) {
+            super(runtime, rubyClass);
+        }
+
+        public void initialize_params(ThreadContext context, Parser parser, IRubyObject arg, IRubyObject lexer, IRubyObject lexmid) {
+            Ruby runtime = context.runtime;
+            this.parser = parser;
+            this.lexer = lexer;
+            if (!lexmid.isNil()) {
+                this.lexmid = value_to_id(context, lexmid);
+                this.call_lexmid = MethodIndex.getFunctionalCallSite(this.lexmid.toString());
+            }
+
+            this.debug           = parser.getInstanceVariable(ID_YYDEBUG).isTrue();
+
+            RubyArray argAry = arg.convertToArray();
+            if (!(13 <= argAry.size() && argAry.size() <= 14)) {
+                throw runtime.newRaiseException(RaccBug, "[Racc Bug] wrong arg.size " + argAry.size());
+            }
+            this.action_table     = assert_array(argAry.eltOk(0));
+            this.action_check     = assert_array(argAry.eltOk(1));
+            this.action_default   = assert_array(argAry.eltOk(2));
+            this.action_pointer   = assert_array(argAry.eltOk(3));
+            this.goto_table       = assert_array(argAry.eltOk(4));
+            this.goto_check       = assert_array(argAry.eltOk(5));
+            this.goto_default     = assert_array(argAry.eltOk(6));
+            this.goto_pointer     = assert_array(argAry.eltOk(7));
+            this.nt_base          = assert_integer(argAry.eltOk(8));
+            this.reduce_table     = assert_array(argAry.eltOk(9));
+            this.token_table      = assert_hash(argAry.eltOk(10));
+            this.shift_n          = assert_integer(argAry.eltOk(11));
+            this.reduce_n         = assert_integer(argAry.eltOk(12));
+            if (argAry.size() > 13) {
+                this.use_result_var = argAry.eltOk(13).isTrue();
+             } else {
+                this.use_result_var = true;
+            }
+
+            this.tstack          = this.debug ? NEW_STACK(context) : null;
+            this.vstack          = NEW_STACK(context);
+            this.state           = NEW_STACK(context);
+            this.curstate        = 0;
+            PUSH(this.state, RubyFixnum.zero(runtime));
+            this.t               = runtime.newFixnum(TokenType.FINAL.id + 1); // must not init to FINAL_TOKEN
+            this.nerr            = 0;
+            this.errstatus       = 0;
+            set_errstatus.call(context, parser, parser.getMetaClass(), ID_ERRSTATUS, RubyNumeric.int2fix(runtime, this.errstatus));
+
+            this.retval          = context.nil;
+            this.fin             = 0;
+
+            this.lex_is_iterator = false;
+
+            parser.setInstanceVariable("@vstack", this.vstack);
+            if (this.debug) {
+                parser.setInstanceVariable("@tstack", this.tstack);
+            }
+            else {
+                parser.setInstanceVariable("@tstack", context.nil);
+            }
+        }
+
+        public void extract_user_token(ThreadContext context, IRubyObject block_args, IRubyObject[] tokVal) {
+            if (block_args.isNil()) {
+                /* EOF */
+                tokVal[0] = context.runtime.getFalse();
+                tokVal[1] = context.runtime.newString("$");
+                return;
+            }
+
+            if (!(block_args instanceof RubyArray)) {
+                throw context.runtime.newTypeError(
+                        (lex_is_iterator ? lexmid.asJavaString() : "next_token") +
+                                " " +
+                                (lex_is_iterator ? "yielded" : "returned") +
+                                " " +
+                                block_args.getMetaClass().getName() +
+                                " (must be Array[2])");
+            }
+            RubyArray block_args_ary = (RubyArray)block_args;
+            if (block_args_ary.size() != 2) {
+                throw context.runtime.newTypeError(
+                        (lex_is_iterator ? lexmid.asJavaString() : "next_token") +
+                                " " +
+                                (lex_is_iterator ? "yielded" : "returned") +
+                                " wrong size of array (" +
+                                block_args_ary.size() +
+                                " for 2)");
+            }
+            tokVal[0] = ((RubyArray) block_args).eltOk(0);
+            tokVal[1] = ((RubyArray) block_args).eltOk(1);
+        }
+
+        private static final int RESUME = 1;
+        private static final int NOTFOUND = 2;
+        private static final int ERROR_RECOVERED = 3;
+        private static final int ERROR = 4;
+        private static final int HANDLE_ACT = 5;
+        private static final int ACT_FIXED = 6;
+        private static final int ACCEPT = 7;
+        private static final int USER_YYERROR = 8;
+        private static final int ERROR_POP = 9;
+        private static final int TRANSIT = 9;
+
+        private void SHIFT(ThreadContext context, int act, IRubyObject tok, IRubyObject val) {
+            shift(context, act, tok, val);
+        }
+
+        private int REDUCE(ThreadContext context, int act) {
+            return reduce(context, act);
+        }
+
+        public void parse_main(ThreadContext context, IRubyObject tok, IRubyObject val, boolean resume) {
+            Ruby runtime = context.runtime;
+
+            int i = 0;              /* table index */
+            int act = 0;            /* action type */
+            IRubyObject act_value;     /* action type, VALUE version */
+            boolean read_next = true;   /* true if we need to read next token */
+            IRubyObject tmp;
+
+            int branch = 0;
+
+            if (resume) {
+                branch = RESUME;
+            }
+
+            BRANCH: while (true) {
+                switch (branch) {
+                    case 0:
+
+                        D_puts("");
+                        D_puts("---- enter new loop ----");
+                        D_puts("");
+
+                        D_printf("(act) k1=%ld\n", this.curstate);
+                        tmp = AREF(context, this.action_pointer, this.curstate);
+                        if (tmp.isNil()) {branch = NOTFOUND; continue BRANCH;}
+                        D_puts("(act) pointer[k1] ok");
+                        i = assert_integer(tmp);
+
+                        D_printf("read_next=%d\n", read_next);
+                        if (read_next && (this.t != vFINAL_TOKEN)) {
+                            if (this.lex_is_iterator) {
+                                D_puts("resuming...");
+                                if (this.fin != 0) throw runtime.newArgumentError("token given after EOF");
+                                this.i = i;  /* save i */
+                                return;
+
+                                // remainder of case duplicated from here for RESUME case
+                                //D_puts(this, "resumed");
+                                //i = this.i;  /* load i */
+                            }
+                            else {
+                                D_puts("next_token");
+                                tmp = call_nexttoken.call(context, this.parser, this.parser);
+                                IRubyObject[] tokVal = {tok, val};
+                                extract_user_token(context, tmp, tokVal);
+                                tok = tokVal[0];
+                                val = tokVal[1];
+                            }
+                            /* convert token */
+                            this.t = ((RubyHash)this.token_table).op_aref(context, tok);
+                            if (this.t.isNil()) {
+                                this.t = vERROR_TOKEN;
+                            }
+                            D_printf("(act) t(k2)=%ld\n", assert_integer(this.t));
+                            if (this.debug) {
+                                call_d_read_token.call(context, this.parser, this.parser, this.t, tok, val);
+                            }
+                        }
+
+                        // duplicated logic from above for RESUME case
+                    case RESUME:
+                        if (branch == RESUME) {
+                            D_puts("resumed");
+                            i = this.i;  /* load i */
+
+                            /* convert token */
+                            this.t = ((RubyHash)this.token_table).op_aref(context, tok);
+                            if (this.t.isNil()) {
+                                this.t = vERROR_TOKEN;
+                            }
+                            D_printf("(act) t(k2)=%ld\n", assert_integer(this.t));
+                            if (this.debug) {
+                                call_d_read_token.call(context, this.parser, this.parser, this.t, tok, val);
+                            }
+                        }
+
+                        read_next = false;
+
+                        i += assert_integer(this.t);
+                        D_printf("(act) i=%ld\n", i);
+                        if (i < 0) {branch = NOTFOUND; continue BRANCH;}
+
+                        act_value = AREF(context, this.action_table, i);
+                        if (act_value.isNil()) {branch = NOTFOUND; continue BRANCH;}
+                        act = assert_integer(act_value);
+                        D_printf("(act) table[i]=%ld\n", act);
+
+                        tmp = AREF(context, this.action_check, i);
+                        if (tmp.isNil()) {branch = NOTFOUND; continue BRANCH;}
+                        if (assert_integer(tmp) != this.curstate) {branch = NOTFOUND; continue BRANCH;}
+                        D_printf("(act) check[i]=%ld\n", assert_integer(tmp));
+
+                        D_puts("(act) found");
+
+                    case ACT_FIXED:
+                        D_printf("act=%ld\n", act);
+                        branch = HANDLE_ACT; continue BRANCH;
+
+                    case NOTFOUND:
+                        D_puts("(act) not found: use default");
+                        act_value = AREF(context, this.action_default, this.curstate);
+                        act = assert_integer(act_value);
+                        branch = ACT_FIXED; continue BRANCH;
+
+                    case HANDLE_ACT:
+                        if (act > 0 && act < this.shift_n) {
+                            D_puts("shift");
+                            if (this.errstatus > 0) {
+                                this.errstatus--;
+                                set_errstatus.call(context, this.parser, this.parser.getMetaClass(), ID_ERRSTATUS, runtime.newFixnum(this.errstatus));
+                            }
+                            SHIFT(context, act, this.t, val);
+                            read_next = true;
+                        }
+                        else if (act < 0 && act > -(this.reduce_n)) {
+                            D_puts("reduce");
+                            REDUCE(context, act);
+                        }
+                        else if (act == -(this.reduce_n)) {
+                            branch = ERROR; continue BRANCH;
+                        }
+                        else if (act == this.shift_n) {
+                            D_puts("accept");
+                            branch = ACCEPT; continue BRANCH;
+                        }
+                        else {
+                            throw runtime.newRaiseException(RaccBug, "[Cparse Bug] unknown act value " + act);
+                        }
+
+                    case ERROR_RECOVERED:
+
+                        if (this.debug) {
+                            call_d_next_state.call(context, this.parser, this.parser, runtime.newFixnum(this.curstate), this.state);
+                        }
+                        branch = 0; continue BRANCH;
+
+                    /* not reach */
+
+                    case ACCEPT:
+                        if (this.debug) call_d_accept.call(context, this.parser, this.parser);
+                        this.retval = this.vstack.eltOk(0);
+                        this.fin = CP_FIN_ACCEPT;
+                        return;
+
+                    case ERROR:
+                        D_printf("error detected, status=%ld\n", this.errstatus);
+                        if (this.errstatus == 0) {
+                            this.nerr++;
+                            call_onerror.call(context, this.parser, this.parser, this.t, val, this.vstack);
+                        }
+
+                    case USER_YYERROR:
+                        if (this.errstatus == 3) {
+                            if (this.t == vFINAL_TOKEN) {
+                                this.retval = runtime.getFalse();
+                                this.fin = CP_FIN_EOT;
+                                return;
+                            }
+                            read_next = true;
+                        }
+                        this.errstatus = 3;
+                        set_errstatus.call(context, this.parser, this.parser.getMetaClass(), ID_ERRSTATUS, runtime.newFixnum(this.errstatus));
+
+                        /* check if we can shift/reduce error token */
+                        D_printf("(err) k1=%ld\n", this.curstate);
+                        D_printf("(err) k2=%d (error)\n", TokenType.ERROR.id);
+
+                        int branch2 = 0;
+
+                        BRANCH2: while (true) {
+                            switch (branch2) {
+                                case 0:
+                                    tmp = AREF(context, this.action_pointer, this.curstate);
+                                    if (tmp.isNil()) {branch2 = ERROR_POP; continue BRANCH2;}
+                                    D_puts("(err) pointer[k1] ok");
+
+                                    i = assert_integer(tmp) + TokenType.ERROR.id;
+                                    D_printf("(err) i=%ld\n", i);
+                                    if (i < 0) {branch2 = ERROR_POP; continue BRANCH2;}
+
+                                    act_value = AREF(context, this.action_table, i);
+                                    if (act_value.isNil()) {
+                                        D_puts("(err) table[i] == nil");
+                                        branch2 = ERROR_POP; continue BRANCH2;
+                                    }
+                                    act = assert_integer(act_value);
+                                    D_printf("(err) table[i]=%ld\n", act);
+
+                                    tmp = AREF(context, this.action_check, i);
+                                    if (tmp.isNil()) {
+                                        D_puts("(err) check[i] == nil");
+                                        branch2 = ERROR_POP; continue BRANCH2;
+                                    }
+                                    if (assert_integer(tmp) != this.curstate) {
+                                        D_puts("(err) check[i] != k1");
+                                        branch2 = ERROR_POP; continue BRANCH2;
+                                    }
+
+                                    D_puts("(err) found: can handle error token");
+                                    break BRANCH2;
+
+                                case ERROR_POP:
+                                    D_puts("(err) act not found: can't handle error token; pop");
+
+                                    if (this.state.size() <= 1) {
+                                        this.retval = context.nil;
+                                        this.fin = CP_FIN_CANTPOP;
+                                        return;
+                                    }
+                                    POP(context, this.state);
+                                    POP(context, this.vstack);
+                                    this.curstate = assert_integer(LAST_I(context, this.state));
+                                    if (this.debug) {
+                                        POP(context, this.tstack);
+                                        call_d_e_pop.call(context, this.parser, this.parser, this.state, this.tstack, this.vstack);
+                                    }
+                            }
+                        }
+
+                        /* shift/reduce error token */
+                        if (act > 0 && act < this.shift_n) {
+                            D_puts("e shift");
+                            SHIFT(context, act, runtime.newFixnum(TokenType.ERROR.id), val);
+                        }
+                        else if (act < 0 && act > -(this.reduce_n)) {
+                            D_puts("e reduce");
+                            REDUCE(context, act);
+                        }
+                        else if (act == this.shift_n) {
+                            D_puts("e accept");
+                            branch = ACCEPT; continue BRANCH;
+                        }
+                        else {
+                            throw runtime.newRaiseException(RaccBug, "[Cparse Bug] unknown act value " + act);
+                        }
+                        branch = ERROR_RECOVERED; continue BRANCH;
+                }
+            }
+        }
+
+        private void shift(ThreadContext context, int act, IRubyObject tok, IRubyObject val) {
+            PUSH(vstack, val);
+            if (debug) {
+                PUSH(tstack, tok);
+                call_d_shift.call(context, this.parser, this.parser, tok, tstack, vstack);
+            }
+            curstate = act;
+            PUSH(state, context.runtime.newFixnum(curstate));
+        }
+
+        private int reduce(ThreadContext context, int act) {
+            IRubyObject code;
+            ruleno = -act * 3;
+            IRubyObject tag = context.runtime.newSymbol("racc_jump");
+            RubyContinuation rbContinuation = new RubyContinuation(context.runtime, context.runtime.newSymbol("racc_jump"));
+            try {
+                context.pushCatch(rbContinuation.getContinuation());
+                code = reduce0(context);
+                errstatus = assert_integer(get_errstatus.call(context, parser, parser.getMetaClass(), ID_ERRSTATUS));
+            } finally {
+                context.popCatch();
+            }
+            return assert_integer(code);
+        }
+
+        private IRubyObject reduce0(ThreadContext context) {
+            Ruby runtime = context.runtime;
+
+            IRubyObject reduce_to, reduce_len, method_id;
+            int len;
+            RubySymbol mid;
+            IRubyObject tmp, tmp_t = RubyBasicObject.UNDEF, tmp_v = RubyBasicObject.UNDEF;
+            int i, k1 = 0, k2;
+            IRubyObject goto_state = context.nil;
+
+            reduce_len = this.reduce_table.entry(this.ruleno);
+            reduce_to  = this.reduce_table.entry(this.ruleno+1);
+            method_id  = this.reduce_table.entry(this.ruleno+2);
+            len = assert_integer(reduce_len);
+            mid = value_to_id(context, method_id);
+
+            int branch = 0;
+            BRANCH: while (true) {
+                switch (branch) {
+                    case 0:
+
+                        /* call action */
+                        if (len == 0) {
+                            tmp = context.nil;
+                            if (mid != sym_noreduce)
+                                tmp_v = runtime.newArray();
+                            if (this.debug)
+                                tmp_t = runtime.newArray();
+                        }
+                        else {
+                            if (mid != sym_noreduce) {
+                                tmp_v = GET_TAIL(context, this.vstack, len);
+                                tmp = ((RubyArray)tmp_v).entry(0);
+                            }
+                            else {
+                                tmp = this.vstack.entry(this.vstack.size() - len);
+                            }
+                            CUT_TAIL(context, this.vstack, len);
+                            if (this.debug) {
+                                tmp_t = GET_TAIL(context, this.tstack, len);
+                                CUT_TAIL(context, this.tstack, len);
+                            }
+                            CUT_TAIL(context, this.state, len);
+                        }
+                        if (mid != sym_noreduce) {
+                            if (this.use_result_var) {
+                                tmp = Helpers.invoke(context, this.parser, mid.toString(), tmp_v, this.vstack, tmp);
+                            }
+                            else {
+                                tmp = Helpers.invoke(context, this.parser, mid.toString(), tmp_v, this.vstack);
+                            }
+                        }
+
+                        /* then push result */
+                        PUSH(this.vstack, tmp);
+                        if (this.debug) {
+                            PUSH(this.tstack, reduce_to);
+                            call_d_reduce.call(context, this.parser, this.parser, tmp_t, reduce_to, this.tstack, this.vstack);
+                        }
+
+                        /* calculate transition state */
+                        if (state.size() == 0)
+                            throw runtime.newRaiseException(RaccBug, "state stack unexpectedly empty");
+                        k2 = assert_integer(LAST_I(context, this.state));
+                        k1 = assert_integer(reduce_to) - this.nt_base;
+                        D_printf("(goto) k1=%ld\n", k1);
+                        D_printf("(goto) k2=%ld\n", k2);
+
+                        tmp = AREF(context, this.goto_pointer, k1);
+                        if (tmp.isNil()) {branch = NOTFOUND; continue BRANCH;}
+
+                        i = assert_integer(tmp) + k2;
+                        D_printf("(goto) i=%ld\n", i);
+                        if (i < 0) {branch = NOTFOUND; continue BRANCH;}
+
+                        goto_state = AREF(context, this.goto_table, i);
+                        if (goto_state.isNil()) {
+                            D_puts("(goto) table[i] == nil");
+                            branch = NOTFOUND; continue BRANCH;
+                        }
+                        D_printf("(goto) table[i]=%ld (goto_state)\n", goto_state.convertToInteger().getLongValue());
+
+                        tmp = AREF(context, this.goto_check, i);
+                        if (tmp.isNil()) {
+                            D_puts("(goto) check[i] == nil");
+                            branch = NOTFOUND; continue BRANCH;
+                        }
+                        if (tmp != runtime.newFixnum(k1)) {
+                            D_puts("(goto) check[i] != table[i]");
+                            branch = NOTFOUND; continue BRANCH;
+                        }
+                        D_printf("(goto) check[i]=%ld\n", tmp.convertToInteger().getLongValue());
+
+                        D_puts("(goto) found");
+
+                    case TRANSIT:
+                        PUSH(this.state, goto_state);
+                        this.curstate = assert_integer(goto_state);
+                        return RubyFixnum.zero(runtime);
+
+                    case NOTFOUND:
+                        D_puts("(goto) not found: use default");
+                        /* overwrite `goto-state' by default value */
+                        goto_state = AREF(context, this.goto_default, k1);
+                        branch = TRANSIT; continue BRANCH;
+                }
+            }
+        }
+
+        private void D_puts(String msg) {
+            if (sys_debug) {
+                System.out.println(msg);
+            }
+        }
+
+        private void D_printf(String fmt, long arg) {
+            if (sys_debug) {
+                System.out.println(fmt + ": " + arg);
+            }
+        }
+
+        private void D_printf(String fmt, boolean arg) {
+            if (sys_debug) {
+                System.out.println(fmt + ": " + arg);
+            }
+        }
+
+        Parser parser;          /* parser object */
+
+        boolean lex_is_iterator;
+        IRubyObject lexer;           /* scanner object */
+        RubySymbol lexmid;          /* name of scanner method (must be an iterator) */
+        CallSite call_lexmid;       /* call site for scanner method */
+
+        /* State transition tables (immutable)
+           Data structure is from Dragon Book 4.9 */
+        /* action table */
+        IRubyObject action_table;
+        IRubyObject action_check;
+        IRubyObject action_default;
+        IRubyObject action_pointer;
+        /* goto table */
+        IRubyObject goto_table;
+        IRubyObject goto_check;
+        IRubyObject goto_default;
+        IRubyObject goto_pointer;
+
+        int nt_base;         /* NonTerminal BASE index */
+        RubyArray reduce_table;    /* reduce data table */
+        IRubyObject token_table;     /* token conversion table */
+
+        /* parser stacks and parameters */
+        RubyArray state;
+        int curstate;
+        RubyArray vstack;
+        RubyArray tstack;
+        IRubyObject t;
+        int shift_n;
+        int reduce_n;
+        int ruleno;
+
+        int errstatus;         /* nonzero in error recovering mode */
+        int nerr;              /* number of error */
+
+        boolean use_result_var;
+
+        IRubyObject retval;           /* return IRubyObject of parser routine */
+        int fin;               /* parse result status */
+
+        boolean debug;              /* user level debug */
+        boolean sys_debug;          /* system level debug */
+
+        int i;                 /* table index */
+    }
+
+    private static RubyArray assert_array(IRubyObject a) {
+        return a.convertToArray();
+    }
+
+    private static RubyHash assert_hash(IRubyObject h) {
+        return h.convertToHash();
+    }
+
+    private static int assert_integer(IRubyObject i) {
+        return (int)i.convertToInteger().getLongValue();
+    }
+
+    public class Parser extends RubyObject {
+        public Parser(Ruby runtime, RubyClass rubyClass) {
+            super(runtime, rubyClass);
+        }
+
+        public static final String Racc_Runtime_Core_Version_C = RACC_VERSION;
+        public static final String Racc_Runtime_Core_Id_C = "$originalId: cparse.c,v 1.8 2006/07/06 11:39:46 aamine Exp $";
+
+        @JRubyMethod(name = "_racc_do_parse_c", frame = true)
+        public IRubyObject racc_cparse(ThreadContext context, IRubyObject arg, IRubyObject sysdebug) {
+            CparseParams v = new CparseParams(context.runtime, CparseParams);
+
+            v.D_puts("starting cparse");
+            v.sys_debug = sysdebug.isTrue();
+            v.initialize_params(context, this, arg, context.nil, context.nil);
+            v.lex_is_iterator = false;
+            v.parse_main(context, context.nil, context.nil, false);
+
+            return v.retval;
+        }
+
+        @JRubyMethod(name = "_racc_yyparse_c", frame = true, required = 4)
+        public IRubyObject racc_yyparse(ThreadContext context, IRubyObject[] args) {
+            Ruby runtime = context.runtime;
+            CparseParams v = new CparseParams(context.runtime, CparseParams);
+
+            IRubyObject lexer = args[0], lexmid = args[1], arg = args[2], sysdebug = args[3];
+
+            v.sys_debug = sysdebug.isTrue();
+            v.D_puts("start C yyparse");
+            v.initialize_params(context, this, arg, lexer, lexmid);
+            v.lex_is_iterator = true;
+            v.D_puts("params initialized");
+            v.parse_main(context, context.nil, context.nil, false);
+            call_lexer(context, v);
+            if (v.fin == 0) {
+                throw runtime.newArgumentError(v.lexmid + " is finished before EndOfToken");
+            }
+
+            return v.retval;
+        }
+
+        private void call_lexer(ThreadContext context, final CparseParams v) {
+            final int frame = context.getFrameJumpTarget();
+            try {
+                v.call_lexmid.call(context, v.lexer, v.lexer, CallBlock19.newCallClosure(v, v.getMetaClass(), Arity.ONE_ARGUMENT, new BlockCallback() {
+                    @Override
+                    public IRubyObject call(ThreadContext context, IRubyObject[] args, Block block) {
+                        Ruby runtime = context.getRuntime();
+                        if (v.fin != 0) {
+                            throw runtime.newArgumentError("extra token after EndOfToken");
+                        }
+                        IRubyObject[] tokVal = {null, null};
+                        v.extract_user_token(context, args[0], tokVal);
+                        v.parse_main(context, tokVal[0], tokVal[1], true);
+                        if (v.fin != 0 && v.fin != CP_FIN_ACCEPT) {
+                            throw new JumpException.BreakJump(frame, context.nil);
+                        }
+
+                        return context.nil;
+                    }
+                }, context));
+            } catch (JumpException.BreakJump bj) {
+                if (bj.getTarget() == frame) {
+                    return;
+                }
+            }
+        }
+    }
+
+    public void load(Ruby runtime, boolean wrap) {
+        RubyModule racc = runtime.getOrCreateModule("Racc");
+        RubyClass parser = racc.defineOrGetClassUnder("Parser", runtime.getObject());
+        parser.setAllocator(new ObjectAllocator() {
+            @Override
+            public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
+                return new Parser(ruby, rubyClass);
+            }
+        });
+
+        parser.defineAnnotatedMethods(Parser.class);
+
+        parser.defineConstant("Racc_Runtime_Core_Version_C", runtime.newString(Parser.Racc_Runtime_Core_Version_C));
+        parser.defineConstant("Racc_Runtime_Core_Id_C", runtime.newString(Parser.Racc_Runtime_Core_Id_C));
+
+        CparseParams = racc.defineClassUnder("CparseParams", runtime.getObject(), new ObjectAllocator() {
+            @Override
+            public IRubyObject allocate(Ruby ruby, RubyClass rubyClass) {
+                return new CparseParams(ruby, rubyClass);
+            }
+        });
+
+        RaccBug = runtime.getRuntimeError();
+        sym_noreduce = runtime.newSymbol(ID_NOREDUCE);
+        call_nexttoken = MethodIndex.getFunctionalCallSite(ID_NEXTTOKEN);
+        call_onerror = MethodIndex.getFunctionalCallSite(ID_ONERROR);
+        call_d_shift = MethodIndex.getFunctionalCallSite(ID_D_SHIFT);
+        call_d_reduce = MethodIndex.getFunctionalCallSite(ID_D_REDUCE);
+        call_d_accept = MethodIndex.getFunctionalCallSite(ID_D_ACCEPT);
+        call_d_read_token = MethodIndex.getFunctionalCallSite(ID_D_READ_TOKEN);
+        call_d_next_state = MethodIndex.getFunctionalCallSite(ID_D_NEXT_STATE);
+        call_d_e_pop = MethodIndex.getFunctionalCallSite(ID_D_E_POP);
+
+        // hacky utility for caching instance var accessor
+        set_errstatus = new AttrWriterMethod(parser, Visibility.PUBLIC, CallConfiguration.FrameNoneScopeNone, ID_ERRSTATUS);
+        get_errstatus = new AttrReaderMethod(parser, Visibility.PUBLIC, CallConfiguration.FrameNoneScopeNone, ID_ERRSTATUS);
+
+        vDEFAULT_TOKEN      = runtime.newFixnum(TokenType.DEFAULT.id);
+        vERROR_TOKEN      = runtime.newFixnum(TokenType.ERROR.id);
+        vFINAL_TOKEN      = runtime.newFixnum(TokenType.FINAL.id);
+    }
+}
diff --git a/ext/racc/cparse.c b/ext/racc/cparse.c
index db87630..d5a0f34 100644
--- a/ext/racc/cparse.c
+++ b/ext/racc/cparse.c
@@ -17,7 +17,7 @@
                         Important Constants
 ----------------------------------------------------------------------- */
 
-#define RACC_VERSION "1.4.9"
+#define RACC_VERSION "1.4.12"
 
 #define DEFAULT_TOKEN -1
 #define ERROR_TOKEN    1
@@ -65,6 +65,10 @@ static ID id_d_e_pop;
 #  define LONG2NUM(i) INT2NUM(i)
 #endif
 
+#ifndef HAVE_RB_ARY_SUBSEQ
+#  define rb_ary_subseq(ary, beg, len) rb_ary_new4(len, RARRAY_PTR(ary) + beg)
+#endif
+
 static ID value_to_id _((VALUE v));
 static inline long num_to_long _((VALUE n));
 
@@ -84,7 +88,7 @@ num_to_long(VALUE n)
 }
 
 #define AREF(s, idx) \
-    ((0 <= idx && idx < RARRAY_LEN(s)) ? RARRAY_PTR(s)[idx] : Qnil)
+    ((0 <= idx && idx < RARRAY_LEN(s)) ? rb_ary_entry(s, idx) : Qnil)
 
 /* -----------------------------------------------------------------------
                         Parser Stack Interfaces
@@ -98,7 +102,7 @@ get_stack_tail(VALUE stack, long len)
 {
     if (len < 0) return Qnil;  /* system error */
     if (len > RARRAY_LEN(stack)) len = RARRAY_LEN(stack);
-    return rb_ary_new4(len, RARRAY_PTR(stack) + RARRAY_LEN(stack) - len);
+    return rb_ary_subseq(stack, RARRAY_LEN(stack) - len, len);
 }
 
 static void
@@ -115,7 +119,7 @@ cut_stack_tail(VALUE stack, long len)
 #define PUSH(s, i) rb_ary_store(s, RARRAY_LEN(s), i)
 #define POP(s) rb_ary_pop(s)
 #define LAST_I(s) \
-    ((RARRAY_LEN(s) > 0) ? RARRAY_PTR(s)[RARRAY_LEN(s) - 1] : Qnil)
+    ((RARRAY_LEN(s) > 0) ? rb_ary_entry(s, RARRAY_LEN(s) - 1) : Qnil)
 #define GET_TAIL(s, len) get_stack_tail(s, len)
 #define CUT_TAIL(s, len) cut_stack_tail(s, len)
 
@@ -327,21 +331,21 @@ initialize_params(VALUE vparams, VALUE parser, VALUE arg, VALUE lexer, VALUE lex
     Check_Type(arg, T_ARRAY);
     if (!(13 <= RARRAY_LEN(arg) && RARRAY_LEN(arg) <= 14))
         rb_raise(RaccBug, "[Racc Bug] wrong arg.size %ld", RARRAY_LEN(arg));
-    v->action_table   = assert_array  (RARRAY_PTR(arg)[ 0]);
-    v->action_check   = assert_array  (RARRAY_PTR(arg)[ 1]);
-    v->action_default = assert_array  (RARRAY_PTR(arg)[ 2]);
-    v->action_pointer = assert_array  (RARRAY_PTR(arg)[ 3]);
-    v->goto_table     = assert_array  (RARRAY_PTR(arg)[ 4]);
-    v->goto_check     = assert_array  (RARRAY_PTR(arg)[ 5]);
-    v->goto_default   = assert_array  (RARRAY_PTR(arg)[ 6]);
-    v->goto_pointer   = assert_array  (RARRAY_PTR(arg)[ 7]);
-    v->nt_base        = assert_integer(RARRAY_PTR(arg)[ 8]);
-    v->reduce_table   = assert_array  (RARRAY_PTR(arg)[ 9]);
-    v->token_table    = assert_hash   (RARRAY_PTR(arg)[10]);
-    v->shift_n        = assert_integer(RARRAY_PTR(arg)[11]);
-    v->reduce_n       = assert_integer(RARRAY_PTR(arg)[12]);
+    v->action_table   = assert_array  (rb_ary_entry(arg,  0));
+    v->action_check   = assert_array  (rb_ary_entry(arg,  1));
+    v->action_default = assert_array  (rb_ary_entry(arg,  2));
+    v->action_pointer = assert_array  (rb_ary_entry(arg,  3));
+    v->goto_table     = assert_array  (rb_ary_entry(arg,  4));
+    v->goto_check     = assert_array  (rb_ary_entry(arg,  5));
+    v->goto_default   = assert_array  (rb_ary_entry(arg,  6));
+    v->goto_pointer   = assert_array  (rb_ary_entry(arg,  7));
+    v->nt_base        = assert_integer(rb_ary_entry(arg,  8));
+    v->reduce_table   = assert_array  (rb_ary_entry(arg,  9));
+    v->token_table    = assert_hash   (rb_ary_entry(arg, 10));
+    v->shift_n        = assert_integer(rb_ary_entry(arg, 11));
+    v->reduce_n       = assert_integer(rb_ary_entry(arg, 12));
     if (RARRAY_LEN(arg) > 13) {
-        v->use_result_var = RTEST(RARRAY_PTR(arg)[13]);
+        v->use_result_var = RTEST(rb_ary_entry(arg, 13));
     }
     else {
         v->use_result_var = Qtrue;
@@ -557,7 +561,7 @@ parse_main(struct cparse_params *v, VALUE tok, VALUE val, int resume)
 
   accept:
     if (v->debug) rb_funcall(v->parser, id_d_accept, 0);
-    v->retval = RARRAY_PTR(v->vstack)[0];
+    v->retval = rb_ary_entry(v->vstack, 0);
     v->fin = CP_FIN_ACCEPT;
     return;
 
@@ -686,9 +690,9 @@ reduce0(VALUE val, VALUE data, VALUE self)
     VALUE goto_state;
 
     Data_Get_Struct(data, struct cparse_params, v);
-    reduce_len = RARRAY_PTR(v->reduce_table)[v->ruleno];
-    reduce_to  = RARRAY_PTR(v->reduce_table)[v->ruleno+1];
-    method_id  = RARRAY_PTR(v->reduce_table)[v->ruleno+2];
+    reduce_len = rb_ary_entry(v->reduce_table, v->ruleno);
+    reduce_to  = rb_ary_entry(v->reduce_table, v->ruleno+1);
+    method_id  = rb_ary_entry(v->reduce_table, v->ruleno+2);
     len = NUM2LONG(reduce_len);
     mid = value_to_id(method_id);
 
@@ -703,10 +707,10 @@ reduce0(VALUE val, VALUE data, VALUE self)
     else {
         if (mid != id_noreduce) {
             tmp_v = GET_TAIL(v->vstack, len);
-            tmp = RARRAY_PTR(tmp_v)[0];
+            tmp = rb_ary_entry(tmp_v, 0);
         }
         else {
-            tmp = RARRAY_PTR(v->vstack)[ RARRAY_LEN(v->vstack) - len ];
+            tmp = rb_ary_entry(v->vstack, RARRAY_LEN(v->vstack) - len);
         }
         CUT_TAIL(v->vstack, len);
         if (v->debug) {
diff --git a/ext/racc/extconf.rb b/ext/racc/extconf.rb
index dd5ddc1..d36b03b 100644
--- a/ext/racc/extconf.rb
+++ b/ext/racc/extconf.rb
@@ -1,5 +1,7 @@
-# $Id: 24b2ba178fd74c1e6029e30ed31e654178865854 $
+# $Id: 1e30abedf4eea155815d1efa5500ec817b10a2ab $
 
 require 'mkmf'
 
+have_func('rb_ary_subseq')
+
 create_makefile 'racc/cparse'
diff --git a/lib/racc/compat.rb b/lib/racc/compat.rb
index b036292..ccb033e 100644
--- a/lib/racc/compat.rb
+++ b/lib/racc/compat.rb
@@ -1,5 +1,5 @@
 #
-# $Id: b40c10cc1a30073bf591fef553277971e3c4cd75 $
+# $Id: 14fa1118eb3a23e85265e4f7afe2d5a297d69f9c $
 #
 # Copyright (c) 1999-2006 Minero Aoki
 #
@@ -21,14 +21,6 @@ unless Object.method_defined?(:__send!)
   end
 end
 
-unless String.method_defined?(:to_a)
-  class String
-    def to_a
-      lines.to_a
-    end
-  end
-end
-
 unless Array.method_defined?(:map!)
   class Array
     if Array.method_defined?(:collect!)
diff --git a/lib/racc/grammarfileparser.rb b/lib/racc/grammarfileparser.rb
index a96a815..7548a9e 100644
--- a/lib/racc/grammarfileparser.rb
+++ b/lib/racc/grammarfileparser.rb
@@ -1,5 +1,5 @@
 #
-# $Id: 3f7136294dbfbc25783f216ca3168a37c671960b $
+# $Id: 5e1871defa15d288d2252e6a76bb2c4cf2119ed3 $
 #
 # Copyright (c) 1999-2006 Minero Aoki
 #
@@ -258,7 +258,7 @@ module Racc
       line = @scanner.lineno
       _, *blocks = *@scanner.epilogue.split(/^----/)
       blocks.each do |block|
-        header, *body = block.to_a
+        header, *body = block.lines.to_a
         label0, pathes = *header.sub(/\A-+/, '').split('=', 2)
         label = canonical_label(label0)
         (pathes ? pathes.strip.split(' ') : []).each do |path|
diff --git a/lib/racc/info.rb b/lib/racc/info.rb
index 19e60b7..3ab5468 100644
--- a/lib/racc/info.rb
+++ b/lib/racc/info.rb
@@ -1,5 +1,5 @@
 #
-# $Id: 96a81cf328285b90878c3bb512715a95950dba46 $
+# $Id: 90afb43b1438ad2bb681a529146d1cb5cd7e45ac $
 #
 # Copyright (c) 1999-2006 Minero Aoki
 #
@@ -10,7 +10,7 @@
 #
 
 module Racc
-  VERSION   = '1.4.9'
+  VERSION   = '1.4.12'
   Version = VERSION
   Copyright = 'Copyright (c) 1999-2006 Minero Aoki'
 end
diff --git a/lib/racc/parser-text.rb b/lib/racc/parser-text.rb
index 0ab27d8..45a7692 100644
--- a/lib/racc/parser-text.rb
+++ b/lib/racc/parser-text.rb
@@ -1,7 +1,7 @@
 module Racc
   PARSER_TEXT = <<'__end_of_file__'
 #
-# $Id: ad1fffef443194fdfa1052d2eee6850552f94313 $
+# $Id: a7af944d201a32a63d2536cdd589d8e9910848e0 $
 #
 # Copyright (c) 1999-2006 Minero Aoki
 #
@@ -13,8 +13,10 @@ module Racc
 # without restriction.
 #
 
+require 'racc/info'
+
 unless defined?(NotImplementedError)
-  NotImplementedError = NotImplementError
+  NotImplementedError = NotImplementError # :nodoc:
 end
 
 module Racc
@@ -24,21 +26,180 @@ unless defined?(::ParseError)
   ParseError = Racc::ParseError
 end
 
+# Racc is a LALR(1) parser generator.
+# It is written in Ruby itself, and generates Ruby programs.
+#
+# == Command-line Reference
+#
+#     racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
+#          [-e<var>rubypath</var>] [--embedded=<var>rubypath</var>]
+#          [-v] [--verbose]
+#          [-O<var>filename</var>] [--log-file=<var>filename</var>]
+#          [-g] [--debug]
+#          [-E] [--embedded]
+#          [-l] [--no-line-convert]
+#          [-c] [--line-convert-all]
+#          [-a] [--no-omit-actions]
+#          [-C] [--check-only]
+#          [-S] [--output-status]
+#          [--version] [--copyright] [--help] <var>grammarfile</var>
+#
+# [+filename+]
+#   Racc grammar file. Any extention is permitted.
+# [-o+outfile+, --output-file=+outfile+]
+#   A filename for output. default is <+filename+>.tab.rb
+# [-O+filename+, --log-file=+filename+]
+#   Place logging output in file +filename+.
+#   Default log file name is <+filename+>.output.
+# [-e+rubypath+, --executable=+rubypath+]
+#   output executable file(mode 755). where +path+ is the Ruby interpreter.
+# [-v, --verbose]
+#   verbose mode. create +filename+.output file, like yacc's y.output file.
+# [-g, --debug]
+#   add debug code to parser class. To display debuggin information,
+#   use this '-g' option and set @yydebug true in parser class.
+# [-E, --embedded]
+#   Output parser which doesn't need runtime files (racc/parser.rb).
+# [-C, --check-only]
+#   Check syntax of racc grammer file and quit.
+# [-S, --output-status]
+#   Print messages time to time while compiling.
+# [-l, --no-line-convert]
+#   turns off line number converting.
+# [-c, --line-convert-all]
+#   Convert line number of actions, inner, header and footer.
+# [-a, --no-omit-actions]
+#   Call all actions, even if an action is empty.
+# [--version]
+#   print Racc version and quit.
+# [--copyright]
+#   Print copyright and quit.
+# [--help]
+#   Print usage and quit.
+#
+# == Generating Parser Using Racc
+#
+# To compile Racc grammar file, simply type:
+#
+#   $ racc parse.y
+#
+# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
+#
+# == Writing A Racc Grammar File
+#
+# If you want your own parser, you have to write a grammar file.
+# A grammar file contains the name of your parser class, grammar for the parser,
+# user code, and anything else.
+# When writing a grammar file, yacc's knowledge is helpful.
+# If you have not used yacc before, Racc is not too difficult.
+#
+# Here's an example Racc grammar file.
+#
+#   class Calcparser
+#   rule
+#     target: exp { print val[0] }
+#
+#     exp: exp '+' exp
+#        | exp '*' exp
+#        | '(' exp ')'
+#        | NUMBER
+#   end
+#
+# Racc grammar files resemble yacc files.
+# But (of course), this is Ruby code.
+# yacc's $$ is the 'result', $0, $1... is
+# an array called 'val', and $-1, $-2... is an array called '_values'.
+#
+# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
+# more information on grammar files.
+#
+# == Parser
+#
+# Then you must prepare the parse entry method. There are two types of
+# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
+#
+# Racc::Parser#do_parse is simple.
+#
+# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
+# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
+# EOF is [false, false].
+# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
+# If you want to change this, see the grammar reference.
+#
+# Racc::Parser#yyparse is little complicated, but useful.
+# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
+#
+# For example, <code>yyparse(obj, :scan)</code> causes
+# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
+#
+# == Debugging
+#
+# When debugging, "-v" or/and the "-g" option is helpful.
+#
+# "-v" creates verbose log file (.output).
+# "-g" creates a "Verbose Parser".
+# Verbose Parser prints the internal status when parsing.
+# But it's _not_ automatic.
+# You must use -g option and set + at yydebug+ to +true+ in order to get output.
+# -g option only creates the verbose parser.
+#
+# === Racc reported syntax error.
+#
+# Isn't there too many "end"?
+# grammar of racc file is changed in v0.10.
+#
+# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
+#
+# === Racc reported "XXXX conflicts".
+#
+# Try "racc -v xxxx.y".
+# It causes producing racc's internal log file, xxxx.output.
+#
+# === Generated parsers does not work correctly
+#
+# Try "racc -g xxxx.y".
+# This command let racc generate "debugging parser".
+# Then set @yydebug=true in your parser.
+# It produces a working log of your parser.
+#
+# == Re-distributing Racc runtime
+#
+# A parser, which is created by Racc, requires the Racc runtime module;
+# racc/parser.rb.
+#
+# Ruby 1.8.x comes with Racc runtime module,
+# you need NOT distribute Racc runtime files.
+#
+# If you want to include the Racc runtime module with your parser.
+# This can be done by using '-E' option:
+#
+#   $ racc -E -omyparser.rb myparser.y
+#
+# This command creates myparser.rb which `includes' Racc runtime.
+# Only you must do is to distribute your parser file (myparser.rb).
+#
+# Note: parser.rb is LGPL, but your parser is not.
+# Your own parser is completely yours.
 module Racc
 
   unless defined?(Racc_No_Extentions)
-    Racc_No_Extentions = false
+    Racc_No_Extentions = false # :nodoc:
   end
 
   class Parser
 
-    Racc_Runtime_Version = '1.4.6'
-    Racc_Runtime_Revision = '$Id: ad1fffef443194fdfa1052d2eee6850552f94313 $'
+    Racc_Runtime_Version = ::Racc::VERSION
+    Racc_Runtime_Revision = '$Id: a7af944d201a32a63d2536cdd589d8e9910848e0 $'
 
-    Racc_Runtime_Core_Version_R = '1.4.6'
-    Racc_Runtime_Core_Revision_R = '$Id: ad1fffef443194fdfa1052d2eee6850552f94313 $'.split[1]
+    Racc_Runtime_Core_Version_R = ::Racc::VERSION
+    Racc_Runtime_Core_Revision_R = '$Id: a7af944d201a32a63d2536cdd589d8e9910848e0 $'.split[1]
     begin
-      require 'racc/cparse'
+      if RUBY_ENGINE == 'jruby'
+        require 'racc/cparse-jruby.jar'
+        com.headius.racc.Cparse.new.load(JRuby.runtime, false)
+      else
+        require 'racc/cparse'
+      end
     # Racc_Runtime_Core_Version_C  = (defined in extention)
       Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
       unless new.respond_to?(:_racc_do_parse_c, true)
@@ -48,12 +209,14 @@ module Racc
         raise LoadError, 'selecting ruby version of racc runtime core'
       end
 
-      Racc_Main_Parsing_Routine    = :_racc_do_parse_c
-      Racc_YY_Parse_Method         = :_racc_yyparse_c
-      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_C
-      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_C
-      Racc_Runtime_Type            = 'c'
+      Racc_Main_Parsing_Routine    = :_racc_do_parse_c # :nodoc:
+      Racc_YY_Parse_Method         = :_racc_yyparse_c # :nodoc:
+      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_C # :nodoc:
+      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_C # :nodoc:
+      Racc_Runtime_Type            = 'c' # :nodoc:
     rescue LoadError
+puts $!
+puts $!.backtrace
       Racc_Main_Parsing_Routine    = :_racc_do_parse_rb
       Racc_YY_Parse_Method         = :_racc_yyparse_rb
       Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_R
@@ -61,12 +224,10 @@ module Racc
       Racc_Runtime_Type            = 'ruby'
     end
 
-    def Parser.racc_runtime_type
+    def Parser.racc_runtime_type # :nodoc:
       Racc_Runtime_Type
     end
 
-    private
-
     def _racc_setup
       @yydebug = false unless self.class::Racc_debug_parser
       @yydebug = false unless defined?(@yydebug)
@@ -93,14 +254,33 @@ module Racc
       @racc_error_status = 0
     end
 
-    ###
-    ### do_parse
-    ###
-
+    # The entry point of the parser. This method is used with #next_token.
+    # If Racc wants to get token (and its value), calls next_token.
+    #
+    # Example:
+    #     def parse
+    #       @q = [[1,1],
+    #             [2,2],
+    #             [3,3],
+    #             [false, '$']]
+    #       do_parse
+    #     end
+    #
+    #     def next_token
+    #       @q.shift
+    #     end
     def do_parse
       __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
     end
 
+    # The method to fetch next token.
+    # If you use #do_parse method, you must implement #next_token.
+    #
+    # The format of return value is [TOKEN_SYMBOL, VALUE].
+    # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
+    # for 'IDENT'.  ";" (String) for ';'.
+    #
+    # The final symbol (End of file) must be false.
     def next_token
       raise NotImplementedError, "#{self.class}\#next_token is not defined"
     end
@@ -144,12 +324,13 @@ module Racc
       }
     end
 
-    ###
-    ### yyparse
-    ###
-
+    # Another entry point for the parser.
+    # If you use this method, you must implement RECEIVER#METHOD_ID method.
+    #
+    # RECEIVER#METHOD_ID is a method to get next token.
+    # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
     def yyparse(recv, mid)
-      __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
+      __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), false)
     end
 
     def _racc_yyparse_rb(recv, mid, arg, c_debug)
@@ -342,27 +523,43 @@ module Racc
       goto_default[k1]
     end
 
+    # This method is called when a parse error is found.
+    #
+    # ERROR_TOKEN_ID is an internal ID of token which caused error.
+    # You can get string representation of this ID by calling
+    # #token_to_str.
+    #
+    # ERROR_VALUE is a value of error token.
+    #
+    # value_stack is a stack of symbol values.
+    # DO NOT MODIFY this object.
+    #
+    # This method raises ParseError by default.
+    #
+    # If this method returns, parsers enter "error recovering mode".
     def on_error(t, val, vstack)
       raise ParseError, sprintf("\nparse error on value %s (%s)",
                                 val.inspect, token_to_str(t) || '?')
     end
 
+    # Enter error recovering mode.
+    # This method does not call #on_error.
     def yyerror
       throw :racc_jump, 1
     end
 
+    # Exit parser.
+    # Return value is Symbol_Value_Stack[0].
     def yyaccept
       throw :racc_jump, 2
     end
 
+    # Leave error recovering mode.
     def yyerrok
       @racc_error_status = 0
     end
 
-    #
-    # for debugging output
-    #
-
+    # For debugging output
     def racc_read_token(t, tok, val)
       @racc_debug_out.print 'read    '
       @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
@@ -385,7 +582,6 @@ module Racc
         toks.each {|t| out.print ' ', racc_token2str(t) }
       end
       out.puts " --> #{racc_token2str(sim)}"
-          
       racc_print_stacks tstack, vstack
       @racc_debug_out.puts
     end
@@ -429,6 +625,7 @@ module Racc
           raise "[Racc Bug] can't convert token #{tok} to string"
     end
 
+    # Convert internal ID of token symbol to the string.
     def token_to_str(t)
       self.class::Racc_token_to_s_table[t]
     end
diff --git a/lib/racc/parser.rb b/lib/racc/parser.rb
index 13af8d7..d81428b 100644
--- a/lib/racc/parser.rb
+++ b/lib/racc/parser.rb
@@ -1,5 +1,5 @@
 #
-# $Id: ad1fffef443194fdfa1052d2eee6850552f94313 $
+# $Id: a7af944d201a32a63d2536cdd589d8e9910848e0 $
 #
 # Copyright (c) 1999-2006 Minero Aoki
 #
@@ -11,8 +11,10 @@
 # without restriction.
 #
 
+require 'racc/info'
+
 unless defined?(NotImplementedError)
-  NotImplementedError = NotImplementError
+  NotImplementedError = NotImplementError # :nodoc:
 end
 
 module Racc
@@ -22,21 +24,180 @@ unless defined?(::ParseError)
   ParseError = Racc::ParseError
 end
 
+# Racc is a LALR(1) parser generator.
+# It is written in Ruby itself, and generates Ruby programs.
+#
+# == Command-line Reference
+#
+#     racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
+#          [-e<var>rubypath</var>] [--embedded=<var>rubypath</var>]
+#          [-v] [--verbose]
+#          [-O<var>filename</var>] [--log-file=<var>filename</var>]
+#          [-g] [--debug]
+#          [-E] [--embedded]
+#          [-l] [--no-line-convert]
+#          [-c] [--line-convert-all]
+#          [-a] [--no-omit-actions]
+#          [-C] [--check-only]
+#          [-S] [--output-status]
+#          [--version] [--copyright] [--help] <var>grammarfile</var>
+#
+# [+filename+]
+#   Racc grammar file. Any extention is permitted.
+# [-o+outfile+, --output-file=+outfile+]
+#   A filename for output. default is <+filename+>.tab.rb
+# [-O+filename+, --log-file=+filename+]
+#   Place logging output in file +filename+.
+#   Default log file name is <+filename+>.output.
+# [-e+rubypath+, --executable=+rubypath+]
+#   output executable file(mode 755). where +path+ is the Ruby interpreter.
+# [-v, --verbose]
+#   verbose mode. create +filename+.output file, like yacc's y.output file.
+# [-g, --debug]
+#   add debug code to parser class. To display debuggin information,
+#   use this '-g' option and set @yydebug true in parser class.
+# [-E, --embedded]
+#   Output parser which doesn't need runtime files (racc/parser.rb).
+# [-C, --check-only]
+#   Check syntax of racc grammer file and quit.
+# [-S, --output-status]
+#   Print messages time to time while compiling.
+# [-l, --no-line-convert]
+#   turns off line number converting.
+# [-c, --line-convert-all]
+#   Convert line number of actions, inner, header and footer.
+# [-a, --no-omit-actions]
+#   Call all actions, even if an action is empty.
+# [--version]
+#   print Racc version and quit.
+# [--copyright]
+#   Print copyright and quit.
+# [--help]
+#   Print usage and quit.
+#
+# == Generating Parser Using Racc
+#
+# To compile Racc grammar file, simply type:
+#
+#   $ racc parse.y
+#
+# This creates Ruby script file "parse.tab.y". The -o option can change the output filename.
+#
+# == Writing A Racc Grammar File
+#
+# If you want your own parser, you have to write a grammar file.
+# A grammar file contains the name of your parser class, grammar for the parser,
+# user code, and anything else.
+# When writing a grammar file, yacc's knowledge is helpful.
+# If you have not used yacc before, Racc is not too difficult.
+#
+# Here's an example Racc grammar file.
+#
+#   class Calcparser
+#   rule
+#     target: exp { print val[0] }
+#
+#     exp: exp '+' exp
+#        | exp '*' exp
+#        | '(' exp ')'
+#        | NUMBER
+#   end
+#
+# Racc grammar files resemble yacc files.
+# But (of course), this is Ruby code.
+# yacc's $$ is the 'result', $0, $1... is
+# an array called 'val', and $-1, $-2... is an array called '_values'.
+#
+# See the {Grammar File Reference}[rdoc-ref:lib/racc/rdoc/grammar.en.rdoc] for
+# more information on grammar files.
+#
+# == Parser
+#
+# Then you must prepare the parse entry method. There are two types of
+# parse methods in Racc, Racc::Parser#do_parse and Racc::Parser#yyparse
+#
+# Racc::Parser#do_parse is simple.
+#
+# It's yyparse() of yacc, and Racc::Parser#next_token is yylex().
+# This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
+# EOF is [false, false].
+# (TOKENSYMBOL is a Ruby symbol (taken from String#intern) by default.
+# If you want to change this, see the grammar reference.
+#
+# Racc::Parser#yyparse is little complicated, but useful.
+# It does not use Racc::Parser#next_token, instead it gets tokens from any iterator.
+#
+# For example, <code>yyparse(obj, :scan)</code> causes
+# calling +obj#scan+, and you can return tokens by yielding them from +obj#scan+.
+#
+# == Debugging
+#
+# When debugging, "-v" or/and the "-g" option is helpful.
+#
+# "-v" creates verbose log file (.output).
+# "-g" creates a "Verbose Parser".
+# Verbose Parser prints the internal status when parsing.
+# But it's _not_ automatic.
+# You must use -g option and set + at yydebug+ to +true+ in order to get output.
+# -g option only creates the verbose parser.
+#
+# === Racc reported syntax error.
+#
+# Isn't there too many "end"?
+# grammar of racc file is changed in v0.10.
+#
+# Racc does not use '%' mark, while yacc uses huge number of '%' marks..
+#
+# === Racc reported "XXXX conflicts".
+#
+# Try "racc -v xxxx.y".
+# It causes producing racc's internal log file, xxxx.output.
+#
+# === Generated parsers does not work correctly
+#
+# Try "racc -g xxxx.y".
+# This command let racc generate "debugging parser".
+# Then set @yydebug=true in your parser.
+# It produces a working log of your parser.
+#
+# == Re-distributing Racc runtime
+#
+# A parser, which is created by Racc, requires the Racc runtime module;
+# racc/parser.rb.
+#
+# Ruby 1.8.x comes with Racc runtime module,
+# you need NOT distribute Racc runtime files.
+#
+# If you want to include the Racc runtime module with your parser.
+# This can be done by using '-E' option:
+#
+#   $ racc -E -omyparser.rb myparser.y
+#
+# This command creates myparser.rb which `includes' Racc runtime.
+# Only you must do is to distribute your parser file (myparser.rb).
+#
+# Note: parser.rb is LGPL, but your parser is not.
+# Your own parser is completely yours.
 module Racc
 
   unless defined?(Racc_No_Extentions)
-    Racc_No_Extentions = false
+    Racc_No_Extentions = false # :nodoc:
   end
 
   class Parser
 
-    Racc_Runtime_Version = '1.4.6'
-    Racc_Runtime_Revision = '$Id: ad1fffef443194fdfa1052d2eee6850552f94313 $'
+    Racc_Runtime_Version = ::Racc::VERSION
+    Racc_Runtime_Revision = '$Id: a7af944d201a32a63d2536cdd589d8e9910848e0 $'
 
-    Racc_Runtime_Core_Version_R = '1.4.6'
-    Racc_Runtime_Core_Revision_R = '$Id: ad1fffef443194fdfa1052d2eee6850552f94313 $'.split[1]
+    Racc_Runtime_Core_Version_R = ::Racc::VERSION
+    Racc_Runtime_Core_Revision_R = '$Id: a7af944d201a32a63d2536cdd589d8e9910848e0 $'.split[1]
     begin
-      require 'racc/cparse'
+      if RUBY_ENGINE == 'jruby'
+        require 'racc/cparse-jruby.jar'
+        com.headius.racc.Cparse.new.load(JRuby.runtime, false)
+      else
+        require 'racc/cparse'
+      end
     # Racc_Runtime_Core_Version_C  = (defined in extention)
       Racc_Runtime_Core_Revision_C = Racc_Runtime_Core_Id_C.split[2]
       unless new.respond_to?(:_racc_do_parse_c, true)
@@ -46,12 +207,14 @@ module Racc
         raise LoadError, 'selecting ruby version of racc runtime core'
       end
 
-      Racc_Main_Parsing_Routine    = :_racc_do_parse_c
-      Racc_YY_Parse_Method         = :_racc_yyparse_c
-      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_C
-      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_C
-      Racc_Runtime_Type            = 'c'
+      Racc_Main_Parsing_Routine    = :_racc_do_parse_c # :nodoc:
+      Racc_YY_Parse_Method         = :_racc_yyparse_c # :nodoc:
+      Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_C # :nodoc:
+      Racc_Runtime_Core_Revision   = Racc_Runtime_Core_Revision_C # :nodoc:
+      Racc_Runtime_Type            = 'c' # :nodoc:
     rescue LoadError
+puts $!
+puts $!.backtrace
       Racc_Main_Parsing_Routine    = :_racc_do_parse_rb
       Racc_YY_Parse_Method         = :_racc_yyparse_rb
       Racc_Runtime_Core_Version    = Racc_Runtime_Core_Version_R
@@ -59,12 +222,10 @@ module Racc
       Racc_Runtime_Type            = 'ruby'
     end
 
-    def Parser.racc_runtime_type
+    def Parser.racc_runtime_type # :nodoc:
       Racc_Runtime_Type
     end
 
-    private
-
     def _racc_setup
       @yydebug = false unless self.class::Racc_debug_parser
       @yydebug = false unless defined?(@yydebug)
@@ -91,14 +252,33 @@ module Racc
       @racc_error_status = 0
     end
 
-    ###
-    ### do_parse
-    ###
-
+    # The entry point of the parser. This method is used with #next_token.
+    # If Racc wants to get token (and its value), calls next_token.
+    #
+    # Example:
+    #     def parse
+    #       @q = [[1,1],
+    #             [2,2],
+    #             [3,3],
+    #             [false, '$']]
+    #       do_parse
+    #     end
+    #
+    #     def next_token
+    #       @q.shift
+    #     end
     def do_parse
       __send__(Racc_Main_Parsing_Routine, _racc_setup(), false)
     end
 
+    # The method to fetch next token.
+    # If you use #do_parse method, you must implement #next_token.
+    #
+    # The format of return value is [TOKEN_SYMBOL, VALUE].
+    # +token-symbol+ is represented by Ruby's symbol by default, e.g. :IDENT
+    # for 'IDENT'.  ";" (String) for ';'.
+    #
+    # The final symbol (End of file) must be false.
     def next_token
       raise NotImplementedError, "#{self.class}\#next_token is not defined"
     end
@@ -142,12 +322,13 @@ module Racc
       }
     end
 
-    ###
-    ### yyparse
-    ###
-
+    # Another entry point for the parser.
+    # If you use this method, you must implement RECEIVER#METHOD_ID method.
+    #
+    # RECEIVER#METHOD_ID is a method to get next token.
+    # It must 'yield' the token, which format is [TOKEN-SYMBOL, VALUE].
     def yyparse(recv, mid)
-      __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), true)
+      __send__(Racc_YY_Parse_Method, recv, mid, _racc_setup(), false)
     end
 
     def _racc_yyparse_rb(recv, mid, arg, c_debug)
@@ -340,27 +521,43 @@ module Racc
       goto_default[k1]
     end
 
+    # This method is called when a parse error is found.
+    #
+    # ERROR_TOKEN_ID is an internal ID of token which caused error.
+    # You can get string representation of this ID by calling
+    # #token_to_str.
+    #
+    # ERROR_VALUE is a value of error token.
+    #
+    # value_stack is a stack of symbol values.
+    # DO NOT MODIFY this object.
+    #
+    # This method raises ParseError by default.
+    #
+    # If this method returns, parsers enter "error recovering mode".
     def on_error(t, val, vstack)
       raise ParseError, sprintf("\nparse error on value %s (%s)",
                                 val.inspect, token_to_str(t) || '?')
     end
 
+    # Enter error recovering mode.
+    # This method does not call #on_error.
     def yyerror
       throw :racc_jump, 1
     end
 
+    # Exit parser.
+    # Return value is Symbol_Value_Stack[0].
     def yyaccept
       throw :racc_jump, 2
     end
 
+    # Leave error recovering mode.
     def yyerrok
       @racc_error_status = 0
     end
 
-    #
-    # for debugging output
-    #
-
+    # For debugging output
     def racc_read_token(t, tok, val)
       @racc_debug_out.print 'read    '
       @racc_debug_out.print tok.inspect, '(', racc_token2str(t), ') '
@@ -383,7 +580,6 @@ module Racc
         toks.each {|t| out.print ' ', racc_token2str(t) }
       end
       out.puts " --> #{racc_token2str(sim)}"
-          
       racc_print_stacks tstack, vstack
       @racc_debug_out.puts
     end
@@ -427,6 +623,7 @@ module Racc
           raise "[Racc Bug] can't convert token #{tok} to string"
     end
 
+    # Convert internal ID of token symbol to the string.
     def token_to_str(t)
       self.class::Racc_token_to_s_table[t]
     end
diff --git a/lib/racc/parserfilegenerator.rb b/lib/racc/parserfilegenerator.rb
index 99fa7a6..1c0d790 100644
--- a/lib/racc/parserfilegenerator.rb
+++ b/lib/racc/parserfilegenerator.rb
@@ -1,5 +1,5 @@
 #
-# $Id: 75aee0ac3cd6429e28eac511d78a717614123a89 $
+# $Id: f2d2788af2323ada1913f1dad5fea8aae4cc6830 $
 #
 # Copyright (c) 1999-2006 Minero Aoki
 #
@@ -478,7 +478,7 @@ module Racc
     end
 
     def unindent_auto(str)
-      lines = str.to_a
+      lines = str.lines.to_a
       n = minimum_indent(lines)
       lines.map {|line| detab(line).sub(indent_re(n), '').rstrip + "\n" }.join('')
     end
diff --git a/metadata.yml b/metadata.yml
index 1100b78..af88043 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,67 +1,78 @@
 --- !ruby/object:Gem::Specification
 name: racc
 version: !ruby/object:Gem::Version
-  version: 1.4.9
-  prerelease: 
+  version: 1.4.12
 platform: ruby
 authors:
 - Aaron Patterson
 autorequire: 
 bindir: bin
 cert_chain: []
-date: 2012-08-07 00:00:00.000000000 Z
+date: 2014-08-26 00:00:00.000000000 Z
 dependencies:
 - !ruby/object:Gem::Dependency
   name: rdoc
   requirement: !ruby/object:Gem::Requirement
-    none: false
     requirements:
-    - - ~>
+    - - "~>"
       - !ruby/object:Gem::Version
-        version: '3.10'
+        version: '4.0'
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
-    none: false
     requirements:
-    - - ~>
+    - - "~>"
       - !ruby/object:Gem::Version
-        version: '3.10'
+        version: '4.0'
 - !ruby/object:Gem::Dependency
   name: rake-compiler
   requirement: !ruby/object:Gem::Requirement
-    none: false
     requirements:
-    - - ! '>='
+    - - ">="
       - !ruby/object:Gem::Version
         version: 0.4.1
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
-    none: false
     requirements:
-    - - ! '>='
+    - - ">="
       - !ruby/object:Gem::Version
         version: 0.4.1
 - !ruby/object:Gem::Dependency
+  name: minitest
+  requirement: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '4.7'
+  type: :development
+  prerelease: false
+  version_requirements: !ruby/object:Gem::Requirement
+    requirements:
+    - - "~>"
+      - !ruby/object:Gem::Version
+        version: '4.7'
+- !ruby/object:Gem::Dependency
   name: hoe
   requirement: !ruby/object:Gem::Requirement
-    none: false
     requirements:
-    - - ~>
+    - - "~>"
       - !ruby/object:Gem::Version
-        version: '3.0'
+        version: '3.12'
   type: :development
   prerelease: false
   version_requirements: !ruby/object:Gem::Requirement
-    none: false
     requirements:
-    - - ~>
+    - - "~>"
       - !ruby/object:Gem::Version
-        version: '3.0'
-description: ! "Racc is a LALR(1) parser generator.\n  It is written in Ruby itself,
-  and generates Ruby program.\n\n  NOTE: Ruby 1.8.x comes with Racc runtime module.
-  \ You\n  can run your parsers generated by racc 1.4.x out of the\n  box."
+        version: '3.12'
+description: |-
+  Racc is a LALR(1) parser generator.
+    It is written in Ruby itself, and generates Ruby program.
+
+    NOTE: Ruby 1.8.x comes with Racc runtime module.  You
+    can run your parsers generated by racc 1.4.x out of the
+    box.
 email:
 - aaron at tenderlovemaking.com
 executables:
@@ -75,14 +86,13 @@ extra_rdoc_files:
 - README.ja.rdoc
 - README.rdoc
 - rdoc/en/NEWS.en.rdoc
-- rdoc/en/debug.en.rdoc
 - rdoc/en/grammar.en.rdoc
-- rdoc/en/parser.en.rdoc
 - rdoc/ja/NEWS.ja.rdoc
 - rdoc/ja/debug.ja.rdoc
 - rdoc/ja/grammar.ja.rdoc
 - rdoc/ja/parser.ja.rdoc
 files:
+- ".gemtest"
 - COPYING
 - ChangeLog
 - DEPENDS
@@ -95,6 +105,7 @@ files:
 - bin/racc2y
 - bin/y2racc
 - ext/racc/MANIFEST
+- ext/racc/com/headius/racc/Cparse.java
 - ext/racc/cparse.c
 - ext/racc/depend
 - ext/racc/extconf.rb
@@ -119,12 +130,7 @@ files:
 - lib/racc/static.rb
 - misc/dist.sh
 - rdoc/en/NEWS.en.rdoc
-- rdoc/en/command.en.html
-- rdoc/en/debug.en.rdoc
 - rdoc/en/grammar.en.rdoc
-- rdoc/en/index.en.html
-- rdoc/en/parser.en.rdoc
-- rdoc/en/usage.en.html
 - rdoc/ja/NEWS.ja.rdoc
 - rdoc/ja/command.ja.html
 - rdoc/ja/debug.ja.rdoc
@@ -188,32 +194,31 @@ files:
 - test/testscanner.rb
 - web/racc.en.rhtml
 - web/racc.ja.rhtml
-- .gemtest
 homepage: http://i.loveruby.net/en/projects/racc/
-licenses: []
+licenses:
+- MIT
+metadata: {}
 post_install_message: 
 rdoc_options:
-- --main
+- "--main"
 - README.rdoc
 require_paths:
 - lib
 required_ruby_version: !ruby/object:Gem::Requirement
-  none: false
   requirements:
-  - - ! '>='
+  - - ">="
     - !ruby/object:Gem::Version
       version: '0'
 required_rubygems_version: !ruby/object:Gem::Requirement
-  none: false
   requirements:
-  - - ! '>='
+  - - ">="
     - !ruby/object:Gem::Version
       version: '0'
 requirements: []
-rubyforge_project: racc
-rubygems_version: 1.8.23
+rubyforge_project: 
+rubygems_version: 2.2.2
 signing_key: 
-specification_version: 3
+specification_version: 4
 summary: Racc is a LALR(1) parser generator
 test_files:
 - test/test_chk_y.rb
diff --git a/rdoc/en/command.en.html b/rdoc/en/command.en.html
deleted file mode 100644
index 7e2f712..0000000
--- a/rdoc/en/command.en.html
+++ /dev/null
@@ -1,78 +0,0 @@
-<h1>Racc Command Reference</h1>
-<p>
-racc [-o<var>filename</var>] [--output-file=<var>filename</var>]
-     [-e<var>rubypath</var>] [--embedded=<var>rubypath</var>]
-     [-v] [--verbose]
-     [-O<var>filename</var>] [--log-file=<var>filename</var>]
-     [-g] [--debug]
-     [-E] [--embedded]
-     [-l] [--no-line-convert]
-     [-c] [--line-convert-all]
-     [-a] [--no-omit-actions]
-     [-C] [--check-only]
-     [-S] [--output-status]
-     [--version] [--copyright] [--help] <var>grammarfile</var>
-</p>
-
-<dl>
-<dt><var>filename</var>
-<dd>
-Racc grammar file. Any extention is permitted.
-</dd>
-<dt>-o<var>outfile</var>, --output-file=<var>outfile</var>
-<dd>
-A filename for output. default is <filename>.tab.rb
-</dd>
-<dt>-O<var>filename</var>, --log-file=<var>filename</var>
-<dd>
-Place logging output in file <var>filename</var>.
-Default log file name is <var>filename</var>.output.
-</dd>
-<dt>-e<var>rubypath</var>, --executable=<var>rubypath</var>
-<dd>
-output executable file(mode 755). <var>path</var> is a path of ruby interpreter.
-</dd>
-<dt>-v, --verbose
-<dd>
-verbose mode. create <filename>.output file, like yacc's y.output file.
-</dd>
-<dt>-g, --debug
-<dd>
-add debug code to parser class. To display debuggin information,
-use this '-g' option and set @yydebug true in parser class.
-</dd>
-<dt>-E, --embedded
-<dd>
-Output parser which doesn't need runtime files (racc/parser.rb).
-</dd>
-<dt>-C, --check-only
-<dd>
-Check syntax of racc grammer file and quit.
-</dd>
-<dt>-S, --output-status
-<dd>
-Print messages time to time while compiling.
-</dd>
-<dt>-l, --no-line-convert
-<dd>
-turns off line number converting.
-</dd>
-<dt>-c, --line-convert-all
-<dd>
-Convert line number of actions, inner, header and footer.
-<dt>-a, --no-omit-actions
-<dd>
-Call all actions, even if an action is empty.
-</dd>
-<dt>--version
-<dd>
-print Racc version and quit.
-</dd>
-<dt>--copyright
-<dd>
-Print copyright and quit.
-<dt>--help
-<dd>
-Print usage and quit.
-</dd>
-</dl>
diff --git a/rdoc/en/debug.en.rdoc b/rdoc/en/debug.en.rdoc
deleted file mode 100644
index 4bf83c3..0000000
--- a/rdoc/en/debug.en.rdoc
+++ /dev/null
@@ -1,20 +0,0 @@
-= Debugging
-
-== Racc reported syntax error.
-
-Isn't there too many "end"?
-grammar of racc file is changed in v0.10.
-
-Racc does not use '%' mark, while yacc uses huge number of '%' marks..
-
-== Racc reported "XXXX conflicts".
-
-Try "racc -v xxxx.y".
-It causes producing racc's internal log file, xxxx.output.
-
-== Generated parsers does not work correctly
-
-Try "racc -g xxxx.y".
-This command let racc generate "debugging parser".
-Then set @yydebug=true in your parser.
-It produces a working log of your parser.
diff --git a/rdoc/en/index.en.html b/rdoc/en/index.en.html
deleted file mode 100644
index c6944e9..0000000
--- a/rdoc/en/index.en.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<h1>Racc User Manual</h1>
-<p>updated for version 1.4</p>
-<ul>
-<li><a href="usage.html">Usage</a>
-<li><a href="command.html">Racc Command Reference</a>
-<li><a href="grammar.html">Racc Grammar File Reference</a>
-<li><a href="parser.html">Racc::Parser class Reference</a>
-<li><a href="debug.html">Debugging Parser</a>
-<li><a href="NEWS.html">Release Note</a>
-</ul>
diff --git a/rdoc/en/parser.en.rdoc b/rdoc/en/parser.en.rdoc
deleted file mode 100644
index 977ca80..0000000
--- a/rdoc/en/parser.en.rdoc
+++ /dev/null
@@ -1,74 +0,0 @@
-= class Racc::Parser
-
-== Super Class
-
-Object
-
-== Instance Methods
-
-: do_parse -> Object
-    The entry point of parser. This method is used with #next_token.
-    If Racc wants to get token (and its value), calls next_token.
-
-      --
-      # Example
-      ---- inner
-        def parse
-          @q = [[1,1],
-                [2,2],
-                [3,3],
-                [false, '$']]
-          do_parse
-        end
-
-        def next_token
-          @q.shift
-        end
-      --
-
-: next_token -> [Symbol, Object]
-    [abstract method]
-
-    The method to fetch next token.  If you use #do_parse method,
-    you must implement #next_token.  The format of return value is
-    [TOKEN_SYMBOL, VALUE].  token-symbol is represented by Ruby's symbol
-    by default, e.g. :IDENT for 'IDENT'.  ";" (String) for ';'.
-
-    The final symbol (End of file) must be false.
-
-: yyparse( receiver, method_id )
-    The another entry point of parser.
-    If you use this method, you must implement RECEIVER#METHOD_ID method.
-
-    RECEIVER#METHOD_ID is a method to get next token.
-    It must 'yield's token, which format is [TOKEN-SYMBOL, VALUE].
-
-: on_error( error_token_id, error_value, value_stack )
-    This method is called when parse error is found.
-
-    ERROR_TOKEN_ID is an internal ID of token which caused error.
-    You can get string replesentation of this ID by calling
-    #token_to_str.
-
-    ERROR_VALUE is a value of error token.
-
-    value_stack is a stack of symbol values.
-    DO NOT MODIFY this object.
-
-    This method raises ParseError by default.
-
-    If this method returns, parsers enter "error recovering mode".
-
-: token_to_str( t ) -> String
-    Convert internal ID of token symbol to the string.
-
-: yyerror
-    Enter error recovering mode.
-    This method does not call #on_error.
-
-: yyerrok
-    Leave error recovering mode.
-
-: yyaccept
-    Exit parser.
-    Return value is Symbol_Value_Stack[0].
diff --git a/rdoc/en/usage.en.html b/rdoc/en/usage.en.html
deleted file mode 100644
index de5810e..0000000
--- a/rdoc/en/usage.en.html
+++ /dev/null
@@ -1,92 +0,0 @@
-<h1>Usage</h1>
-
-<h2>Generating Parser Using Racc</h2>
-<p>
-To compile Racc grammar file, simply type:
-</p>
-<pre>
-$ racc parse.y
-</pre>
-<p>
-This creates ruby script file "parse.tab.y". -o option changes this.
-</p>
-
-<h2>Writing Racc Grammer File</h2>
-<p>
-If you want your own parser, you have to write grammar file.
-A grammar file contains name of parser class, grammar the parser can parse,
-user code, and any.<br>
-When writing grammar file, yacc's knowledge is helpful.
-If you have not use yacc, also racc is too difficult.
-</p>
-<p>
-Here's example of Racc grammar file.
-</p>
-<pre>
-class Calcparser
-rule
-  target: exp { print val[0] }
-
-  exp: exp '+' exp
-     | exp '*' exp
-     | '(' exp ')'
-     | NUMBER
-end
-</pre>
-<p>
-Racc grammar file is resembles to yacc file.
-But (of cource), action is Ruby code. yacc's $$ is 'result', $0, $1... is
-an array 'val', $-1, $-2... is an array '_values'.
-</p>
-<p>
-Then you must prepare parse entry method. There's two types of
-racc's parse method, 
-<a href="parser.html#Racc%3a%3aParser-do_parse"><code>do_parse</code></a> and
-<a href="parser.html#Racc%3a%3aParser-yyparse"><code>yyparse</code></a>.
-</p>
-<p>
-"do_parse()" is simple. it is yyparse() of yacc, and "next_token()" is
-yylex(). This method must returns an array like [TOKENSYMBOL, ITS_VALUE].
-EOF is [false, false].
-(token symbol is ruby symbol (got by String#intern) as default.
- If you want to change this, see <a href="grammar.html#token">grammar reference</a>.
-</p>
-<p>
-"yyparse()" is little complecated, but useful. It does not use "next_token()",
-it gets tokens from any iterator. For example, "yyparse(obj, :scan)" causes
-calling obj#scan, and you can return tokens by yielding them from obj#scan.
-</p>
-<p>
-When debugging, "-v" or/and "-g" option is helpful.
-"-v" causes creating verbose log file (.output).
-"-g" causes creating "Verbose Parser".
-Verbose Parser prints internal status when parsing.
-But it is <em>not</em> automatic.
-You must use -g option and set @yydebug true to get output.
--g option only creates verbose parser.
-</p>
-
-<h3>re-distributing Racc runtime</h3>
-<p>
-A parser, which is created by Racc, requires Racc runtime module;
-racc/parser.rb.
-</p>
-<p>
-Ruby 1.8.x comes with racc runtime module,
-you need NOT distribute racc runtime files.
-</p>
-<p>
-If you want to run your parsers on ruby 1.6,
-you need re-distribute racc runtime module with your parser.
-It can be done by using '-E' option:
-<pre>
-$ racc -E -omyparser.rb myparser.y
-</pre>
-<p>
-This command creates myparser.rb which `includes' racc runtime.
-Only you must do is to distribute your parser file (myparser.rb).
-</p>
-<p>
-Note: parser.rb is LGPL, but your parser is not.
-Your own parser is completely yours.
-</p>
diff --git a/test/helper.rb b/test/helper.rb
index 6ad491a..616c4fb 100644
--- a/test/helper.rb
+++ b/test/helper.rb
@@ -1,11 +1,11 @@
 $VERBOSE = true
-require 'test/unit'
+require 'minitest/autorun'
 require 'racc/static'
 require 'fileutils'
 require 'tempfile'
 
 module Racc
-  class TestCase < Test::Unit::TestCase
+  class TestCase < MiniTest::Unit::TestCase
     PROJECT_DIR = File.expand_path(File.join(File.dirname(__FILE__), '..'))
 
     TEST_DIR = File.join(PROJECT_DIR, 'test')
@@ -22,10 +22,6 @@ module Racc
       File.join(PROJECT_DIR, 'ext'),
     ].join(':')
 
-    unless RUBY_VERSION >= '1.9'
-      undef :default_test
-    end
-
     def setup
       [OUT_DIR, TAB_DIR, LOG_DIR, ERR_DIR].each do |dir|
         FileUtils.mkdir_p(dir)
@@ -81,7 +77,7 @@ module Racc
     def ruby arg
       Dir.chdir(TEST_DIR) do
         Tempfile.open 'test' do |io|
-          cmd = "#{ENV['_']} -I #{INC} #{arg} 2>#{io.path}"
+          cmd = "#{ENV['_'] || Gem.ruby} -I #{INC} #{arg} 2>#{io.path}"
           result = system(cmd)
           assert(result, io.read)
         end
diff --git a/test/test_chk_y.rb b/test/test_chk_y.rb
index 117872a..cabad15 100644
--- a/test/test_chk_y.rb
+++ b/test/test_chk_y.rb
@@ -14,11 +14,10 @@ module Racc
     def test_compile_chk_y
       generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
 
-      fork {
-        eval(generator.generate_parser)
+      # it generates valid ruby
+      assert Module.new {
+        self.instance_eval(generator.generate_parser, __FILE__, __LINE__)
       }
-      Process.wait
-      assert_equal 0, $?.exitstatus
 
       grammar = @states.grammar
 
@@ -35,9 +34,10 @@ module Racc
 
       generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
 
-      fork { eval(generator.generate_parser) }
-      assert_equal 0, $?.exitstatus
-      Process.wait
+      # it generates valid ruby
+      assert Module.new {
+        self.instance_eval(generator.generate_parser, __FILE__, __LINE__)
+      }
 
       grammar = @states.grammar
 
diff --git a/test/test_scan_y.rb b/test/test_scan_y.rb
index 4ac8379..b5f9593 100644
--- a/test/test_scan_y.rb
+++ b/test/test_scan_y.rb
@@ -14,11 +14,10 @@ module Racc
     def test_compile
       generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
 
-      fork {
-        eval(generator.generate_parser)
+      # it generates valid ruby
+      assert Module.new {
+        self.class_eval(generator.generate_parser)
       }
-      Process.wait
-      assert_equal 0, $?.exitstatus
 
       grammar = @states.grammar
 
@@ -35,9 +34,10 @@ module Racc
 
       generator = Racc::ParserFileGenerator.new(@states, @result.params.dup)
 
-      fork { eval(generator.generate_parser) }
-      assert_equal 0, $?.exitstatus
-      Process.wait
+      # it generates valid ruby
+      assert Module.new {
+        self.class_eval(generator.generate_parser)
+      }
 
       grammar = @states.grammar
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/racc.git



More information about the Pkg-ruby-extras-commits mailing list