function() {
    const result = this.node("foreach");
    this.expect(this.tok.T_FOREACH) && this.next();
    let source = null;
    let key = null;
    let value = null;
    let body = null;
    let shortForm = false;
    if (this.expect("(")) this.next();
    source = this.read_expr();
    if (this.expect(this.tok.T_AS)) {
      this.next();
      value = this.read_foreach_variable();
      if (this.token === this.tok.T_DOUBLE_ARROW) {
        key = value;
        value = this.next().read_foreach_variable();
      }
    }

    // grammatically correct but not supported by PHP
    if (key && key.kind === "list") {
      this.raiseError("Fatal Error : Cannot use list as key element");
    }

    if (this.expect(")")) this.next();

    if (this.token === ":") {
      shortForm = true;
      body = this.read_short_form(this.tok.T_ENDFOREACH);
    } else {
      body = this.read_statement();
    }
    return result(source, key, value, body, shortForm);
  }
function() {
    const result = this.node("foreach");
    this.expect(this.tok.T_FOREACH) && this.next();
    let source = null;
    let key = null;
    let value = null;
    let body = null;
    let shortForm = false;
    if (this.expect("(")) this.next();
    source = this.read_expr();
    if (this.expect(this.tok.T_AS)) {
      this.next();
      value = this.read_foreach_variable();
      if (this.token === this.tok.T_DOUBLE_ARROW) {
        key = value;
        value = this.next().read_foreach_variable();
      }
    }

    
    if (key && key.kind === "list") {
      this.raiseError("Fatal Error : Cannot use list as key element");
    }

    if (this.expect(")")) this.next();

    if (this.token === ":") {
      shortForm = true;
      body = this.read_short_form(this.tok.T_ENDFOREACH);
    } else {
      body = this.read_statement();
    }
    return result(source, key, value, body, shortForm);
  }
function ( ) { const result = this . node ( "foreach" ) ; this . expect ( this . tok . T_FOREACH ) && this . next ( ) ; let source = null ; let key = null ; let value = null ; let body = null ; let shortForm = false ; if ( this . expect ( "(" ) ) this . next ( ) ; source = this . read_expr ( ) ; if ( this . expect ( this . tok . T_AS ) ) { this . next ( ) ; value = this . read_foreach_variable ( ) ; if ( this . token === this . tok . T_DOUBLE_ARROW ) { key = value ; value = this . next ( ) . read_foreach_variable ( ) ; } } // grammatically correct but not supported by PHP if ( key && key . kind === "list" ) { this . raiseError ( "Fatal Error : Cannot use list as key element" ) ; } if ( this . expect ( ")" ) ) this . next ( ) ; if ( this . token === ":" ) { shortForm = true ; body = this . read_short_form ( this . tok . T_ENDFOREACH ) ; } else { body = this . read_statement ( ) ; } return result ( source , key , value , body , shortForm ) ; }
Reads a foreach loop
```ebnf
foreach ::= '(' expr T_AS foreach_variable (T_DOUBLE_ARROW foreach_variable)? ')' statement
```
@see https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L438
@return {Foreach}
Reads a foreach loop ebnf foreach :: = ( expr T_AS foreach_variable ( T_DOUBLE_ARROW foreach_variable ) ? ) statement