Beispiel #1
0
 /**
  * @return ParseSets
  */
 public static function followSets()
 {
     $sets = new ParseSets([StandardSymbol::nonTerminal('S'), StandardSymbol::nonTerminal('B'), StandardSymbol::nonTerminal('C')]);
     $sets->addTerminal(StandardSymbol::nonTerminal('S'), StandardSymbol::terminal('e'));
     $sets->addTerminal(StandardSymbol::nonTerminal('S'), new EpsilonSymbol());
     $sets->addTerminal(StandardSymbol::nonTerminal('B'), StandardSymbol::terminal('e'));
     $sets->addTerminal(StandardSymbol::nonTerminal('B'), new EpsilonSymbol());
     $sets->addTerminal(StandardSymbol::nonTerminal('C'), StandardSymbol::terminal('e'));
     $sets->addTerminal(StandardSymbol::nonTerminal('C'), new EpsilonSymbol());
     return $sets;
 }
Beispiel #2
0
 /**
  * @param array|NormalizedProduction[] $productions
  * @param ParseSets $firstSets
  * @param SymbolSet $emptySet
  *
  * @return SetsGenerator
  */
 public function generateFirstSets(array $productions, ParseSets $firstSets, SymbolSet $emptySet)
 {
     //add epsilon to the first sets of the non terminals which generate epsilon
     foreach ($productions as $production) {
         $lhs = $production->getLeftHandSide();
         if ($emptySet->contains($lhs)) {
             $firstSets->addEpsilon($lhs);
         }
     }
     //initialize the obvious first sets of productions which start with a terminal
     foreach ($productions as $production) {
         $symbol = $production->getFirstSymbol();
         if ($symbol->getType() == Symbol::TYPE_TERMINAL) {
             $firstSets->addTerminal($production->getLeftHandSide(), $symbol);
         }
     }
     //initialize first sets for productions which contain several non-terminals
     do {
         $changes = false;
         foreach ($productions as $production) {
             $updateSet = new ArraySet();
             $rhs = $production->getRightHandSide();
             $this->firstSetCalculator->processSymbolList($updateSet, $rhs, $firstSets);
             $nonTerminal = $production->getLeftHandSide();
             $changes |= $firstSets->addAllTerminals($nonTerminal, $updateSet);
         }
     } while ($changes);
     return $this;
 }
 /**
  * @param array|Symbol[] $nonTerminals
  * @param array|Symbol[][] $parseSets
  *
  * @return \Helstern\Nomsky\GrammarAnalysis\ParseSets\ParseSets
  */
 private function buildFirstSets(array $nonTerminals, array $parseSets)
 {
     $firstSets = new ParseSets(array_values($nonTerminals));
     foreach ($parseSets as $nonTerminal => $listOfTerminals) {
         foreach ($listOfTerminals as $terminal) {
             $firstSets->addTerminal($nonTerminals[$nonTerminal], $terminal);
         }
     }
     return $firstSets;
 }