Project

General

Profile

Bug #4364

Ripper loses MLHS variables in the presence of an LHS splat

Added by adgar (Michael Edgar) about 9 years ago. Updated almost 9 years ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 1.9.3dev (2011-02-04 trunk 30778) [x86_64-darwin10.6.0]
Backport:
[ruby-core:35078]

Description

=begin
Ripper.sexp currently mis-parses the following LHS forms:

*b, c = ...
*, a = ...
a, *, b = ...

Specifically, in all 3 cases, the variables after the splat are not present in the resulting AST. The cause is simply missing mlhs_add calls in parse.y.

Here is the output of the trunk Ripper.sexp:

pp Ripper.sexp('*, b = 1, 2, 3')
[:program,
[[:massign,
[:mlhs_add_star, [], nil],
[:mrhs_new_from_args,
:@int, "1", [1, 7, [:@int, "2", [1, 10]]],
[:@int, "3", [1, 13]]]]]]

pp Ripper.sexp('*b, c = 1, 2, 3')
[:program,
[[:massign,
[:mlhs_add_star, [], [:@ident, "b", [1, 1]]],
[:mrhs_new_from_args,
:@int, "1", [1, 8, [:@int, "2", [1, 11]]],
[:@int, "3", [1, 14]]]]]]

pp Ripper.sexp('a, *, c = 1, 2, 3')
[:program,
[[:massign,
[:mlhs_add_star, :@ident, "a", [1, 0], nil],
[:mrhs_new_from_args,
:@int, "1", [1, 10, [:@int, "2", [1, 13]]],
[:@int, "3", [1, 16]]]]]]

And here is it after the patch I am including:

require 'ripper'
require 'pp'

pp Ripper.sexp('*, b = 1, 2, 3')
[:program,
[[:massign,
[:mlhs_add_star, [], nil, :@ident, "b", [1, 3]],
[:mrhs_new_from_args,
:@int, "1", [1, 7, [:@int, "2", [1, 10]]],
[:@int, "3", [1, 13]]]]]]

pp Ripper.sexp('*b, c = 1, 2, 3, 4')
[:program,
[[:massign,
[:mlhs_add_star, [], [:@ident, "b", [1, 1]], :@ident, "c", [1, 4]],
[:mrhs_new_from_args,
:@int, "1", [1, 8, [:@int, "2", [1, 11]], [:@int, "3", [1, 14]]],
[:@int, "4", [1, 17]]]]]]

pp Ripper.sexp('a, *, b, c = 1, 2, 3, 4')
[:program,
[[:massign,
[:mlhs_add_star,
:@ident, "a", [1, 0],
nil,
:@ident, "b", [1, 6, [:@ident, "c", [1, 9]]]],
[:mrhs_new_from_args,
:@int, "1", [1, 13, [:@int, "2", [1, 16]], [:@int, "3", [1, 19]]],
[:@int, "4", [1, 22]]]]]]

I based the new output on the results of the one case that does parse successfully (this is for both versions):

pp Ripper.sexp('a, b, *c, d, e = 1, 2, 3, 4, 5, 6')
[:program,
[[:massign,
[:mlhs_add_star,
:@ident, "a", [1, 0, [:@ident, "b", [1, 3]]],
[:@ident, "c", [1, 7]],
:@ident, "d", [1, 10, [:@ident, "e", [1, 13]]]],
[:mrhs_new_from_args,
:@int, "1", [1, 17,
[:@int, "2", [1, 20]],
[:@int, "3", [1, 23]],
[:@int, "4", [1, 26]],
[:@int, "5", [1, 29]]],
[:@int, "6", [1, 32]]]]]]
=end


Files

ripper.splat.diff (768 Bytes) ripper.splat.diff adgar (Michael Edgar), 02/04/2011 06:55 AM
ripper.splat.test.diff (1.51 KB) ripper.splat.test.diff adgar (Michael Edgar), 02/05/2011 12:53 PM
#1

Updated by nobu (Nobuyoshi Nakada) about 9 years ago

  • Category set to core
  • Status changed from Open to Feedback

=begin
Thank you, it seems fine.
Couldn't you make test case for it too?
=end

#2

Updated by adgar (Michael Edgar) about 9 years ago

=begin
Test patch attached. Thanks!
=end

#3

Updated by nobu (Nobuyoshi Nakada) about 9 years ago

  • Status changed from Feedback to Closed
  • % Done changed from 0 to 100

=begin
This issue was solved with changeset r30799.
Michael, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • parse.y (mlhs_basic): include mlhs_post for ripper. a patch from Michael Edgar at [ruby-core:35078]. =end

Also available in: Atom PDF