🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

ruby_parser

Package Overview
Dependencies
Maintainers
1
Versions
80
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ruby_parser - rubygems Package Compare versions

Comparing version
2.3.1
to
3.0.0.a1
bin/ruby_parse_extract_error

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

+69
-0

@@ -0,1 +1,70 @@

=== 3.0.0.a1 / 2012-05-22
This is the first alpha release of the 3.0.0 series. It is probably
woefully incomplete, bug ridden, and hasn't showered in several days.
Please please please beat the crap out of it and send
bugs/patches/complaints/suggestions.
* 5 major enhancements:
* 1.9 parsing! Thanks to EVERYONE for submitting patches for this!
* Removed :arglist from everything but :op_asgn1
* Removed :block from resbody
* Removed :block from when
* Removed :block nodes inside of scope nodes (defn/defs/class/sclass).
* Removed :scope nodes in defn/defs/class/sclass nodes.
* (probably more sexp cleanup to come before 3.0.0 final)
* 25 minor enhancements:
* 1.9: Fix \!a. (wanabe)
* 1.9: Method calling with postargs. (wanabe)
* 1.9: Method definition with postargs. (wanabe)
* 1.9: Support lambda args without parentheses. (wanabe)
* Added R arg to `rake debug` to debug ruby straight up
* Added RubyParser, subclassing Ruby18Parser but warning on instantiation.
* Added backref_assign_error (needs tests)
* Added bin/ruby_parse_extract_error to help with error submissions
* Added debug task to help quickly get into a bug
* Added more 18 vs 19 lexing tests for ?c.
* Added ruby_parser.rb that pulls everything together in proper order.
* Added tLABEL. (brynary)
* Branched ruby_parser.y to ruby18_parser.y
* Fix to pass test_lambda_args_block__19 test. (mrmargolis)
* Got rid of one instance of unread_many. (Confusion)
* Moved everything from RubyParser to RubyParserStuff and included module in both.
* Refactored 1.9 args handling
* Refactored and added new_resbody to ruby_parser_extras.
* Refactored and added new_when
* Refactored tests infrastructure and added both 1.8 and 1.9 test branches.
* Removed unused methods: unread, begin_of_line? was_begin_of_line. (YAY!) (Confusion)
* Renamed ruby_parser.y to ruby19_parser.y
* RubyLexer now takes a version specifier.
* Started doing comparative refactoring between MRI's 1.9 parser and RP's. Shouldn't differ functionally except where we missed stuff in RP.
* `rake debug` prints the output if it succeeds.
* 21 bug fixes:
* Added missing gvar arg error. (1.8)
* Attach parser files to isolate to ensure they can build
* Conditionalize handling of tLABEL to ruby19+. Fixes issue #33.
* DOH. I deactivated some tests and never reactivated them. (Confusion ftw)
* Duplicate the input so that heredoc processing doesn't morph original. (banister)
* Entirely reworked block arg handling. (1.8)
* Fix ?x char literal. (nobu)
* Fixed 4/5 of literal lambda tests (jamie)
* Fixed deps for parser
* Fixed lexing of ?c for ruby 1.8 and 1.9.
* Fixed more Ruby 1.9 args tests (brynary)
* Fixed reswords to match MRI (1.8, 1.9)
* Fixed symbols with no spaces in method calls (e.g. foo:bar) (YAY! brynary)
* Fixed ternary_nil_no_space and other ternary edge cases for 1.9. (lastobelus)
* Fixed test_call_not_equal__19. First bug bounty! (albus522)
* Made lambda w/o arg list zero out the arg slot.
* Renamed awords to qwords to match stupid MRI naming. (1.8, 1.9) :(
* Rolled out brynary's symbols-no-spaces (foo:bar) changes when parsing 1.8 code
* Split 1.8 from 1.9 open paren lexer. Gawd that's ugly code.
* Split block_var from for_var. (1.8, 1.9)
* Use binread (and emulate in ruby 1.8) to avoid encoding issues
=== 2.3.1 / 2011-09-21

@@ -2,0 +71,0 @@

+130
-37

@@ -5,2 +5,3 @@ class RubyLexer

attr_accessor :cond
attr_accessor :tern
attr_accessor :nest

@@ -10,2 +11,8 @@

##
# What version of ruby to parse. 18 and 19 are the only valid values
# currently supported.
attr_accessor :version
# Additional context surrounding tokens that both the lexer and

@@ -40,3 +47,3 @@ # grammar use.

STR_FUNC_REGEXP = 0x04
STR_FUNC_AWORDS = 0x08
STR_FUNC_QWORDS = 0x08
STR_FUNC_SYMBOL = 0x10

@@ -64,2 +71,3 @@ STR_FUNC_INDENT = 0x20 # <<-HEREDOC

"=~" => :tMATCH,
"->" => :tLAMBDA,
}

@@ -137,3 +145,3 @@

until src.scan(eos_re) do
until src.check(eos_re) do
c = tokadd_string func, "\n", nil

@@ -154,5 +162,2 @@

end
# tack on a NL after the heredoc token - FIX NL should not be needed
src.unread_many(eos + "\n") # TODO: remove this... stupid stupid stupid
else

@@ -204,8 +209,6 @@ until src.check(eos_re) do

if src.check(/.*\n/) then
if src.scan(/.*\n/) then
# TODO: think about storing off the char range instead
line = src.string[src.pos, src.matched_size]
src.string[src.pos, src.matched_size] = "\n"
line = src.matched
src.extra_lines_added += 1
src.pos += 1
else

@@ -226,5 +229,7 @@ line = nil

def initialize
def initialize v = 18
self.version = v
self.cond = RubyParser::StackState.new(:cond)
self.cmdarg = RubyParser::StackState.new(:cmdarg)
self.tern = RubyParser::StackState.new(:tern)
self.nest = 0

@@ -320,6 +325,6 @@ @comments = []

