Backport #1921 [ruby-core:24855]

Ripper Heredoc Parsing

Added by Andy Keep 220 days ago. Updated 103 days ago.

Status :Closed Start :08/11/2009
Priority :Normal Due date :
Assigned to :Yuki Sonoda % Done :

100%

Category :-
Target version :-

Description

I'm using the Ripper parser extension in a project I'm working on for school, and I noticed that heredocs do not seem to process correctly.  What seems to be happening is that the scanner events are dispatched: heredoc_beg, then tstring_content, then heredoc_end, but at the parser level only the heredoc_end is coming back in the results.

To quickly demonstrate using Ripper's sexp generator:

$ irb -rripper
>> Ripper.sexp("<<-EOF\nThis is a\ntest of heredocs\nEOF")
=> [:program, [[:string_literal, [:string_content, [:heredoc_end, "EOF", [4, 0]]]]]]
>> Ripper.sexp_raw("<<-EOF\nThis is a\ntest of heredocs\nEOF")
=> [:program, [:stmts_add, [:stmts_new], [:string_literal, [:string_add, [:string_content], [:heredoc_end, "EOF", [4, 0]]]]]]

Here instead of the expected string content, "This is a\ntest of heredocs\n", we get [:heredoc_end, "EOF", [4, 0]] from the scanner.

While Ripper's sexp and sexp_raw do not seem to deliver the correct stuff, the correct scanner events are being fired off, so it is not just an issue of the scanner events begin incorrect or the content string being lost. I think the problem stems from the fact that the heredocs are handled within the lexer, and at the parser level only one value representing the string (or at least the final string) is expected, but the scanner is sending two final events.  First the tstring_content then the heredoc_end, both of which overwrite the yyval.  The right way to tackle this may be fundamentally change how heredocs are handled, but the simpler approach is to allow the heredoc_end to fire without it accidentally overwriting the yyval, since the parser is not expecting a heredoc value anyway.

I've included a patch to parse.y that basically adds a function called ripper_dispatch_ignored_scan_event, which mimics ripper_dispatch_scan_event, but does not update the yyval.  It then uses this to dispatch the heredoc_end event to avoid overwriting the tstring_content token.

With my patch:

$ irb -rripper
>> Ripper.sexp("t = <<-EOF\nThis is a\ntest of heredocs\nEOF")
=> [:program, [[:assign, [:var_field, [:ident, "t", [1, 0]]], [:string_literal, [:string_content, [:tstring_content, "This is a\ntest of heredocs\n", [2, 0]]]]]]]
>> Ripper.sexp_raw("t = <<-EOF\nThis is a\ntest of heredocs\nEOF")
=> [:program, [:stmts_add, [:stmts_new], [:assign, [:var_field, [:ident, "t", [1, 0]]], [:string_literal, [:string_add, [:string_content], [:tstring_content, "This is a\ntest of heredocs\n", [2, 0]]]]]]]

parse.y.heredoc_patch - Patch to fix Ripper handling of HEREDOC (generated with svn diff off rev 25401) (981 Bytes) Andy Keep, 10/20/2009 12:02 AM

Associated revisions

Revision 25402
Added by nobu 149 days ago

  • parse.y (parser_here_document): dispatch delayed heredoc contents. based on a patch from Andy Keep in [ruby-core:24855].

Revision 26008
Added by yugui 103 days ago

merges r25402 from trunk into ruby_1_9_1. fixes the backport task #1921. --

  • parse.y (parser_here_document): dispatch delayed heredoc contents. based on a patch from Andy Keep in [ruby-core:24855].

Revision 26496
Added by yugui 47 days ago

merges r25402,r25404,r25405,r25406 and r25407 from trunk into ruby_1_9_1. --

  • parse.y (parser_here_document): dispatch delayed heredoc contents. based on a patch from Andy Keep in [ruby-core:24855].

--

  • parse.y (mlhs_basic): fixed handling splat in middle of mlhs. a patch from Andy Keep in [ruby-core:26163]

--

  • parse.y (method_call): dispatch symbols. a patch from Andy Keep in [ruby-core:26169]. [ruby-core:26165]

--

  • test/ripper/test_*.rb: fixed indent.

--

  • parse.y (ripper_intern): enable literal optimization.

History

10/17/2009 09:21 AM - Nobuyoshi Nakada

  • Status changed from Open to Feedback
Where's your patch?

10/20/2009 12:02 AM - Andy Keep

Hmmm... That is odd, I had attached the patch when I initially created this ticket.  (Or at least I thought I had.)  Here is a patch (updated for SVN revision 25401)

10/20/2009 02:57 PM - Nobuyoshi Nakada

  • Status changed from Feedback to Closed
  • % Done changed from 0 to 100
This issue was solved with changeset r25402.
Andy, thank you for your reporting of the issue.
You have greatfully contributed toward Ruby.
May Ruby be with you.

12/01/2009 07:20 AM - Nobuyoshi Nakada

  • Status changed from Closed to Assigned
  • Assigned to set to Yuki Sonoda

12/05/2009 06:47 PM - Yuki Sonoda

  • Status changed from Assigned to Closed
This issue was solved with changeset r26008.
Andy, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.

Also available in: Atom PDF