/**
  * @param \Helstern\Nomsky\Grammar\Symbol\SymbolSet $set
  * @param NormalizedProduction $production
  * @param \Helstern\Nomsky\GrammarAnalysis\ParseSets\ParseSets $followSets
  * @param \Helstern\Nomsky\GrammarAnalysis\ParseSets\ParseSets $firstSets
  *
  * @return bool
  */
 public function processProduction(SymbolSet $set, NormalizedProduction $production, ParseSets $followSets, ParseSets $firstSets)
 {
     $rhs = $production->getRightHandSide();
     $epsilonAdded = $this->firstSetCalculator->processSymbolList($set, $rhs, $firstSets);
     if ($epsilonAdded) {
         $lhs = $production->getLeftHandSide();
         $otherSet = $followSets->getTerminalSet($lhs);
         $set->addAll($otherSet);
     }
     return $epsilonAdded;
 }
 /**
  * @param \Helstern\Nomsky\Grammar\Symbol\SymbolSet $set
  * @param SymbolOccurrence $occurrence
  * @param \Helstern\Nomsky\GrammarAnalysis\ParseSets\ParseSets $followSets
  * @param \Helstern\Nomsky\GrammarAnalysis\ParseSets\ParseSets $firstSets
  *
  * @return bool
  */
 public function processOccurrence(SymbolSet $set, SymbolOccurrence $occurrence, ParseSets $followSets, ParseSets $firstSets)
 {
     $symbol = $occurrence->getSymbol();
     $isTerminal = SymbolTypeEquals::newInstanceMatchingTerminals();
     if ($isTerminal->matchSymbol($symbol)) {
         return false;
     }
     $following = $occurrence->getFollowing();
     $epsilonAdded = $this->firstSetCalculator->processSymbolList($set, $following, $firstSets);
     if ($epsilonAdded) {
         $set->remove(new EpsilonSymbol());
         $lhs = $occurrence->getProductionNonTerminal();
         $otherSet = $followSets->getTerminalSet($lhs);
         $set->addAll($otherSet);
     }
     return true;
 }