src/parser/class.js
function() {
    const result = this.node("class");
    const flag = this.read_class_scope();
    // graceful mode : ignore token & go next
    if (this.token !== this.tok.T_CLASS) {
      this.error(this.tok.T_CLASS);
      this.next();
      return null;
    }
    this.next().expect(this.tok.T_STRING);
    let propName = this.node("identifier");
    const name = this.text();
    this.next();
    propName = propName(name);
    let propExtends = null;
    if (this.token == this.tok.T_EXTENDS) {
      propExtends = this.next().read_namespace_name();
    }
    let propImplements = null;
    if (this.token == this.tok.T_IMPLEMENTS) {
      propImplements = this.next().read_name_list();
    }
    this.expect("{");
    const body = this.next().read_class_body();
    return result(propName, propExtends, propImplements, body, flag);
  }
function() {
    const result = this.node("class");
    const flag = this.read_class_scope();
    // graceful mode : ignore token & go next
    if (this.token !== this.tok.T_CLASS) {
      this.error(this.tok.T_CLASS);
      this.next();
      return null;
    }
    this.next().expect(this.tok.T_STRING);
    let propName = this.node("identifier");
    const name = this.text();
    this.next();
    propName = propName(name);
    let propExtends = null;
    if (this.token == this.tok.T_EXTENDS) {
      propExtends = this.next().read_namespace_name();
    }
    let propImplements = null;
    if (this.token == this.tok.T_IMPLEMENTS) {
      propImplements = this.next().read_name_list();
    }
    this.expect("{");
    const body = this.next().read_class_body();
    return result(propName, propExtends, propImplements, body, flag);
  }
function ( ) { const result = this . node ( "class" ) ; const flag = this . read_class_scope ( ) ; // graceful mode : ignore token & go next if ( this . token !== this . tok . T_CLASS ) { this . error ( this . tok . T_CLASS ) ; this . next ( ) ; return null ; } this . next ( ) . expect ( this . tok . T_STRING ) ; let propName = this . node ( "identifier" ) ; const name = this . text ( ) ; this . next ( ) ; propName = propName ( name ) ; let propExtends = null ; if ( this . token == this . tok . T_EXTENDS ) { propExtends = this . next ( ) . read_namespace_name ( ) ; } let propImplements = null ; if ( this . token == this . tok . T_IMPLEMENTS ) { propImplements = this . next ( ) . read_name_list ( ) ; } this . expect ( "{" ) ; const body = this . next ( ) . read_class_body ( ) ; return result ( propName , propExtends , propImplements , body , flag ) ; }
reading a class
```ebnf
class ::= class_scope? T_CLASS T_STRING (T_EXTENDS NAMESPACE_NAME)? (T_IMPLEMENTS (NAMESPACE_NAME ',')* NAMESPACE_NAME)? '{' CLASS_BODY '}'
```
reading a class ebnf class :: = class_scope? T_CLASS T_STRING ( T_EXTENDS NAMESPACE_NAME ) ? ( T_IMPLEMENTS ( NAMESPACE_NAME ) * NAMESPACE_NAME ) ? { CLASS_BODY }