followOf method

SymbolSet followOf(
  1. String productionName,
  2. ProductionsMap allProductions, {
  3. required ProductionTerminals followList,
  4. required SymbolSet hasToo,
  5. required ProductionTerminals firstList,
  6. required Map<String, SymbolSet> allProducers,
})
inherited

Recursive function that receives a productions map and generates the follow set for each production

Implementation

SymbolSet followOf(
  String productionName,
  ProductionsMap allProductions, {
  required ProductionTerminals followList,
  required SymbolSet hasToo,
  required ProductionTerminals firstList,
  required Map<String, SymbolSet> allProducers,
}) {
  if (followList.containsKey(productionName)) {
    return followList[productionName]!;
  }
  final followSet = joinSets({}, hasToo);
  followList[productionName] = followSet;
  if (!allProducers.containsKey(productionName)) {
    throw ('Production $productionName is not used, please fix it');
  }
  for (final producedBy in allProducers[productionName] ?? <String>{}) {
    final producerProduction = allProductions[producedBy] ?? <List<Token>>[];
    for (var counter = 0; counter < producerProduction.length; counter++) {
      final index = getAheadSymbol(
        productionName,
        producerProduction[counter],
      );
      var getProducedByFollow = false;
      /*print(
        '$index $productionName ---> $producedBy ::= ${producerProduction[counter]}',
      );*/
      if (index >= producerProduction[counter].length) {
        getProducedByFollow = true;
      } else if (index > 0) {
        final aheadSymbol = producerProduction[counter][index];
        final aheadFirstSet = getFirst(aheadSymbol.lexeme, firstList);
        joinSets(followSet, aheadFirstSet);
        if (aheadFirstSet.contains("''") || aheadFirstSet.contains('')) {
          getProducedByFollow = true;
        }
      } else {
        continue;
      }
      if (getProducedByFollow) {
        joinSets(
          followSet,
          followOf(
            producedBy,
            allProductions,
            followList: followList,
            hasToo: {},
            firstList: firstList,
            allProducers: allProducers,
          ),
        );
      }
    }
  }
  return followSet;
}