function(read_only, encapsed, byref) {
    let result;

    // check the byref flag
    if (!byref && this.token === "&") {
      byref = true;
      this.next();
    }

    // reads the entry point
    if (this.is([this.tok.T_VARIABLE, "$"])) {
      result = this.read_reference_variable(encapsed, byref);
    } else if (
      this.is([
        this.tok.T_NS_SEPARATOR,
        this.tok.T_STRING,
        this.tok.T_NAMESPACE
      ])
    ) {
      result = this.node();
      const name = this.read_namespace_name();
      if (
        this.token != this.tok.T_DOUBLE_COLON &&
        this.token != "(" &&
        ["parentreference", "selfreference"].indexOf(name.kind) === -1
      ) {
        // @see parser.js line 130 : resolves a conflict with scalar
        const literal = name.name.toLowerCase();
        if (literal === "true") {
          result = name.destroy(result("boolean", true, name.name));
        } else if (literal === "false") {
          result = name.destroy(result("boolean", false, name.name));
        } else {
          // @todo null keyword ?
          result = result("identifier", name);
        }
      } else {
        // @fixme possible #193 bug
        result.destroy(name);
        result = name;
      }
    } else if (this.token === this.tok.T_STATIC) {
      result = this.node("staticreference");
      const raw = this.text();
      this.next();
      result = result(raw);
    } else {
      this.expect("VARIABLE");
    }

    // static mode
    if (this.token === this.tok.T_DOUBLE_COLON) {
      result = this.read_static_getter(result, encapsed);
    }

    return this.recursive_variable_chain_scan(result, read_only, encapsed);
  }
function(read_only, encapsed, byref) {
    let result;

    
    if (!byref && this.token === "&") {
      byref = true;
      this.next();
    }

    
    if (this.is([this.tok.T_VARIABLE, "$"])) {
      result = this.read_reference_variable(encapsed, byref);
    } else if (
      this.is([
        this.tok.T_NS_SEPARATOR,
        this.tok.T_STRING,
        this.tok.T_NAMESPACE
      ])
    ) {
      result = this.node();
      const name = this.read_namespace_name();
      if (
        this.token != this.tok.T_DOUBLE_COLON &&
        this.token != "(" &&
        ["parentreference", "selfreference"].indexOf(name.kind) === -1
      ) {
        
        const literal = name.name.toLowerCase();
        if (literal === "true") {
          result = name.destroy(result("boolean", true, name.name));
        } else if (literal === "false") {
          result = name.destroy(result("boolean", false, name.name));
        } else {
          
          result = result("identifier", name);
        }
      } else {
        
        result.destroy(name);
        result = name;
      }
    } else if (this.token === this.tok.T_STATIC) {
      result = this.node("staticreference");
      const raw = this.text();
      this.next();
      result = result(raw);
    } else {
      this.expect("VARIABLE");
    }

    
    if (this.token === this.tok.T_DOUBLE_COLON) {
      result = this.read_static_getter(result, encapsed);
    }

    return this.recursive_variable_chain_scan(result, read_only, encapsed);
  }
function ( read_only , encapsed , byref ) { let result ; // check the byref flag if ( ! byref && this . token === "&" ) { byref = true ; this . next ( ) ; } // reads the entry point if ( this . is ( [ this . tok . T_VARIABLE , "$" ] ) ) { result = this . read_reference_variable ( encapsed , byref ) ; } else if ( this . is ( [ this . tok . T_NS_SEPARATOR , this . tok . T_STRING , this . tok . T_NAMESPACE ] ) ) { result = this . node ( ) ; const name = this . read_namespace_name ( ) ; if ( this . token != this . tok . T_DOUBLE_COLON && this . token != "(" && [ "parentreference" , "selfreference" ] . indexOf ( name . kind ) === - 1 ) { // @see parser.js line 130 : resolves a conflict with scalar const literal = name . name . toLowerCase ( ) ; if ( literal === "true" ) { result = name . destroy ( result ( "boolean" , true , name . name ) ) ; } else if ( literal === "false" ) { result = name . destroy ( result ( "boolean" , false , name . name ) ) ; } else { // @todo null keyword ? result = result ( "identifier" , name ) ; } } else { // @fixme possible #193 bug result . destroy ( name ) ; result = name ; } } else if ( this . token === this . tok . T_STATIC ) { result = this . node ( "staticreference" ) ; const raw = this . text ( ) ; this . next ( ) ; result = result ( raw ) ; } else { this . expect ( "VARIABLE" ) ; } // static mode if ( this . token === this . tok . T_DOUBLE_COLON ) { result = this . read_static_getter ( result , encapsed ) ; } return this . recursive_variable_chain_scan ( result , read_only , encapsed ) ; }
Reads a variable

```ebnf
variable ::= &? ...complex @todo
```

Some samples of parsed code :
```php
&$var                      // simple var
$var                      // simple var
classname::CONST_NAME     // dynamic class name with const retrieval
foo()                     // function call
$var->func()->property    // chained calls
```
Reads a variable