/** * Calculates the first set of the symbol $source and adds it's elements to $set * * @param \Helstern\Nomsky\Grammar\Symbol\SymbolSet $set * @param \Helstern\Nomsky\Grammar\Symbol\Symbol $source * @param \Helstern\Nomsky\GrammarAnalysis\ParseSets\ParseSets $firstSets * * @return boolean if the epsilon symbol was added to $set */ public function processSymbol(SymbolSet $set, Symbol $source, ParseSets $firstSets) { $symbolIsEpsilon = SymbolIsEpsilon::singletonInstance(); if ($symbolIsEpsilon->matchSymbol($source)) { $set->add(new EpsilonSymbol()); return true; } $symbolsIsNonTerminal = SymbolTypeEquals::newInstanceMatchingNonTerminals(); if ($symbolsIsNonTerminal->matchSymbol($source)) { $epsilonCounter = new MatchCountingInterceptor($symbolIsEpsilon); $acceptPredicate = Inverter::newInstance($epsilonCounter); $otherSet = $firstSets->filterTerminalSet($source, $acceptPredicate); $set->addAll($otherSet); if ($epsilonCounter->getMatchCount() > 0) { $set->add(new EpsilonSymbol()); return true; } return false; } $set->add($source); return false; }