private function build_follow_sets(){
		if( ! isset($this->firsts) ){
			$this->firsts = $this->build_first_sets();
		}
		// remember inhritance for error checking
		//$inherits = array();
		// create default/dummy sets with special symbols
		$follows = array(
			P_GOAL => array(),
			P_EOF => array()
		);
		do {
			$changes = 0;
			foreach( $this->rules as $rule ){
				list( $s, $rhs ) = $rule;
				//echo "----\n";
				//echo "$s -> ", implode(',', $rhs), "\n";
				while( $a = current($rhs) ){
					if( $a === P_EPSILON ){
						next($rhs);
						continue;
					}
					//echo "\na = $a\n";
					if( false === next($rhs) ){
						// end of rule, inherit from LHS
						if( !isset($follows[$s]) ){
							//echo "FOLLOW($s) not set, required by $a \n";
							//$inherits[$s] = true;
							continue 2;
						}
						foreach( $follows[$s] as $t ){
							if( !isset($follows[$a][$t]) ){
								//echo "FOLLOW($a) []= $t \n";
								$follows[$a][$t] = $t;
								$changes++;
							}
						}
						// next rule.
						continue 2;
					}

					$r = array_slice( $rhs, key($rhs) );
					while( $b = current($r) ){
						//echo "b = $b\n";
						// merge first(b) into follow(a), 
						// if it derives the empty string, continue to next in rhs
						$fs = $this->is_terminal($b) ? array($b) : $this->firsts[$b];
						//echo "FOLLOW($a) []= FIRST($b) = ",implode(',', $fs),"\n";
						foreach( $fs as $t ){
							if( ! isset($follows[$a][$t]) && $t !== P_EPSILON ){
								$follows[$a][$t] = $t;
								//echo "FOLLOW($a) []= $t \n";
								$changes++;
							}
						}
						// if derives empty, skip to next or inherit lhs
						if( ! isset($fs[P_EPSILON]) ){
							break;
						} 
						if( false === next($r) ){
							//echo "FOLLOW($a) []= FOLLOW($s)\n";
							if( !isset($follows[$s]) ){
								//echo "FOLLOW($s) not set, required by $a \n";
								//$inherits[$s] = true;
								continue 3;
							}
							foreach( $follows[$s] as $t ){
								if( !isset($follows[$a][$t]) ){
									//echo "FOLLOW($a) []= $t \n";
									$follows[$a][$t] = $t;
									$changes++;
								}
							}
						}
					}
				}
			}
		}
		while( $changes );
		// check inheritance problems, uncomment to debug
		/*
		foreach( $inherits as $s => $bool ){
			if( ! isset($follows[$s]) ){
				trigger_error("FOLLOW($s) was never created", E_USER_NOTICE );
			}
		} 
		//*/
		return $follows;
	}
private function build_follow_sets(){
		if( ! isset($this->firsts) ){
			$this->firsts = $this->build_first_sets();
		}
		// remember inhritance for error checking
		//$inherits = array();
		// create default/dummy sets with special symbols
		$follows = array(
			P_GOAL => array(),
			P_EOF => array()
		);
		do {
			$changes = 0;
			foreach( $this->rules as $rule ){
				list( $s, $rhs ) = $rule;
				//echo "----\n";
				//echo "$s -> ", implode(',', $rhs), "\n";
				while( $a = current($rhs) ){
					if( $a === P_EPSILON ){
						next($rhs);
						continue;
					}
					//echo "\na = $a\n";
					if( false === next($rhs) ){
						// end of rule, inherit from LHS
						if( !isset($follows[$s]) ){
							//echo "FOLLOW($s) not set, required by $a \n";
							//$inherits[$s] = true;
							continue 2;
						}
						foreach( $follows[$s] as $t ){
							if( !isset($follows[$a][$t]) ){
								//echo "FOLLOW($a) []= $t \n";
								$follows[$a][$t] = $t;
								$changes++;
							}
						}
						// next rule.
						continue 2;
					}

					$r = array_slice( $rhs, key($rhs) );
					while( $b = current($r) ){
						//echo "b = $b\n";
						// merge first(b) into follow(a), 
						// if it derives the empty string, continue to next in rhs
						$fs = $this->is_terminal($b) ? array($b) : $this->firsts[$b];
						//echo "FOLLOW($a) []= FIRST($b) = ",implode(',', $fs),"\n";
						foreach( $fs as $t ){
							if( ! isset($follows[$a][$t]) && $t !== P_EPSILON ){
								$follows[$a][$t] = $t;
								//echo "FOLLOW($a) []= $t \n";
								$changes++;
							}
						}
						// if derives empty, skip to next or inherit lhs
						if( ! isset($fs[P_EPSILON]) ){
							break;
						} 
						if( false === next($r) ){
							//echo "FOLLOW($a) []= FOLLOW($s)\n";
							if( !isset($follows[$s]) ){
								//echo "FOLLOW($s) not set, required by $a \n";
								//$inherits[$s] = true;
								continue 3;
							}
							foreach( $follows[$s] as $t ){
								if( !isset($follows[$a][$t]) ){
									//echo "FOLLOW($a) []= $t \n";
									$follows[$a][$t] = $t;
									$changes++;
								}
							}
						}
					}
				}
			}
		}
		while( $changes );
		// check inheritance problems, uncomment to debug
		/*
		foreach( $inherits as $s => $bool ){
			if( ! isset($follows[$s]) ){
				trigger_error("FOLLOW($s) was never created", E_USER_NOTICE );
			}
		} 
		//*/
		return $follows;
	}