src.scan(/\s*/)
[:tWORDS_BEG, STR_DQUOTE | STR_FUNC_AWORDS]
[:tWORDS_BEG, STR_DQUOTE | STR_FUNC_QWORDS]
when 'w' then
src.scan(/\s*/)
[:tAWORDS_BEG, STR_SQUOTE | STR_FUNC_AWORDS]
[:tQWORDS_BEG, STR_SQUOTE | STR_FUNC_QWORDS]
when 'x' then

@@ -350,3 +355,3 @@ [:tXSTRING_BEG, STR_XQUOTE]

awords = (func & STR_FUNC_AWORDS) != 0
qwords = (func & STR_FUNC_QWORDS) != 0
regexp = (func & STR_FUNC_REGEXP) != 0

@@ -360,6 +365,6 @@ expand = (func & STR_FUNC_EXPAND) != 0

space = true if awords and src.scan(/\s+/)
space = true if qwords and src.scan(/\s+/)
if self.nest == 0 && src.scan(/#{term_re}/) then
if awords then
if qwords then
quote[1] = nil

@@ -487,2 +492,6 @@ return :tSPACE

def ruby18
Ruby18Parser === parser
end
def src= src

@@ -514,3 +523,3 @@ raise "bad src: #{src.inspect}" unless String === src

def tokadd_string(func, term, paren) # 105 lines
awords = (func & STR_FUNC_AWORDS) != 0
qwords = (func & STR_FUNC_QWORDS) != 0
escape = (func & STR_FUNC_ESCAPE) != 0

@@ -535,3 +544,3 @@ expand = (func & STR_FUNC_EXPAND) != 0

self.nest -= 1
when awords && src.scan(/\s/) then
when qwords && src.scan(/\s/) then
src.pos -= 1

@@ -546,6 +555,6 @@ break

case
when awords && src.scan(/\\\n/) then
when qwords && src.scan(/\\\n/) then
string_buffer << "\n"
next
when awords && src.scan(/\\\s/) then
when qwords && src.scan(/\\\s/) then
c = ' '

@@ -579,3 +588,3 @@ when expand && src.scan(/\\\n/) then

x = Regexp.escape(paren) if paren && paren != "\000"
re = if awords then
re = if qwords then
/[^#{t}#{x}\#\0\\\n\ ]+|./ # |. to pick up whatever

@@ -649,3 +658,2 @@ else

def yylex # 826 lines
c = ''

@@ -707,2 +715,3 @@ space_seen = false

}[src.matched]
self.tern.lexpop if [:tRBRACK, :tRCURLY].include?(result)
return result

@@ -722,16 +731,8 @@ elsif src.scan(/\.\.\.?|,|![=~]?/) then

elsif src.scan(/\(/) then
result = :tLPAREN2
self.command_start = true
result = if ruby18 then
yylex_paren18 space_seen
else
yylex_paren19 space_seen
end
if lex_state == :expr_beg || lex_state == :expr_mid then
result = :tLPAREN
elsif space_seen then
if lex_state == :expr_cmdarg then
result = :tLPAREN_ARG
elsif lex_state == :expr_arg then
warning("don't put space before argument parentheses")
result = :tLPAREN2
end
end
self.expr_beg_push "("

@@ -829,5 +830,9 @@

elsif lex_state == :expr_beg || lex_state == :expr_mid then
self.tern.push false
result = :tLBRACK
elsif lex_state.is_argument && space_seen then
self.tern.push false
result = :tLBRACK
else
result = :tLBRACK2
end

@@ -861,2 +866,8 @@

elsif src.scan(/\{/) then
if defined?(@hack_expects_lambda) && @hack_expects_lambda
@hack_expects_lambda = false
self.lex_state = :expr_beg
return :tLAMBEG
end
result = if lex_state.is_argument || lex_state == :expr_end then

@@ -867,2 +878,3 @@ :tLCURLY # block (primary)

else
self.tern.push false
:tLBRACE # hash

@@ -875,2 +887,6 @@ end

return result
elsif src.scan(/->/) then
@hack_expects_lambda = true
self.lex_state = :expr_arg
return :tLAMBDA
elsif src.scan(/[+-]/) then

@@ -1021,2 +1037,3 @@ sign = src.matched

self.lex_state = :expr_beg
self.tern.push true
self.yacc_value = "?"

@@ -1046,2 +1063,3 @@ return :tEH

self.lex_state = :expr_beg
self.tern.push true
self.yacc_value = "?"

@@ -1051,2 +1069,3 @@ return :tEH

self.lex_state = :expr_beg
self.tern.push true
self.yacc_value = "?"

@@ -1062,4 +1081,10 @@ return :tEH

self.lex_state = :expr_end
self.yacc_value = c[0].ord & 0xff
return :tINTEGER
if version == 18 then
self.yacc_value = c[0].ord & 0xff
return :tINTEGER
else
self.yacc_value = c
return :tSTRING
end
elsif src.check(/\&/) then

@@ -1238,2 +1263,49 @@ if src.scan(/\&\&\=/) then

def yylex_paren18 space_seen
self.command_start = true
result = :tLPAREN2
if lex_state == :expr_beg || lex_state == :expr_mid then
result = :tLPAREN
elsif space_seen then
if lex_state == :expr_cmdarg then
result = :tLPAREN_ARG
elsif lex_state == :expr_arg then
self.tern.push false
warning "don't put space before argument parentheses"
end
else
self.tern.push false
end
result
end
def yylex_paren19 space_seen
if (lex_state == :expr_beg || lex_state == :expr_mid ||
lex_state == :expr_value || lex_state == :expr_class) then
result = :tLPAREN
elsif ((lex_state == :expr_arg || lex_state == :expr_cmdarg) and
space_seen) then
result = :tLPAREN_ARG
else
self.tern.push false
result = :tLPAREN2
end
# HACK paren_nest++;
# HACK: this is a mess, but it makes the tests pass, so suck it
# (stolen from the 1.8 side)
if lex_state == :expr_beg || lex_state == :expr_mid then
# do nothing
elsif space_seen then
if lex_state == :expr_arg then
self.tern.push false
end
else
self.tern.push false
end
result
end
def process_token(command_state)

@@ -1246,3 +1318,2 @@

case token

@@ -1275,2 +1346,20 @@ when /^\$/ then

unless self.tern.is_in_state
if (lex_state == :expr_beg && (ruby18 || !command_state)) ||
lex_state == :expr_arg ||
lex_state == :expr_cmdarg then
colon = src.scan(/:/)
if colon && src.peek(1) != ":"
src.unscan
self.lex_state = :expr_beg
src.scan(/:/)
self.yacc_value = [token, src.lineno]
return :tLABEL
end
src.unscan if colon
end
end unless ruby18
unless lex_state == :expr_dot then

@@ -1295,2 +1384,6 @@ # See if it is a reserved word.

return :kDO_BLOCK if state == :expr_endarg
if defined?(@hack_expects_lambda) && @hack_expects_lambda
@hack_expects_lambda = false
return :kDO_LAMBDA
end
return :kDO

@@ -1297,0 +1390,0 @@ end

@@ -6,6 +6,11 @@ require 'stringio'

def d o
$stderr.puts o.inspect
end
# WHY do I have to do this?!?
class Regexp
unless defined? ONCE then
ONCE = 0 # 16 # ?
ONCE = 0 unless defined? ONCE # FIX: remove this - it makes no sense
unless defined? ENC_NONE then
ENC_NONE = /x/n.options

@@ -51,7 +56,2 @@ ENC_EUC = /x/e.options

# TODO: current_line and lineno much more accurate and easy to do
def unread c # TODO: remove this entirely - we should not need it
return if c.nil? # UGH
warn({:unread => caller[0]}.inspect) if ENV['TALLY']
string[pos, 0] = c
end

@@ -64,10 +64,2 @@ def unread_many str # TODO: remove this entirely - we should not need it

def begin_of_line?
pos == 0 or string[pos-1] == ?\n
end
def was_begin_of_line # TODO: kill me
pos <= 2 or string[pos-2] == ?\n
end
if ENV['DEBUG'] then

@@ -84,3 +76,3 @@ alias :old_getch :getch

s = old_scan re
p :scan => [s, caller.first] if s
d :scan => [s, caller.first] if s
s

@@ -129,4 +121,4 @@ end

class RubyParser < Racc::Parser
VERSION = '2.3.1' unless constants.include? "VERSION" # SIGH
module RubyParserStuff
VERSION = '3.0.0.a1' unless constants.include? "VERSION" # SIGH

@@ -157,3 +149,28 @@ attr_accessor :lexer, :in_def, :in_single, :file

def args arg, optarg, rest_arg, block_arg
def block_var ary, splat, block
ary ||= s(:array)
if splat then
if splat == s(:splat) then
ary << splat
else
ary << s(:splat, splat)
end
end
if block then
block[-1] = :"&#{block[-1]}"
ary << block
end
result = if ary.length > 2 or ary.splat then
s(:masgn, ary)
else
ary.last
end
result
end
def args arg, optarg, rest_arg, block_arg, post_arg = nil
arg ||= s(:args)

@@ -170,4 +187,6 @@

result << rest_arg if rest_arg
result << :"&#{block_arg.last}" if block_arg
result << optarg if optarg # TODO? huh - processed above as well
post_arg[1..-1].each {|pa| result << pa } if post_arg

@@ -177,5 +196,41 @@ result

def args19 vals # TODO: migrate to args once 1.8 tests pass as well
result = s(:args)
block = nil
vals.each do |val|
case val
when Sexp then
case val.first
when :args then
val[1..-1].each do |name|
result << name
end
when :block_arg then
result << :"&#{val.last}"
when :block then
block = val
val[1..-1].each do |lasgn| # FIX clean sexp iter
raise "wtf? #{val.inspect}" unless lasgn[0] == :lasgn
result << lasgn[1]
end
else
raise "unhandled sexp: #{val.inspect}"
end
when Symbol then
result << val
when ",", nil then
# ignore
else
raise "unhandled val: #{val.inspect} in #{vals.inspect}"
end
end
result << block if block
result
end
def aryset receiver, index
index[0] = :arglist if index[0] == :array
s(:attrasgn, receiver, :"[]=", index)
s(:attrasgn, receiver, :"[]=", *index[1..-1])
end

@@ -299,3 +354,3 @@

return s(:call, lhs, :"=~", s(:arglist, rhs)).line(lhs.line)
return new_call(lhs, :"=~", argl(rhs)).line(lhs.line)
end

@@ -319,6 +374,4 @@

s(type, id)
elsif env.dynamic? and :dvar == env[id] then
s(:lvar, id)
else
s(:call, nil, id, s(:arglist))
new_call(nil, id)
end

@@ -345,3 +398,5 @@ end

super()
self.lexer = RubyLexer.new
v = self.class.name[/1[89]/]
self.lexer = RubyLexer.new v && v.to_i
self.lexer.parser = self

@@ -467,2 +522,19 @@ @env = Environment.new

def argl x
x = s(:arglist, x) if x and x[0] != :arglist
x
end
def backref_assign_error ref
# TODO: need a test for this... obviously
case ref.first
when :nth_ref then
raise SyntaxError, "Can't set variable %p" % ref.last
when :back_ref then
raise SyntaxError, "Can't set back reference %p" % ref.last
else
raise "Unknown backref type: #{ref.inspect}"
end
end
def new_call recv, meth, args = nil

@@ -472,6 +544,12 @@ result = s(:call, recv, meth)

# TODO: need a test with f(&b) to produce block_pass
# TODO: need a test with f(&b) { } to produce warning
args ||= s(:arglist)
args[0] = :arglist if args.first == :array
args = s(:arglist, args) unless args.first == :arglist
result << args
# HACK quick hack to make this work quickly... easy to clean up above
result.concat args[1..-1]
result

@@ -489,2 +567,7 @@ end

result[2..-1].each do |node|
block = node.block(:delete)
node.concat block[1..-1] if block
end
# else

@@ -500,4 +583,13 @@ body = nil if body == s(:block)

line, path, superclass, body = val[1], val[2], val[3], val[5]
scope = s(:scope, body).compact
result = s(:class, path, superclass, scope)
result = s(:class, path, superclass)
if body then
if body.first == :block then
result.push(*body[1..-1])
else
result.push body
end
end
result.line = line

@@ -518,6 +610,12 @@ result.comments = self.comments.pop

body ||= s(:block)
body = s(:block, body) unless body.first == :block
result = s(:defn, name.to_sym, args)
result = s(:defn, name.to_sym, args, s(:scope, body))
if body then
if body.first == :block then
result.push(*body[1..-1])
else
result.push body
end
end
result.line = line

@@ -531,6 +629,12 @@ result.comments = self.comments.pop

body ||= s(:block)
body = s(:block, body) unless body.first == :block
result = s(:defs, recv, name.to_sym, args)
result = s(:defs, recv, name.to_sym, args, s(:scope, body))
if body then
if body.first == :block then
result.push(*body[1..-1])
else
result.push body
end
end
result.line = recv.line

@@ -575,3 +679,3 @@ result.comments = self.comments.pop

body = s(:scope, body).compact
result = s(:module, path, body)
result = s(:module, path, *body[1..-1])
result.line = line

@@ -595,4 +699,3 @@ result.comments = self.comments.pop

# TODO: why [2] ?
lhs[2] = new_call(self.gettable(name), asgn_op,
s(:arglist, arg))
lhs[2] = new_call(self.gettable(name), asgn_op, argl(arg))
lhs

@@ -649,6 +752,24 @@ end

def new_resbody cond, body
if body && body.first == :block then
body.shift # remove block and splat it in directly
else
body = [body]
end
s(:resbody, cond, *body)
end
def new_sclass val
recv, in_def, in_single, body = val[3], val[4], val[6], val[7]
scope = s(:scope, body).compact
result = s(:sclass, recv, scope)
result = s(:sclass, recv)
if body then
if body.first == :block then
result.push(*body[1..-1])
else
result.push body
end
end
result.line = val[2]

@@ -677,2 +798,6 @@ self.in_def = in_def

def new_until block, expr, pre
new_until_or_while :until, block, expr, pre
end
def new_until_or_while type, block, expr, pre

@@ -695,4 +820,4 @@ other = type == :until ? :while : :until

def new_until block, expr, pre
new_until_or_while :until, block, expr, pre
def new_when cond, body
s(:when, cond, body)
end

@@ -748,8 +873,7 @@

case lhs[0]
when :gasgn, :iasgn, :lasgn, :dasgn, :dasgn_curr,
:masgn, :cdecl, :cvdecl, :cvasgn then
when :gasgn, :iasgn, :lasgn, :masgn, :cdecl, :cvdecl, :cvasgn then
lhs << rhs
when :attrasgn, :call then
args = lhs.pop unless Symbol === lhs.last
lhs << arg_add(args, rhs)
lhs.concat arg_add(args, rhs)[1..-1]
when :const then

@@ -769,3 +893,3 @@ lhs[0] = :cdecl

self.file = file
self.lexer.src = str
self.lexer.src = str.dup

@@ -836,6 +960,5 @@ @yydebug = ENV.has_key? 'DEBUG'

alias :old_yyerror :yyerror
def yyerror msg
# for now do nothing with the msg
old_yyerror
super
end

@@ -1026,2 +1149,18 @@

class Ruby19Parser < Racc::Parser
include RubyParserStuff
end
class Ruby18Parser < Racc::Parser
include RubyParserStuff
end
class RubyParser < Ruby18Parser
def initialize
super
warn "WA\RNING: Deprecated: RubyParser. Use Ruby18Parser or Ruby19Parser"
warn " from #{caller.first}"
end
end
############################################################

@@ -1052,2 +1191,10 @@ # HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK

def add x
raise "no" # TODO: need a test to trigger this
end
def add_all x
raise "no" # TODO: need a test to trigger this
end
alias :node_type :sexp_type

@@ -1054,0 +1201,0 @@ alias :values :sexp_body # TODO: retire

@@ -7,5 +7,9 @@ .autotest

bin/ruby_parse
bin/ruby_parse_extract_error
lib/gauntlet_rubyparser.rb
lib/ruby18_parser.rb
lib/ruby18_parser.y
lib/ruby19_parser.rb
lib/ruby19_parser.y
lib/ruby_lexer.rb
lib/ruby_parser.y
lib/ruby_parser.rb

@@ -12,0 +16,0 @@ lib/ruby_parser_extras.rb

@@ -19,3 +19,6 @@ # -*- ruby -*-

self.perforce_ignore << "lib/ruby_parser.rb" if plugin? :perforce
if plugin? :perforce then
self.perforce_ignore << "lib/ruby18_parser.rb"
self.perforce_ignore << "lib/ruby19_parser.rb"
end

@@ -25,2 +28,5 @@ self.racc_flags << " -g" if plugin?(:racc) && ENV["DEBUG"]

file "lib/ruby18_parser.rb" => "lib/ruby18_parser.y"
file "lib/ruby19_parser.rb" => "lib/ruby19_parser.y"
task :clean do

@@ -112,2 +118,60 @@ rm_rf(Dir["**/*~"] +

def (task(:phony)).timestamp
Time.at 0
end
task :isolate => :phony
file "lib/ruby18_parser.rb" => :isolate
file "lib/ruby19_parser.rb" => :isolate
task :compare18 do
sh "./yack.rb lib/ruby18_parser.output > racc18.txt"
sh "./yack.rb parse18.output > yacc18.txt"
sh "diff -du racc18.txt yacc18.txt || true"
puts
sh "diff -du racc18.txt yacc18.txt | wc -l"
end
task :compare19 do
sh "./yack.rb lib/ruby19_parser.output > racc19.txt"
sh "./yack.rb parse19.output > yacc19.txt"
sh "diff -du racc19.txt yacc19.txt || true"
puts
sh "diff -du racc19.txt yacc19.txt | wc -l"
end
task :debug => :isolate do
ENV["V"] ||= "18"
Rake.application[:parser].invoke # this way we can have DEBUG set
$: << "lib"
require 'ruby_parser'
parser = if ENV["V"] == "18" then
Ruby18Parser.new
else
Ruby19Parser.new
end
file = ENV["F"] || ENV["FILE"]
ruby = if file then
File.read(file)
else
file = "env"
ENV["R"] || ENV["RUBY"]
end
begin
p parser.process(ruby, file)
rescue Racc::ParseError => e
p e
ss = parser.lexer.src
src = ss.string
lines = src[0..ss.pos].split(/\n/)
abort "on #{file}:#{lines.size}"
end
end
# vim: syntax=Ruby
= ruby_parser
home :: https://github.com/seattlerb/ruby_parser
bugs :: https://github.com/seattlerb/ruby_parser/issues
rdoc :: http://docs.seattlerb.org/ruby_parser

@@ -50,4 +51,4 @@

RubyParser.new.parse "1+1"
# => s(:call, s(:lit, 1), :+, s(:array, s(:lit, 1)))
Ruby19Parser.new.parse "1+1"
# => s(:call, s(:lit, 1), :+, s(:lit, 1))

@@ -57,4 +58,3 @@ == REQUIREMENTS:

* ruby. woot.
* sexp_processor for Sexp and SexpProcessor classes.
* ParseTree for testing.
* sexp_processor for Sexp and SexpProcessor classes, and testing.
* racc full package for parser development (compiling .y to .rb).

@@ -70,3 +70,3 @@

Copyright (c) 2007-2008 Ryan Davis
Copyright (c) Ryan Davis, seattle.rb

@@ -73,0 +73,0 @@ Permission is hereby granted, free of charge, to any person obtaining

#!/usr/local/bin/ruby
require 'rubygems'
gem "minitest"
require 'minitest/autorun'
require 'ruby_lexer'
require 'ruby_parser'
require 'ruby18_parser'

@@ -12,3 +14,7 @@ class TestRubyLexer < MiniTest::Unit::TestCase

def setup
p = RubyParser.new
setup_lexer Ruby18Parser
end
def setup_lexer parser_class
p = parser_class.new
@lex = p.lexer

@@ -129,2 +135,34 @@ @lex.src = "blah blah"

def test_yylex_label__18
util_lex_token("{a:",
:tLBRACE, "{",
:tIDENTIFIER, "a",
:tSYMBEG, ":")
end
def test_yylex_label_in_params__18
util_lex_token("foo(a:",
:tIDENTIFIER, "foo",
:tLPAREN2, "(",
:tIDENTIFIER, "a",
:tSYMBEG, ":")
end
def test_yylex_label__19
setup_lexer Ruby19Parser
util_lex_token("{a:",
:tLBRACE, "{",
:tLABEL, "a")
end
def test_yylex_label_in_params__19
setup_lexer Ruby19Parser
util_lex_token("foo(a:",
:tIDENTIFIER, "foo",
:tLPAREN2, "(",
:tLABEL, "a")
end
def test_yylex_back_ref

@@ -615,3 +653,2 @@ util_lex_token("[$&, $`, $', $+]",

:tSTRING_CONTENT, "blah\nblah\n",
:tSTRING_CONTENT, "",
:tSTRING_END, "EOF",

@@ -634,3 +671,2 @@ :tNL, nil)

:tSTRING_CONTENT, "blah\nblah\n",
:tSTRING_CONTENT, "",
:tSTRING_END, "EOF",

@@ -812,10 +848,26 @@ :tNL, nil)

def test_yylex_integer_eh_a
util_lex_token '?a', :tINTEGER, 97
def test_yylex_question_eh_a__18
@lex = RubyLexer.new 18
util_lex_token "?a", :tINTEGER, 97
end
def test_yylex_integer_eh_escape_M_escape_C
def test_yylex_question_eh_a__19
@lex = RubyLexer.new 19
util_lex_token '?a', :tSTRING, "a"
end
def test_yylex_question_eh_escape_M_escape_C__18
@lex = RubyLexer.new 18
util_lex_token '?\M-\C-a', :tINTEGER, 129
end
def test_yylex_question_eh_escape_M_escape_C__19
@lex = RubyLexer.new 19
util_lex_token '?\M-\C-a', :tSTRING, "\M-\C-a"
end
def test_yylex_integer_hex

@@ -1036,3 +1088,3 @@ util_lex_token "0x2a", :tINTEGER, 42

:tIDENTIFIER, "m",
"[", "[",
:tLBRACK2, "[",
:tINTEGER, 3,

@@ -1098,6 +1150,14 @@ :tRBRACK, "]")

def test_yylex_question
def test_yylex_question__18
@lex = RubyLexer.new 18
util_lex_token "?*", :tINTEGER, 42
end
def test_yylex_question__19
@lex = RubyLexer.new 19
util_lex_token "?*", :tSTRING, "*"
end
def test_yylex_question_bad_eos

@@ -1116,3 +1176,5 @@ util_bad_token "?"

def test_yylex_question_ws_backslashed
def test_yylex_question_ws_backslashed__18
@lex = RubyLexer.new 18
@lex.lex_state = :expr_beg

@@ -1132,2 +1194,19 @@ util_lex_token "?\\ ", :tINTEGER, 32

def test_yylex_question_ws_backslashed__19
@lex = RubyLexer.new 19
@lex.lex_state = :expr_beg
util_lex_token "?\\ ", :tSTRING, " "
@lex.lex_state = :expr_beg
util_lex_token "?\\n", :tSTRING, "\n"
@lex.lex_state = :expr_beg
util_lex_token "?\\t", :tSTRING, "\t"
@lex.lex_state = :expr_beg
util_lex_token "?\\v", :tSTRING, "\v"
@lex.lex_state = :expr_beg
util_lex_token "?\\r", :tSTRING, "\r"
@lex.lex_state = :expr_beg
util_lex_token "?\\f", :tSTRING, "\f"
end
def test_yylex_rbracket

@@ -1626,3 +1705,3 @@ util_lex_token "]", :tRBRACK, "]"

util_bad_token("%w[s1 s2 ",
:tAWORDS_BEG, "%w[",
:tQWORDS_BEG, "%w[",
:tSTRING_CONTENT, "s1",

@@ -1636,3 +1715,3 @@ :tSPACE, nil,

util_lex_token("%w[s1 \\\ns2]",
:tAWORDS_BEG, "%w[",
:tQWORDS_BEG, "%w[",
:tSTRING_CONTENT, "s1",

@@ -1647,3 +1726,3 @@ :tSPACE, nil,

util_lex_token("%w[s\\ 1 s\\ 2]",
:tAWORDS_BEG, "%w[",
:tQWORDS_BEG, "%w[",
:tSTRING_CONTENT, "s 1",

@@ -1658,3 +1737,3 @@ :tSPACE, nil,

util_lex_token("%w[abc\tdef]",
:tAWORDS_BEG, "%w[",
:tQWORDS_BEG, "%w[",
:tSTRING_CONTENT, "abc\tdef",

@@ -1836,3 +1915,3 @@ :tSPACE, nil,

assert @lex.advance, "no more tokens"
assert_equal [token, value], [@lex.token, [@lex.yacc_value].flatten.first]
assert_equal [token, value], [@lex.token, [@lex.yacc_value].flatten.first], input
end

@@ -1839,0 +1918,0 @@

require 'rubygems'
gem "minitest"
require 'minitest/autorun'
require 'ruby_parser_extras'
require 'minitest/unit'
class TestStackState < MiniTest::Unit::TestCase

@@ -6,0 +9,0 @@ attr_reader :s

@@ -6,2 +6,3 @@ #!/usr/local/bin/ruby

require 'rubygems'
gem "minitest"
require 'minitest/autorun'

@@ -14,3 +15,3 @@ require 'ruby_parser'

class RubyParser
class Ruby18Parser # FIX
def process input

@@ -21,3 +22,11 @@ parse input

class Ruby19Parser
def process input
parse input
end
end
class RubyParserTestCase < ParseTreeTestCase
attr_accessor :result, :processor
def self.previous key

@@ -35,13 +44,3 @@ "Ruby"

end
end
class TestRubyParser < RubyParserTestCase
attr_accessor :result, :processor
def setup
super
self.processor = RubyParser.new
end
def assert_parse rb, pt

@@ -56,3 +55,5 @@ self.result = processor.parse rb

end
end
module TestRubyParser
def test_attrasgn_array_lhs

@@ -63,7 +64,6 @@ rb = '[1, 2, 3, 4][from .. to] = ["a", "b", "c"]'

:[]=,
s(:arglist,
s(:dot2,
s(:call, nil, :from, s(:arglist)),
s(:call, nil, :to, s(:arglist))),
s(:array, s(:str, "a"), s(:str, "b"), s(:str, "c"))))
s(:dot2,
s(:call, nil, :from),
s(:call, nil, :to)),
s(:array, s(:str, "a"), s(:str, "b"), s(:str, "c")))

@@ -109,6 +109,6 @@ assert_parse rb, pt

def test_block_append_tail_block
head = s(:call, nil, :f1, s(:arglist))
head = s(:call, nil, :f1)
tail = s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y)))
expected = s(:block,
s(:call, nil, :f1, s(:arglist)),
s(:call, nil, :f1),
s(:block, s(:undef, s(:lit, :x)), s(:undef, s(:lit, :y))))

@@ -118,6 +118,13 @@ assert_equal expected, processor.block_append(head, tail)

def test_call_array_arg
rb = "1 == [:b, :c]"
pt = s(:call, s(:lit, 1), :==, s(:array, s(:lit, :b), s(:lit, :c)))
assert_parse rb, pt
end
def test_call_env
processor.env[:a] = :lvar
rb = "a.happy"
pt = s(:call, s(:lvar, :a), :happy, s(:arglist))
pt = s(:call, s(:lvar, :a), :happy)

@@ -130,3 +137,3 @@ assert_parse rb, pt

pt = s(:iter,
s(:call, nil, :a, s(:arglist)),
s(:call, nil, :a),
nil,

@@ -147,4 +154,3 @@ s(:block,

pt = s(:class, :X, nil,
s(:scope,
s(:defn, :blah, s(:args), s(:scope, s(:block, s(:nil))))))
s(:defn, :blah, s(:args), s(:nil)))

@@ -154,3 +160,3 @@ assert_parse rb, pt

assert_equal "# blah 1\n# blah 2\n\n", result.comments
assert_equal "# blah 3\n", result.scope.defn.comments
assert_equal "# blah 3\n", result.defn.comments
end

@@ -161,8 +167,7 @@

pt = s(:module, :X,
s(:scope,
s(:defn, :blah, s(:args), s(:scope, s(:block, s(:nil))))))
s(:defn, :blah, s(:args), s(:nil)))
assert_parse rb, pt
assert_equal "# blah 1\n\n# blah 2\n\n", result.comments
assert_equal "# blah 3\n", result.scope.defn.comments
assert_equal "# blah 3\n", result.defn.comments
end

@@ -172,3 +177,3 @@

rb = "# blah 1\n# blah 2\n\ndef blah\nend"
pt = s(:defn, :blah, s(:args), s(:scope, s(:block, s(:nil))))
pt = s(:defn, :blah, s(:args), s(:nil))

@@ -181,3 +186,3 @@ assert_parse rb, pt

rb = "# blah 1\n# blah 2\n\ndef self.blah\nend"
pt = s(:defs, s(:self), :blah, s(:args), s(:scope, s(:block)))
pt = s(:defs, s(:self), :blah, s(:args))

@@ -191,5 +196,5 @@ assert_parse rb, pt

pt = s(:block,
s(:call, nil, :a, s(:arglist, s(:lit, 1))),
s(:call, nil, :a, s(:lit, 1)),
s(:iter,
s(:call, s(:call, nil, :a, s(:arglist)), :b, s(:arglist)),
s(:call, s(:call, nil, :a), :b),
s(:lasgn, :c)))

@@ -211,3 +216,3 @@

rb = 'g ( 1), 2'
pt = s(:call, nil, :g, s(:arglist, s(:lit, 1), s(:lit, 2)))
pt = s(:call, nil, :g, s(:lit, 1), s(:lit, 2))

@@ -223,7 +228,3 @@ assert_parse rb, pt

pt = s(:defn, :f, s(:args),
s(:scope,
s(:block,
s(:call, nil, :g,
s(:arglist,
s(:lit, 1), s(:lit, 2))))))
s(:call, nil, :g, s(:lit, 1), s(:lit, 2)))

