seattlerb / ruby_parser

ruby_parser is a ruby parser written in pure ruby. It outputs s-expressions which can be manipulated and converted back to ruby via the ruby2ruby gem.
http://www.zenspider.com/projects/ruby_parser.html
475 stars 102 forks source link

Fails to parse dxstr with exctly one evstr when passed as sole argument to function #303

Closed danini-the-panini closed 4 years ago

danini-the-panini commented 4 years ago

The following ruby strings fail to parse (using the Ruby26Parser):

p `#{foo}` # single evstr in dxstr as single argument to function
x.p `#{foo}` # single evstr in dxstr as single argument to method

It produces the following error:

Traceback (most recent call last):
    13: from bin/parse:13:in `<main>'
    12: from bin/parse:13:in `each'
    11: from bin/parse:15:in `block in <main>'
    10: from ruby_parser/lib/ruby_parser_extras.rb:1290:in `process'
     9: from ruby/2.7.0/lib/ruby/2.7.0/timeout.rb:110:in `timeout'
     8: from ruby/2.7.0/lib/ruby/2.7.0/timeout.rb:33:in `catch'
     7: from ruby/2.7.0/lib/ruby/2.7.0/timeout.rb:33:in `catch'
     6: from ruby/2.7.0/lib/ruby/2.7.0/timeout.rb:33:in `block in catch'
     5: from ruby/2.7.0/lib/ruby/2.7.0/timeout.rb:95:in `block in timeout'
     4: from ruby_parser/lib/ruby_parser_extras.rb:1302:in `block in process'
     3: from (eval):3:in `do_parse'
     2: from (eval):3:in `_racc_do_parse_c'
     1: from ruby_parser/lib/ruby26_parser.rb:4971:in `_reduce_270'
ruby_parser/lib/ruby_parser_extras.rb:129:in `arg_blk_pass': undefined method `sexp_type' for nil:NilClass (NoMethodError)

It appears to happen with or without parentheses around the argument.

The following ruby code is parsed without error:

`#{foo}` # dxtr by itself
x = `#{foo}` # dxtr being assigned
puts(`echo #{foo}`) # dxtr as arg with string literal(s) as well as an evstr
puts(`#{foo}#{bar}`) # dxtr as arg with more than one evstr
puts(`#{foo}`, bar) # when it's not the only arg
zenspider commented 4 years ago

I am unable to reproduce:

979 % rake debug R='p `#{foo}`'
s(:call, nil, :p, s(:dxstr, "", s(:evstr, s(:call, nil, :foo))))
980 % rake debug R='x.p `#{foo}`'
s(:call, s(:call, nil, :x), :p, s(:dxstr, "", s(:evstr, s(:call, nil, :foo))))
zenspider commented 4 years ago
ruby_parser/lib/ruby_parser_extras.rb:129:in `arg_blk_pass': undefined method `sexp_type' for nil:NilClass (NoMethodError)

That line number is off (should be 128) and implies that node1 being passed in is nil. What version are you using?

        | args opt_block_arg
                    {
                      result = call_args val
                      result = self.arg_blk_pass val[0], val[1]
                    }

This has to be the code in question, and a nil for val[0] should be impossible.

ETA: tho not reusing that first result seems like an error...

zenspider commented 4 years ago

I just cleaned up call_args entirely and removed arg_blk_pass as a result... This will address your problem, but not really, as I don't know how you got INTO this situation given the grammar.

danini-the-panini commented 4 years ago

Ah, my bad, I just checked my version now. It was happening on 3.14.0, but after updating to 3.14.1 the problem went away. 🤦‍♂

zenspider commented 4 years ago

No worries! Thanks!