public
Created

Bug with rbx + racc gem (not stdlib)

  • Download Gist
Readme.md
Markdown

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).

bug.rb
Ruby
1
require_relative 'parser.tab'
lexer.rex
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#
# 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
lexer.rex.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
#--
# 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
parser.tab.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#
# 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
parser.y
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
#
# 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 ----

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.