@@ -243,3 +244,3 @@ assert_parse rb, pt

rb = "\"#\{'a'}#\{b}\""
pt = s(:dstr, "a", s(:evstr, s(:call, nil, :b, s(:arglist))))
pt = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))

@@ -265,3 +266,3 @@ assert_parse rb, pt

rb = "\"#\{a}#\{b}\""
pt = s(:dstr, "", s(:evstr, s(:call, nil, :a, s(:arglist))), s(:evstr, s(:call, nil, :b, s(:arglist))))
pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:evstr, s(:call, nil, :b)))

@@ -273,3 +274,3 @@ assert_parse rb, pt

rb = "\"#\{a} b\""
pt = s(:dstr, "", s(:evstr, s(:call, nil, :a, s(:arglist))), s(:str, " b"))
pt = s(:dstr, "", s(:evstr, s(:call, nil, :a)), s(:str, " b"))

@@ -331,5 +332,5 @@ assert_parse rb, pt

lhs = s(:dstr, "Failed to download spec ",
s(:evstr, s(:call, nil, :spec_name, s(:arglist))),
s(:evstr, s(:call, nil, :spec_name)),
s(:str, " from "),
s(:evstr, s(:call, nil, :source_uri, s(:arglist))),
s(:evstr, s(:call, nil, :source_uri)),
s(:str, ":\n"))

