whole_func_string: 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);
    }
func_code_string: 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);
    }
func_documentation_string: 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
  ```