src/parser/scalar.js
function(isDoubleQuote) {
    const encapsedPart = this.node("encapsedpart");
    let curly = false;
    let result = this.node(),
      offset,
      node,
      name;

    // plain text
    // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1222
    if (this.token === this.tok.T_ENCAPSED_AND_WHITESPACE) {
      const text = this.text();
      this.next();
      result = result(
        "string",
        false,
        this.resolve_special_chars(text, isDoubleQuote),
        false,
        text
      );
    } else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) {
      // dynamic variable name
      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1239
      name = null;
      if (this.next().token === this.tok.T_STRING_VARNAME) {
        name = this.node("variable");
        const varName = this.text();
        this.next();
        // check if lookup an offset
        // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243
        if (this.token === "[") {
          name = name(varName, false, false);
          node = this.node("offsetlookup");
          offset = this.next().read_expr();
          this.expect("]") && this.next();
          name = node(name, offset);
        } else {
          name = varName;
        }
      } else {
        name = this.read_expr();
      }
      this.expect("}") && this.next();
      result = result("variable", name, false, true);
    } else if (this.token === this.tok.T_CURLY_OPEN) {
      // expression
      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1246
      curly = true;
      result.destroy();
      result = this.next().read_variable(false, false, false);
      this.expect("}") && this.next();
    } else if (this.token === this.tok.T_VARIABLE) {
      // plain variable
      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1231
      result.destroy();
      result = this.read_simple_variable(false);

      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1233
      if (this.token === "[") {
        node = this.node("offsetlookup");
        offset = this.next().read_encaps_var_offset();
        this.expect("]") && this.next();
        result = node(result, offset);
      }

      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1236
      if (this.token === this.tok.T_OBJECT_OPERATOR) {
        node = this.node("propertylookup");
        this.next().expect(this.tok.T_STRING);
        const what = this.node("identifier");
        name = this.text();
        this.next();
        result = node(result, what(name));
      }

      // error / fallback
    } else {
      this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE);
      const value = this.text();
      this.next();
      // consider it as string
      result.destroy();
      result = result("string", false, value, false, value);
    }

    return encapsedPart(result, curly);
  }
function(isDoubleQuote) {
    const encapsedPart = this.node("encapsedpart");
    let curly = false;
    let result = this.node(),
      offset,
      node,
      name;

    // plain text
    // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1222
    if (this.token === this.tok.T_ENCAPSED_AND_WHITESPACE) {
      const text = this.text();
      this.next();
      result = result(
        "string",
        false,
        this.resolve_special_chars(text, isDoubleQuote),
        false,
        text
      );
    } else if (this.token === this.tok.T_DOLLAR_OPEN_CURLY_BRACES) {
      // dynamic variable name
      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1239
      name = null;
      if (this.next().token === this.tok.T_STRING_VARNAME) {
        name = this.node("variable");
        const varName = this.text();
        this.next();
        // check if lookup an offset
        // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243
        if (this.token === "[") {
          name = name(varName, false, false);
          node = this.node("offsetlookup");
          offset = this.next().read_expr();
          this.expect("]") && this.next();
          name = node(name, offset);
        } else {
          name = varName;
        }
      } else {
        name = this.read_expr();
      }
      this.expect("}") && this.next();
      result = result("variable", name, false, true);
    } else if (this.token === this.tok.T_CURLY_OPEN) {
      // expression
      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1246
      curly = true;
      result.destroy();
      result = this.next().read_variable(false, false, false);
      this.expect("}") && this.next();
    } else if (this.token === this.tok.T_VARIABLE) {
      // plain variable
      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1231
      result.destroy();
      result = this.read_simple_variable(false);

      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1233
      if (this.token === "[") {
        node = this.node("offsetlookup");
        offset = this.next().read_encaps_var_offset();
        this.expect("]") && this.next();
        result = node(result, offset);
      }

      // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1236
      if (this.token === this.tok.T_OBJECT_OPERATOR) {
        node = this.node("propertylookup");
        this.next().expect(this.tok.T_STRING);
        const what = this.node("identifier");
        name = this.text();
        this.next();
        result = node(result, what(name));
      }

      // error / fallback
    } else {
      this.expect(this.tok.T_ENCAPSED_AND_WHITESPACE);
      const value = this.text();
      this.next();
      // consider it as string
      result.destroy();
      result = result("string", false, value, false, value);
    }

    return encapsedPart(result, curly);
  }
function ( isDoubleQuote ) { const encapsedPart = this . node ( "encapsedpart" ) ; let curly = false ; let result = this . node ( ) , offset , node , name ; // plain text // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1222 if ( this . token === this . tok . T_ENCAPSED_AND_WHITESPACE ) { const text = this . text ( ) ; this . next ( ) ; result = result ( "string" , false , this . resolve_special_chars ( text , isDoubleQuote ) , false , text ) ; } else if ( this . token === this . tok . T_DOLLAR_OPEN_CURLY_BRACES ) { // dynamic variable name // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1239 name = null ; if ( this . next ( ) . token === this . tok . T_STRING_VARNAME ) { name = this . node ( "variable" ) ; const varName = this . text ( ) ; this . next ( ) ; // check if lookup an offset // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1243 if ( this . token === "[" ) { name = name ( varName , false , false ) ; node = this . node ( "offsetlookup" ) ; offset = this . next ( ) . read_expr ( ) ; this . expect ( "]" ) && this . next ( ) ; name = node ( name , offset ) ; } else { name = varName ; } } else { name = this . read_expr ( ) ; } this . expect ( "}" ) && this . next ( ) ; result = result ( "variable" , name , false , true ) ; } else if ( this . token === this . tok . T_CURLY_OPEN ) { // expression // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1246 curly = true ; result . destroy ( ) ; result = this . next ( ) . read_variable ( false , false , false ) ; this . expect ( "}" ) && this . next ( ) ; } else if ( this . token === this . tok . T_VARIABLE ) { // plain variable // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1231 result . destroy ( ) ; result = this . read_simple_variable ( false ) ; // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1233 if ( this . token === "[" ) { node = this . node ( "offsetlookup" ) ; offset = this . next ( ) . read_encaps_var_offset ( ) ; this . expect ( "]" ) && this . next ( ) ; result = node ( result , offset ) ; } // https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1236 if ( this . token === this . tok . T_OBJECT_OPERATOR ) { node = this . node ( "propertylookup" ) ; this . next ( ) . expect ( this . tok . T_STRING ) ; const what = this . node ( "identifier" ) ; name = this . text ( ) ; this . next ( ) ; result = node ( result , what ( name ) ) ; } // error / fallback } else { this . expect ( this . tok . T_ENCAPSED_AND_WHITESPACE ) ; const value = this . text ( ) ; this . next ( ) ; // consider it as string result . destroy ( ) ; result = result ( "string" , false , value , false , value ) ; } return encapsedPart ( result , curly ) ; }
Reads and extracts an encapsed item
```ebnf
encapsed_string_item ::= T_ENCAPSED_AND_WHITESPACE
| T_DOLLAR_OPEN_CURLY_BRACES expr '}'
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}'
| T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}'
| T_CURLY_OPEN variable '}'
| variable
| variable '[' expr ']'
| variable T_OBJECT_OPERATOR T_STRING
```
@return {String|Variable|Expr|Lookup}
@see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L1219
Reads and extracts an encapsed item ebnf encapsed_string_item :: = T_ENCAPSED_AND_WHITESPACE | T_DOLLAR_OPEN_CURLY_BRACES expr } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME [ expr ] } | T_CURLY_OPEN variable } | variable | variable [ expr ] | variable T_OBJECT_OPERATOR T_STRING