@@ -339,5 +340,5 @@ rhs = s(:dstr, "\t",

expected = s(:dstr, "Failed to download spec ",
s(:evstr, s(:call, nil, :spec_name, s(:arglist))),
s(:evstr, s(:call, nil, :spec_name)),
s(:str, " from "),
s(:evstr, s(:call, nil, :source_uri, s(:arglist))),
s(:evstr, s(:call, nil, :source_uri)),
s(:str, ":\n"),

@@ -351,4 +352,4 @@ s(:str, "\t"),

def test_literal_concat_dstr_evstr
lhs, rhs = s(:dstr, "a"), s(:evstr, s(:call, nil, :b, s(:arglist)))
expected = s(:dstr, "a", s(:evstr, s(:call, nil, :b, s(:arglist))))
lhs, rhs = s(:dstr, "a"), s(:evstr, s(:call, nil, :b))
expected = s(:dstr, "a", s(:evstr, s(:call, nil, :b)))

@@ -418,7 +419,7 @@ assert_equal expected, processor.literal_concat(lhs, rhs)

def test_logop_nested_mix
lhs = s(:or, s(:call, nil, :a, s(:arglist)), s(:call, nil, :b, s(:arglist)))
rhs = s(:and, s(:call, nil, :c, s(:arglist)), s(:call, nil, :d, s(:arglist)))
lhs = s(:or, s(:call, nil, :a), s(:call, nil, :b))
rhs = s(:and, s(:call, nil, :c), s(:call, nil, :d))
exp = s(:or,
s(:or, s(:call, nil, :a, s(:arglist)), s(:call, nil, :b, s(:arglist))),
s(:and, s(:call, nil, :c, s(:arglist)), s(:call, nil, :d, s(:arglist))))
s(:or, s(:call, nil, :a), s(:call, nil, :b)),
s(:and, s(:call, nil, :c), s(:call, nil, :d)))

@@ -433,3 +434,3 @@ lhs.paren = true

rb = "\"a #\{b}\""
pt = s(:dstr, "a ", s(:evstr, s(:call, nil, :b, s(:arglist))))
pt = s(:dstr, "a ", s(:evstr, s(:call, nil, :b)))

@@ -467,3 +468,3 @@ assert_parse rb, pt

rb = "%Q[before [#\{nest}] after]"
pt = s(:dstr, "before [", s(:evstr, s(:call, nil, :nest, s(:arglist))), s(:str, "] after"))
pt = s(:dstr, "before [", s(:evstr, s(:call, nil, :nest)), s(:str, "] after"))

@@ -522,3 +523,3 @@ assert_parse rb, pt

s(:lasgn, :a, s(:lit, 42)),
s(:call, nil, :p, s(:arglist, s(:lvar, :a))))
s(:call, nil, :p, s(:lvar, :a)))

