src/lexer/strings.js
function() {
    const revert = this.offset;
    if (
      this._input[this.offset - 1] === "<" &&
      this._input[this.offset] === "<" &&
      this._input[this.offset + 1] === "<"
    ) {
      this.offset += 3;

      // optional tabs / spaces
      if (this.is_TABSPACE()) {
        while (this.offset < this.size) {
          this.offset++;
          if (!this.is_TABSPACE()) {
            break;
          }
        }
      }

      // optional quotes
      let tChar = this._input[this.offset - 1];
      if (tChar === "'" || tChar === '"') {
        this.offset++;
      } else {
        tChar = null;
      }

      // required label
      if (this.is_LABEL_START()) {
        let yyoffset = this.offset - 1;
        while (this.offset < this.size) {
          this.offset++;
          if (!this.is_LABEL()) {
            break;
          }
        }
        const yylabel = this._input.substring(yyoffset, this.offset - 1);
        if (!tChar || tChar === this._input[this.offset - 1]) {
          // required ending quote
          if (tChar) this.offset++;
          // require newline
          if (
            this._input[this.offset - 1] === "\r" ||
            this._input[this.offset - 1] === "\n"
          ) {
            // go go go
            this.heredoc_label = yylabel;
            yyoffset = this.offset - revert;
            this.offset = revert;
            this.consume(yyoffset);
            if (tChar === "'") {
              this.begin("ST_NOWDOC");
            } else {
              this.begin("ST_HEREDOC");
            }
            return this.tok.T_START_HEREDOC;
          }
        }
      }
    }
    this.offset = revert;
    return false;
  }
function() {
    const revert = this.offset;
    if (
      this._input[this.offset - 1] === "<" &&
      this._input[this.offset] === "<" &&
      this._input[this.offset + 1] === "<"
    ) {
      this.offset += 3;

      // optional tabs / spaces
      if (this.is_TABSPACE()) {
        while (this.offset < this.size) {
          this.offset++;
          if (!this.is_TABSPACE()) {
            break;
          }
        }
      }

      // optional quotes
      let tChar = this._input[this.offset - 1];
      if (tChar === "'" || tChar === '"') {
        this.offset++;
      } else {
        tChar = null;
      }

      // required label
      if (this.is_LABEL_START()) {
        let yyoffset = this.offset - 1;
        while (this.offset < this.size) {
          this.offset++;
          if (!this.is_LABEL()) {
            break;
          }
        }
        const yylabel = this._input.substring(yyoffset, this.offset - 1);
        if (!tChar || tChar === this._input[this.offset - 1]) {
          // required ending quote
          if (tChar) this.offset++;
          // require newline
          if (
            this._input[this.offset - 1] === "\r" ||
            this._input[this.offset - 1] === "\n"
          ) {
            // go go go
            this.heredoc_label = yylabel;
            yyoffset = this.offset - revert;
            this.offset = revert;
            this.consume(yyoffset);
            if (tChar === "'") {
              this.begin("ST_NOWDOC");
            } else {
              this.begin("ST_HEREDOC");
            }
            return this.tok.T_START_HEREDOC;
          }
        }
      }
    }
    this.offset = revert;
    return false;
  }
function ( ) { const revert = this . offset ; if ( this . _input [ this . offset - 1 ] === "<" && this . _input [ this . offset ] === "<" && this . _input [ this . offset + 1 ] === "<" ) { this . offset += 3 ; // optional tabs / spaces if ( this . is_TABSPACE ( ) ) { while ( this . offset < this . size ) { this . offset ++ ; if ( ! this . is_TABSPACE ( ) ) { break ; } } } // optional quotes let tChar = this . _input [ this . offset - 1 ] ; if ( tChar === "'" || tChar === '"' ) { this . offset ++ ; } else { tChar = null ; } // required label if ( this . is_LABEL_START ( ) ) { let yyoffset = this . offset - 1 ; while ( this . offset < this . size ) { this . offset ++ ; if ( ! this . is_LABEL ( ) ) { break ; } } const yylabel = this . _input . substring ( yyoffset , this . offset - 1 ) ; if ( ! tChar || tChar === this . _input [ this . offset - 1 ] ) { // required ending quote if ( tChar ) this . offset ++ ; // require newline if ( this . _input [ this . offset - 1 ] === "\r" || this . _input [ this . offset - 1 ] === "\n" ) { // go go go this . heredoc_label = yylabel ; yyoffset = this . offset - revert ; this . offset = revert ; this . consume ( yyoffset ) ; if ( tChar === "'" ) { this . begin ( "ST_NOWDOC" ) ; } else { this . begin ( "ST_HEREDOC" ) ; } return this . tok . T_START_HEREDOC ; } } } } this . offset = revert ; return false ; }
check if matching a HEREDOC state
check if matching a HEREDOC state