[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