@@ -542,5 +543,5 @@ assert_parse_line rb, pt, 1

pt = s(:iter,
s(:call, nil, :f, s(:arglist)),
s(:call, nil, :f),
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
s(:call, s(:lvar, :x), :+, s(:arglist, s(:lvar, :y))))
s(:call, s(:lvar, :x), :+, s(:lvar, :y)))

@@ -554,3 +555,3 @@ assert_parse_line rb, pt, 1

def test_parse_line_defn_no_parens
pt = s(:defn, :f, s(:args), s(:scope, s(:block, s(:nil))))
pt = s(:defn, :f, s(:args), s(:nil))

@@ -567,12 +568,9 @@ rb = "def f\nend"

pt = s(:defn, :x, s(:args, :y),
s(:scope,
s(:block,
s(:call, nil, :p, s(:arglist, s(:lvar, :y))),
s(:lasgn, :y,
s(:call, s(:lvar, :y), :*, s(:arglist, s(:lit, 2)))),
s(:return, s(:lvar, :y)))))
s(:call, nil, :p, s(:lvar, :y)),
s(:lasgn, :y, s(:call, s(:lvar, :y), :*, s(:lit, 2))),
s(:return, s(:lvar, :y)))
assert_parse_line rb, pt, 1
body = result.scope.block
body = result
assert_equal 2, body.call.line, "call should have line number"

