Skip to content

Instantly share code, notes, and snippets.

@pocke
Last active Sep 13, 2021
Embed
What would you like to do?
Run parser gem on a Ractor
require 'parser/current'
class Parser::Lexer
methods.grep(/^lex_en/).each do |m|
if m.end_with?('=')
singleton_class.undef_method m
else
v = __send__ m
singleton_class.undef_method m
eval <<~RUBY
def self.#{m}
#{v.inspect}
end
RUBY
end
end
private_methods.grep(/^_lex_/).each do |m|
if m.end_with?('=')
singleton_class.undef_method m
else
v = __send__ m
singleton_class.undef_method m
eval <<~RUBY
private_class_method def self.#{m}
#{v.inspect}
end
RUBY
end
end
lex_error = self.lex_error
singleton_class.undef_method :lex_error
eval <<~RUBY
def self.lex_error
#{lex_error.inspect}
end
RUBY
Ractor.make_shareable(PUNCTUATION)
Ractor.make_shareable(KEYWORDS)
Ractor.make_shareable(KEYWORDS_BEGIN)
Ractor.make_shareable(Literal::TYPES)
Ractor.make_shareable(Literal::DELIMITERS)
LEX_STATES.freeze
end
module Parser
class Ruby31
# It should be backported to racc
Ractor.make_shareable(Racc_arg)
Ractor.make_shareable(Racc_token_to_s_table)
end
end
# customized builder may solve the problem
class Parser::Builders::Default
methods.grep(/^emit_/).each do |m|
if m.end_with?('=')
singleton_class.undef_method m
else
v = __send__ m
singleton_class.undef_method m
eval <<~RUBY
def self.#{m}
#{v.inspect}
end
RUBY
end
end
end
rb = File.read(__FILE__)
r = Ractor.new(rb) do |rb|
Ractor.yield Parser::CurrentRuby.parse(rb)
Ractor.yield Parser::CurrentRuby.parse("class X;"+rb)
end
p r.take # dispaly AST
p r.take # display parse error
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment