src/lexer/strings.js
function() {
    let ch = this.input();
    if (ch === "$") {
      ch = this.input();
      if (ch === "{") {
        this.begin("ST_LOOKING_FOR_VARNAME");
        return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
      } else if (this.is_LABEL_START()) {
        const tok = this.consume_VARIABLE();
        return tok;
      }
    } else if (ch === "{") {
      if (this._input[this.offset] === "$") {
        this.begin("ST_IN_SCRIPTING");
        return this.tok.T_CURLY_OPEN;
      }
    } else if (ch === "`") {
      this.popState();
      return "`";
    }

    // any char
    while (this.offset < this.size) {
      if (ch === "\\") {
        this.input();
      } else if (ch === "`") {
        this.unput(1);
        this.popState();
        this.appendToken("`", 1);
        break;
      } else if (ch === "$") {
        ch = this.input();
        if (ch === "{") {
          this.begin("ST_LOOKING_FOR_VARNAME");
          if (this.yytext.length > 2) {
            this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES, 2);
            this.unput(2);
            return this.tok.T_ENCAPSED_AND_WHITESPACE;
          } else {
            return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
          }
        } else if (this.is_LABEL_START()) {
          // start of $var...
          const yyoffset = this.offset;
          const next = this.consume_VARIABLE();
          if (this.yytext.length > this.offset - yyoffset + 2) {
            this.appendToken(next, this.offset - yyoffset + 2);
            this.unput(this.offset - yyoffset + 2);
            return this.tok.T_ENCAPSED_AND_WHITESPACE;
          } else {
            return next;
          }
        }
        continue;
      } else if (ch === "{") {
        ch = this.input();
        if (ch === "$") {
          // start of {$...
          this.begin("ST_IN_SCRIPTING");
          if (this.yytext.length > 2) {
            this.appendToken(this.tok.T_CURLY_OPEN, 1);
            this.unput(2);
            return this.tok.T_ENCAPSED_AND_WHITESPACE;
          } else {
            this.unput(1);
            return this.tok.T_CURLY_OPEN;
          }
        }
        continue;
      }
      ch = this.input();
    }
    return this.tok.T_ENCAPSED_AND_WHITESPACE;
  }
function() {
    let ch = this.input();
    if (ch === "$") {
      ch = this.input();
      if (ch === "{") {
        this.begin("ST_LOOKING_FOR_VARNAME");
        return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
      } else if (this.is_LABEL_START()) {
        const tok = this.consume_VARIABLE();
        return tok;
      }
    } else if (ch === "{") {
      if (this._input[this.offset] === "$") {
        this.begin("ST_IN_SCRIPTING");
        return this.tok.T_CURLY_OPEN;
      }
    } else if (ch === "`") {
      this.popState();
      return "`";
    }

    // any char
    while (this.offset < this.size) {
      if (ch === "\\") {
        this.input();
      } else if (ch === "`") {
        this.unput(1);
        this.popState();
        this.appendToken("`", 1);
        break;
      } else if (ch === "$") {
        ch = this.input();
        if (ch === "{") {
          this.begin("ST_LOOKING_FOR_VARNAME");
          if (this.yytext.length > 2) {
            this.appendToken(this.tok.T_DOLLAR_OPEN_CURLY_BRACES, 2);
            this.unput(2);
            return this.tok.T_ENCAPSED_AND_WHITESPACE;
          } else {
            return this.tok.T_DOLLAR_OPEN_CURLY_BRACES;
          }
        } else if (this.is_LABEL_START()) {
          // start of $var...
          const yyoffset = this.offset;
          const next = this.consume_VARIABLE();
          if (this.yytext.length > this.offset - yyoffset + 2) {
            this.appendToken(next, this.offset - yyoffset + 2);
            this.unput(this.offset - yyoffset + 2);
            return this.tok.T_ENCAPSED_AND_WHITESPACE;
          } else {
            return next;
          }
        }
        continue;
      } else if (ch === "{") {
        ch = this.input();
        if (ch === "$") {
          // start of {$...
          this.begin("ST_IN_SCRIPTING");
          if (this.yytext.length > 2) {
            this.appendToken(this.tok.T_CURLY_OPEN, 1);
            this.unput(2);
            return this.tok.T_ENCAPSED_AND_WHITESPACE;
          } else {
            this.unput(1);
            return this.tok.T_CURLY_OPEN;
          }
        }
        continue;
      }
      ch = this.input();
    }
    return this.tok.T_ENCAPSED_AND_WHITESPACE;
  }
function ( ) { let ch = this . input ( ) ; if ( ch === "$" ) { ch = this . input ( ) ; if ( ch === "{" ) { this . begin ( "ST_LOOKING_FOR_VARNAME" ) ; return this . tok . T_DOLLAR_OPEN_CURLY_BRACES ; } else if ( this . is_LABEL_START ( ) ) { const tok = this . consume_VARIABLE ( ) ; return tok ; } } else if ( ch === "{" ) { if ( this . _input [ this . offset ] === "$" ) { this . begin ( "ST_IN_SCRIPTING" ) ; return this . tok . T_CURLY_OPEN ; } } else if ( ch === "`" ) { this . popState ( ) ; return "`" ; } // any char while ( this . offset < this . size ) { if ( ch === "\\" ) { this . input ( ) ; } else if ( ch === "`" ) { this . unput ( 1 ) ; this . popState ( ) ; this . appendToken ( "`" , 1 ) ; break ; } else if ( ch === "$" ) { ch = this . input ( ) ; if ( ch === "{" ) { this . begin ( "ST_LOOKING_FOR_VARNAME" ) ; if ( this . yytext . length > 2 ) { this . appendToken ( this . tok . T_DOLLAR_OPEN_CURLY_BRACES , 2 ) ; this . unput ( 2 ) ; return this . tok . T_ENCAPSED_AND_WHITESPACE ; } else { return this . tok . T_DOLLAR_OPEN_CURLY_BRACES ; } } else if ( this . is_LABEL_START ( ) ) { // start of $var... const yyoffset = this . offset ; const next = this . consume_VARIABLE ( ) ; if ( this . yytext . length > this . offset - yyoffset + 2 ) { this . appendToken ( next , this . offset - yyoffset + 2 ) ; this . unput ( this . offset - yyoffset + 2 ) ; return this . tok . T_ENCAPSED_AND_WHITESPACE ; } else { return next ; } } continue ; } else if ( ch === "{" ) { ch = this . input ( ) ; if ( ch === "$" ) { // start of {$... this . begin ( "ST_IN_SCRIPTING" ) ; if ( this . yytext . length > 2 ) { this . appendToken ( this . tok . T_CURLY_OPEN , 1 ) ; this . unput ( 2 ) ; return this . tok . T_ENCAPSED_AND_WHITESPACE ; } else { this . unput ( 1 ) ; return this . tok . T_CURLY_OPEN ; } } continue ; } ch = this . input ( ) ; } return this . tok . T_ENCAPSED_AND_WHITESPACE ; }
HANDLES BACKQUOTES
HANDLES BACKQUOTES