Skip to content

Instantly share code, notes, and snippets.

@txus
Created August 29, 2012 12:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save txus/3511989 to your computer and use it in GitHub Desktop.
Save txus/3511989 to your computer and use it in GitHub Desktop.
Bug with rbx + racc gem (not stdlib)

Bug with Rubinius + Racc gem (not stdlib)

Using the Racc gem instead of the stdlib version (both of them are version 1.4.9) breaks with the latest rubinius, only when racc/parser is required twice.

$ rbx bug.rb

An exception occurred running bug.rb
    Missing or uninitialized constant: Racc::Parser::Racc_Runtime_Core_Id_C (NameError)

Backtrace:
                    Module(Class)#const_missing at kernel/common/module.rb:468
           Racc::Parser.__class_init__ (Parser) at /Users/txus/.rvm/gems/rbx-head@bug/gems/racc-1.4.9/lib/racc/parser.rb:41
                    Racc.__module_init__ (Racc) at /Users/txus/.rvm/gems/rbx-head@bug/gems/racc-1.4.9/lib/racc/parser.rb:31
                              Object#__script__ at /Users/txus/.rvm/gems/rbx-head@bug/gems/racc-1.4.9/lib/racc/parser.rb:25
                   Rubinius::CodeLoader.require at kernel/common/codeloader.rb:212
  Kernel(Object)#gem_original_require (require) at kernel/common/kernel.rb:631
                         Kernel(Object)#require at /Users/txus/.rvm/src/rbx-head/staging/lib/rubygems/custom_require.rb:36
                              Object#__script__ at lexer.rex.rb:7
                   Rubinius::CodeLoader.require at kernel/common/codeloader.rb:212
          Rubinius::CodeLoader.require_relative at kernel/common/codeloader19.rb:28
                Kernel(Object)#require_relative at kernel/common/kernel19.rb:176
                              Object#__script__ at parser.tab.rb:12
                   Rubinius::CodeLoader.require at kernel/common/codeloader.rb:212
          Rubinius::CodeLoader.require_relative at kernel/common/codeloader19.rb:28
                Kernel(Object)#require_relative at kernel/common/kernel19.rb:176
                              Object#__script__ at bug.rb:1
               Rubinius::CodeLoader#load_script at kernel/delta/codeloader.rb:68
               Rubinius::CodeLoader.load_script at kernel/delta/codeloader.rb:110
                        Rubinius::Loader#script at kernel/loader.rb:626
                          Rubinius::Loader#main at kernel/loader.rb:829

This is probably related to the double loading problem pointed out in this issue.

The strange thing is that it works with the Stdlib version, but not with the gem.

(A workaround to avoid failure is removing the require 'racc/parser' line on parser.tab.rb., thus avoid double loading).

require_relative 'parser.tab'
#
# lexer.rex
#
# Lexer
#
class Parser
macro
BLANK [\ ]
rule
. { [text, text] }
inner
def run(code)
scan_setup(code.strip)
tokens = []
while token = next_token
tokens << token
end
tokens
end
end
#--
# DO NOT MODIFY!!!!
# This file is automatically generated by rex 1.0.5
# from lexical definition file "lexer.rex".
#++
require 'racc/parser'
#
# lexer.rex
#
# Lexer
#
class Parser < Racc::Parser
require 'strscan'
class ScanError < StandardError ; end
attr_reader :lineno
attr_reader :filename
attr_accessor :state
def scan_setup(str)
@ss = StringScanner.new(str)
@lineno = 1
@state = nil
end
def action
yield
end
def scan_str(str)
scan_setup(str)
do_parse
end
alias :scan :scan_str
def load_file( filename )
@filename = filename
open(filename, "r") do |f|
scan_setup(f.read)
end
end
def scan_file( filename )
load_file(filename)
do_parse
end
def next_token
return if @ss.eos?
# skips empty actions
until token = _next_token or @ss.eos?; end
token
end
def _next_token
text = @ss.peek(1)
@lineno += 1 if text == "\n"
token = case @state
when nil
case
when (text = @ss.scan(/./))
action { [text, text] }
else
text = @ss.string[@ss.pos .. -1]
raise ScanError, "can not match: '" + text + "'"
end # if
else
raise ScanError, "undefined state: '" + state.to_s + "'"
end # case state
token
end # def _next_token
def run(code)
scan_setup(code.strip)
tokens = []
while token = next_token
tokens << token
end
tokens
end
end # class
#
# DO NOT MODIFY!!!!
# This file is automatically generated by Racc 1.4.7
# from Racc grammer file "".
#
require 'racc/parser.rb'
#
# generated by racc
#
require_relative 'lexer.rex'
class Parser < Racc::Parser
module_eval(<<'...end parser.y/module_eval...', 'parser.y', 22)
def filename
@filename
end
def on_error(t, val, vstack)
raise ParseError, sprintf("\nparse error on value %s (%s) #{@filename}:#{@line}",
val.inspect, token_to_str(t) || '?')
end
...end parser.y/module_eval...
##### State transition tables begin ###
racc_action_table = [
2, 3 ]
racc_action_check = [
1, 2 ]
racc_action_pointer = [
nil, 0, 1, nil ]
racc_action_default = [
-1, -2, -2, 4 ]
racc_goto_table = [
1 ]
racc_goto_check = [
1 ]
racc_goto_pointer = [
nil, 0 ]
racc_goto_default = [
nil, nil ]
racc_reduce_table = [
0, 0, :racc_error,
0, 3, :_reduce_1 ]
racc_reduce_n = 2
racc_shift_n = 4
racc_token_table = {
false => 0,
:error => 1 }
racc_nt_base = 2
racc_use_result_var = true
Racc_arg = [
racc_action_table,
racc_action_check,
racc_action_default,
racc_action_pointer,
racc_goto_table,
racc_goto_check,
racc_goto_default,
racc_goto_pointer,
racc_nt_base,
racc_reduce_table,
racc_token_table,
racc_shift_n,
racc_reduce_n,
racc_use_result_var ]
Racc_token_to_s_table = [
"$end",
"error",
"$start",
"Root" ]
Racc_debug_parser = false
##### State transition tables end #####
# reduce 0 omitted
module_eval(<<'.,.,', 'parser.y', 11)
def _reduce_1(val, _values, result)
result = []
result
end
.,.,
def _reduce_none(val, _values, result)
val[0]
end
end # class Parser
#
# Noscript grammar.
#
class Parser
# Declare tokens produced by the lexer
rule
# The trunk of the AST.
Root:
/* nothing */ { result = [] }
;
---- header ----
#
# generated by racc
#
require_relative 'lexer.rex'
---- inner ----
def filename
@filename
end
def on_error(t, val, vstack)
raise ParseError, sprintf("\nparse error on value %s (%s) #{@filename}:#{@line}",
val.inspect, token_to_str(t) || '?')
end
---- footer ----
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment