public BuilderHorizonSets(Productions <SYMBOL_ENUM, TREE_NODE> productions, int lookaheadWidth, FirstSets <SYMBOL_ENUM> firstSets, CoverSets <SYMBOL_ENUM> coverSets, FollowSets <SYMBOL_ENUM> followSets) : base(productions, lookaheadWidth) { this.firstSets = firstSets; this.followSets = followSets; this.coverSets = coverSets; if (!coverSets.HasNonTerminals || lookaheadWidth != coverSets.LookaheadWidth) { throw new ArgumentException("Internal error."); } }
private void initFirstSets() { firstSets = new FirstSets <SYMBOL_ENUM>(lookaheadWidth); foreach (SYMBOL_ENUM sym in terminals) { var set = new SymbolChunkSet <SYMBOL_ENUM>(); set.Add(SymbolChunk.Create(sym)); firstSets.Add(sym, set); } foreach (SYMBOL_ENUM sym in nonTerminals) { var set = new SymbolChunkSet <SYMBOL_ENUM>(); // iterate over all productions for this symbol except for error recovery productions foreach (Production <SYMBOL_ENUM, TREE_NODE> prod in productions .FilterByLhs(sym) .Where(it => !it.RhsSymbols.Contains(syntaxErrorSymbol))) { // we take only terminals from front IEnumerable <SYMBOL_ENUM> first_chunk = prod.RhsSymbols.TakeWhile(it => terminals.Contains(it)); int count = first_chunk.Count(); if (count >= lookaheadWidth) // we have more than enough { set.Add(SymbolChunk.Create(first_chunk.Take(lookaheadWidth))); } // we have less, but there was no more here else if (count == prod.RhsSymbols.Count) { set.Add(SymbolChunk.Create(first_chunk)); } } firstSets.Add(sym, set); } }
public BuilderFollowSets(Productions <SYMBOL_ENUM, TREE_NODE> productions, int lookaheadWidth, FirstSets <SYMBOL_ENUM> firstSets) : base(productions, lookaheadWidth) { this.firstSets = firstSets; }