@@ -587,5 +585,5 @@ assert_equal 3, body.lasgn.line, "lasgn should have line number"

pt = s(:iter,
s(:call, nil, :f, s(:arglist, s(:call, nil, :a, s(:arglist)))),
s(:call, nil, :f, s(:call, nil, :a)),
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
s(:call, s(:lvar, :x), :+, s(:arglist, s(:lvar, :y))))
s(:call, s(:lvar, :x), :+, s(:lvar, :y)))

@@ -603,5 +601,5 @@ assert_parse_line rb, pt, 1

pt = s(:iter,
s(:call, nil, :f, s(:arglist, s(:call, nil, :a, s(:arglist)))),
s(:call, nil, :f, s(:call, nil, :a)),
s(:masgn, s(:array, s(:lasgn, :x), s(:lasgn, :y))),
s(:call, s(:lvar, :x), :+, s(:arglist, s(:lvar, :y))))
s(:call, s(:lvar, :x), :+, s(:lvar, :y)))

@@ -645,13 +643,10 @@ assert_parse_line rb, pt, 1

pt = s(:defn, :blah, s(:args),
s(:scope,
s(:block,
s(:if,
s(:true),
s(:return, s(:lit, 42)),
nil))))
s(:if, s(:true),
s(:return, s(:lit, 42)),
nil))
assert_parse_line rb, pt, 1
assert_equal 3, result.scope.block.if.return.line
assert_equal 3, result.scope.block.if.return.lit.line
assert_equal 3, result.if.return.line
assert_equal 3, result.if.return.lit.line
end

