// generator is the non-terminal placed at the end of the chunk // such non-terminal generates what can follow it, which can contain also non-terminal at the end // which generates... // ...until we get the length of required lookahead count public FollowSets <SYMBOL_ENUM> ComputeFollowSets() { followSets = new FollowSets <SYMBOL_ENUM>(lookaheadWidth); // fill all symbols with initially empty follow set foreach (SYMBOL_ENUM symbol in nonTerminals.Concat(terminals)) { followSets.Add(symbol, new SymbolChunkSet <SYMBOL_ENUM>()); } followSets[startSymbol].Add(SymbolChunk.CreateRepeat(eofSymbol, lookaheadWidth)); foreach (SYMBOL_ENUM symbol in nonTerminals.Concat(terminals)) { bootstrapFromFirstSets(symbol); } // each chunk can have only terminals, or terminals + 1 non terminal at the end (as FollowSet tail generator) resolveFollowSetsDependencies(); // removal of follow sets "generators" foreach (SymbolChunkSet <SYMBOL_ENUM> fset in followSets.Values) { fset.RemoveWhere(chunk => nonTerminals.Contains(chunk.Symbols.Last())); } return(followSets); }
public HorizonSets <SYMBOL_ENUM> ComputeHorizonSets() { horizonSets = new HorizonSets <SYMBOL_ENUM>(lookaheadWidth); // fill all symbols with initially empty set foreach (SYMBOL_ENUM symbol in nonTerminals.Concat(terminals)) { horizonSets.Add(symbol, new SymbolChunkSet <SYMBOL_ENUM>()); } horizonSets[startSymbol].Add(SymbolChunk.CreateRepeat(eofSymbol, lookaheadWidth)); foreach (SYMBOL_ENUM symbol in nonTerminals.Concat(terminals)) { bootstrapFromFirstSets(symbol); } return(horizonSets); }