constructor(str, options) {
    options = options || {};
    this.stash = [];
    this.indentStack = [];
    this.indentRe = null;
    this.lineno = 1;
    this.column = 1;

    // HACK!
    function comment(str, val, offset, s) {
      var inComment = s.lastIndexOf('/*', offset) > s.lastIndexOf('*/', offset)
        , commentIdx = s.lastIndexOf('//', offset)
        , i = s.lastIndexOf('\n', offset)
        , double = 0
        , single = 0;

      if (~commentIdx && commentIdx > i) {
        while (i != offset) {
          if ("'" == s[i]) single ? single-- : single++;
          if ('"' == s[i]) double ? double-- : double++;

          if ('/' == s[i] && '/' == s[i + 1]) {
            inComment = !single && !double;
            break;
          }
          ++i;
        }
      }

      return inComment
        ? str
        : ((val === ',' && /^[,\t\n]+$/.test(str)) ? str.replace(/\n/, '\r') : val + '\r');
    };

    // Remove UTF-8 BOM.
    if ('\uFEFF' == str.charAt(0)) str = str.slice(1);

    this.str = str
      .replace(/\s+$/, '\n')
      .replace(/\r\n?/g, '\n')
      .replace(/\\ *\n/g, '\r')
      .replace(/([,(:](?!\/\/[^ ])) *(?:\/\/[^\n]*|\/\*.*?\*\/)?\n\s*/g, comment)
      .replace(/\s*\n[ \t]*([,)])/g, comment);
  }
Initialize a new `Lexer` with the given `str` and `options`.

@param {String} str
@param {Object} options
@api private