@@ -662,3 +657,3 @@

pt = s(:if,
s(:call, s(:call, nil, :var, s(:arglist)), :nil?, s(:arglist)),
s(:call, s(:call, nil, :var), :nil?),
s(:str, "bar"),

@@ -674,3 +669,3 @@ s(:str, "foo"))

s(:not,
s(:call, s(:call, nil, :var, s(:arglist)), :nil?, s(:arglist))),
s(:call, s(:call, nil, :var), :nil?)),
s(:str, "foo"),

@@ -687,3 +682,3 @@ s(:str, "bar"))

pt = s(:until,
s(:call, s(:call, nil, :var, s(:arglist)), :nil?, s(:arglist)),
s(:call, s(:call, nil, :var), :nil?),
s(:str, "foo"), true)

@@ -698,3 +693,3 @@

s(:not,
s(:call, s(:call, nil, :var, s(:arglist)), :nil?, s(:arglist))),
s(:call, s(:call, nil, :var), :nil?)),
s(:str, "foo"), true)

@@ -711,3 +706,3 @@

pt = s(:while,
s(:call, s(:call, nil, :var, s(:arglist)), :nil?, s(:arglist)),
s(:call, s(:call, nil, :var), :nil?),
s(:str, "foo"), true)

@@ -722,3 +717,3 @@

