private function build_first_sets(){
		$firsts = array();
		do {
			$changes = 0;
			foreach( $this->rules as $rule ){
				list( $nt, $rhs ) = $rule;
				$s = reset( $rhs );
				// get any special rule processing for this non-terminal
				//$excludela = isset($this->excludela[$nt]) ? $this->excludela[$nt] : null;
				do {
					// add terminal to first set of $nt
					if( $this->is_terminal( $s ) ){
						if( ! isset($firsts[$nt][$s]) ){
							$firsts[$nt][$s] = $s;
							$changes++;
						}
						continue 2;
					}
					// else inherit from first set of this non-terminal
					if( ! isset($firsts[$s]) ){
						// throw new Exception( sprintf("FIRST(%s) not defined", $s) );
						$changes++;
						continue 2;
					}
					// collect all terminal symbols in this non-terminal's set
					// except the empty string which we do not inherit.
					$derives_e = isset( $firsts[$s][P_EPSILON] );
					foreach( $firsts[$s] as $t ){
						// Omit any lookahead symbols denied by special rule
						//if( $excludela && in_array( $t, $excludela,true ) ){
						//	// ignored
						//}
						//else 
						if( $t !== P_EPSILON && ! isset( $firsts[$nt][$t] ) ){
							$firsts[$nt][$t] = $t;
							$changes++;
						}
					}
					// we move to next in sequence if non-terminal can derive empty 
				}
				while( $derives_e && $s = next($rhs) );
			}
		}
		while( $changes > 0 );
		return $firsts;
	}
private function build_first_sets(){
		$firsts = array();
		do {
			$changes = 0;
			foreach( $this->rules as $rule ){
				list( $nt, $rhs ) = $rule;
				$s = reset( $rhs );
				// get any special rule processing for this non-terminal
				//$excludela = isset($this->excludela[$nt]) ? $this->excludela[$nt] : null;
				do {
					// add terminal to first set of $nt
					if( $this->is_terminal( $s ) ){
						if( ! isset($firsts[$nt][$s]) ){
							$firsts[$nt][$s] = $s;
							$changes++;
						}
						continue 2;
					}
					// else inherit from first set of this non-terminal
					if( ! isset($firsts[$s]) ){
						// throw new Exception( sprintf("FIRST(%s) not defined", $s) );
						$changes++;
						continue 2;
					}
					// collect all terminal symbols in this non-terminal's set
					// except the empty string which we do not inherit.
					$derives_e = isset( $firsts[$s][P_EPSILON] );
					foreach( $firsts[$s] as $t ){
						// Omit any lookahead symbols denied by special rule
						//if( $excludela && in_array( $t, $excludela,true ) ){
						//	// ignored
						//}
						//else 
						if( $t !== P_EPSILON && ! isset( $firsts[$nt][$t] ) ){
							$firsts[$nt][$t] = $t;
							$changes++;
						}
					}
					// we move to next in sequence if non-terminal can derive empty 
				}
				while( $derives_e && $s = next($rhs) );
			}
		}
		while( $changes > 0 );
		return $firsts;
	}
private function build_first_sets ( ) { $ firsts = array ( ) ; do { $ changes = 0 ; foreach ( $ this -> rules as $ rule ) { list ( $ nt , $ rhs ) = $ rule ; $ s = reset ( $ rhs ) ; // get any special rule processing for this non-terminal //$excludela = isset($this->excludela[$nt]) ? $this->excludela[$nt] : null; do { // add terminal to first set of $nt if ( $ this -> is_terminal ( $ s ) ) { if ( ! isset ( $ firsts [ $ nt ] [ $ s ] ) ) { $ firsts [ $ nt ] [ $ s ] = $ s ; $ changes ++ ; } continue 2 ; } // else inherit from first set of this non-terminal if ( ! isset ( $ firsts [ $ s ] ) ) { // throw new Exception( sprintf("FIRST(%s) not defined", $s) ); $ changes ++ ; continue 2 ; } // collect all terminal symbols in this non-terminal's set // except the empty string which we do not inherit. $ derives_e = isset ( $ firsts [ $ s ] [ P_EPSILON ] ) ; foreach ( $ firsts [ $ s ] as $ t ) { // Omit any lookahead symbols denied by special rule //if( $excludela && in_array( $t, $excludela,true ) ){ //	// ignored //} //else  if ( $ t !== P_EPSILON && ! isset ( $ firsts [ $ nt ] [ $ t ] ) ) { $ firsts [ $ nt ] [ $ t ] = $ t ; $ changes ++ ; } } // we move to next in sequence if non-terminal can derive empty  } while ( $ derives_e && $ s = next ( $ rhs ) ) ; } } while ( $ changes > 0 ) ; return $ firsts ; }
Generate FIRST sets for each non-terminal.
@return array
Generate FIRST sets for each non - terminal .