     return 0 unless match = HEREDOC.exec @chunk
     heredoc = match[0]
     quote = heredoc.charAt 0
-    doc = @sanitizeHeredoc match[2], quote: quote, indent: null
+    # Trim last newline if it's not escaped
+    trimmed = match[2].replace /(([^\\]|\\\\)\s*)\n[^\n\S]*$/, '$1'
+    doc = @sanitizeHeredoc trimmed, quote: quote, indent: null
     if quote is '"' and 0 <= doc.indexOf '#{'
       @interpolateString doc, heredoc: yes, strOffset: 3, lexedLength: heredoc.length
     else

    if heredoc
      str.replace MULTILINER, '\\n'
    else
      str.replace /\s*\n\s*/g, ' '

  # Constructs a string token by escaping quotes and newlines.
  makeString: (body, quote, heredoc) ->

  ^ \d*\.?\d+ (?:e[+-]?\d+)?  # decimal
///i

HEREDOC    = /// ^ ("""|''') (( [\s\S]*? ([^\\]|\\\\) )?) \1 ///

OPERATOR   = /// ^ (
  ?: [-=]>             # function