s(:not,
s(:call, s(:call, nil, :var, s(:arglist)), :nil?, s(:arglist))),
s(:call, s(:call, nil, :var), :nil?)),
s(:str, "foo"), true)

@@ -731,1 +726,60 @@

end
class TestRuby18Parser < RubyParserTestCase
include TestRubyParser
def setup
super
self.processor = Ruby18Parser.new
end
def test_flip2_env_lvar
rb = "if a..b then end"
pt = s(:if, s(:flip2, s(:call, nil, :a), s(:call, nil, :b)), nil, nil)
assert_parse rb, pt
top_env = processor.env.env.first
assert_kind_of Hash, top_env
flip = top_env.find { |k,v| k =~ /^flip/ }
assert flip
assert_equal :lvar, flip.last
end
end
class TestRuby19Parser < RubyParserTestCase
include TestRubyParser
def setup
super
self.processor = Ruby19Parser.new
end
# HACK: need to figure out the desired structure and get this working
# def test_wtf
# # lambda -> f_larglist lambda_body
# # f_larglist -> f_args opt_bv_decl
# # opt_bv_decl
# # bv_decls
# # bvar
#
# rb = "->(a, b=nil) { p [a, b] }"
# pt = s(:iter,
# s(:call, nil, :lambda),
# s(:args, :a, :b,
# s(:block, s(:lasgn, :b, s(nil)))),
# s(:call, nil, :p, s(:array, s(:lvar, :a), s(:lvar, :b))))
#
# assert_parse rb, pt
#
# rb = "->(a; b) { p [a, b] }"
#
# assert_parse rb, pt
# end
end

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display