private function build_follow_sets ( ) { if ( ! isset ( $ this -> firsts ) ) { $ this -> firsts = $ this -> build_first_sets ( ) ; } // remember inhritance for error checking //$inherits = array(); // create default/dummy sets with special symbols $ follows = array ( P_GOAL => array ( ) , P_EOF => array ( ) ) ; do { $ changes = 0 ; foreach ( $ this -> rules as $ rule ) { list ( $ s , $ rhs ) = $ rule ; //echo "----\n"; //echo "$s -> ", implode(',', $rhs), "\n"; while ( $ a = current ( $ rhs ) ) { if ( $ a === P_EPSILON ) { next ( $ rhs ) ; continue ; } //echo "\na = $a\n"; if ( false === next ( $ rhs ) ) { // end of rule, inherit from LHS if ( ! isset ( $ follows [ $ s ] ) ) { //echo "FOLLOW($s) not set, required by $a \n"; //$inherits[$s] = true; continue 2 ; } foreach ( $ follows [ $ s ] as $ t ) { if ( ! isset ( $ follows [ $ a ] [ $ t ] ) ) { //echo "FOLLOW($a) []= $t \n"; $ follows [ $ a ] [ $ t ] = $ t ; $ changes ++ ; } } // next rule. continue 2 ; } $ r = array_slice ( $ rhs , key ( $ rhs ) ) ; while ( $ b = current ( $ r ) ) { //echo "b = $b\n"; // merge first(b) into follow(a),  // if it derives the empty string, continue to next in rhs $ fs = $ this -> is_terminal ( $ b ) ? array ( $ b ) : $ this -> firsts [ $ b ] ; //echo "FOLLOW($a) []= FIRST($b) = ",implode(',', $fs),"\n"; foreach ( $ fs as $ t ) { if ( ! isset ( $ follows [ $ a ] [ $ t ] ) && $ t !== P_EPSILON ) { $ follows [ $ a ] [ $ t ] = $ t ; //echo "FOLLOW($a) []= $t \n"; $ changes ++ ; } } // if derives empty, skip to next or inherit lhs if ( ! isset ( $ fs [ P_EPSILON ] ) ) { break ; } if ( false === next ( $ r ) ) { //echo "FOLLOW($a) []= FOLLOW($s)\n"; if ( ! isset ( $ follows [ $ s ] ) ) { //echo "FOLLOW($s) not set, required by $a \n"; //$inherits[$s] = true; continue 3 ; } foreach ( $ follows [ $ s ] as $ t ) { if ( ! isset ( $ follows [ $ a ] [ $ t ] ) ) { //echo "FOLLOW($a) []= $t \n"; $ follows [ $ a ] [ $ t ] = $ t ; $ changes ++ ; } } } } } } } while ( $ changes ) ; // check inheritance problems, uncomment to debug /*
		foreach( $inherits as $s => $bool ){
			if( ! isset($follows[$s]) ){
				trigger_error("FOLLOW($s) was never created", E_USER_NOTICE );
			}
		} 
		//*/ return $ follows ; }
Generate FOLLOW sets for each non-terminal.
@todo fix inheritance problem
@return array
Generate FOLLOW sets for each non - terminal .