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;
	}