public FirstSets <SYMBOL_ENUM> ComputeFirstSets(ref Dictionary <Production <SYMBOL_ENUM, TREE_NODE>, Dictionary <int, SymbolChunkSet <SYMBOL_ENUM> > > precomputedRhsFirsts) { initFirstSets(); while (expandFirstSets()) { ; } precomputedRhsFirsts = new Dictionary <Production <SYMBOL_ENUM, TREE_NODE>, Dictionary <int, SymbolChunkSet <SYMBOL_ENUM> > >(); foreach (Production <SYMBOL_ENUM, TREE_NODE> prod in productions.ProductionsWithNoErrorSymbol()) { var rhs_firsts = new Dictionary <int, SymbolChunkSet <SYMBOL_ENUM> >(); // =, because we could read all symbols for (int i = 0; i <= prod.RhsSymbols.Count; ++i) { rhs_firsts.Add(i, firstSets.GetFirstsOf(prod.RhsSymbols.Skip(i), terminals, syntaxErrorSymbol, lookaheadWidth)); } precomputedRhsFirsts.Add(prod, rhs_firsts); } return(firstSets); }
private void bootstrapFromFirstSets(SYMBOL_ENUM symbol) { SymbolChunkSet <SYMBOL_ENUM> follow_set = followSets[symbol]; // in all RHS of productions find our symbol foreach (Production <SYMBOL_ENUM, TREE_NODE> prod in productions.ProductionsWithNoErrorSymbol()) { for (int i = 0; i < prod.RhsSymbols.Count(); ++i) { // we are above our symbol on RHS of the production if (prod.RhsSymbols[i].Equals(symbol)) { // get first set of what can happen AFTER our symbol -- this will be follow set by definition SymbolChunkSet <SYMBOL_ENUM> chunk_set = firstSets.GetFirstsOf(prod.RhsSymbols.Skip(i + 1), terminals, syntaxErrorSymbol, lookaheadWidth); { SymbolChunkSet <SYMBOL_ENUM> tmp = new SymbolChunkSet <SYMBOL_ENUM>(); // add LHS non-terminal at the end of too short chunks as generator // because what follows LHS also follows given symbol foreach (SymbolChunk <SYMBOL_ENUM> chunk in chunk_set.Chunks) { if (chunk.Count < lookaheadWidth) { tmp.Add(chunk.Append(prod.LhsNonTerminal)); } else { tmp.Add(chunk); } } chunk_set = tmp; } if (chunk_set.IsEmpty) { chunk_set.Add(SymbolChunk.Create(prod.LhsNonTerminal)); } follow_set.Add(chunk_set); } } } }
private void bootstrapFromFirstSets(SYMBOL_ENUM symbol) { SymbolChunkSet <SYMBOL_ENUM> current_set = horizonSets[symbol]; // in all RHS of productions find our symbol foreach (Production <SYMBOL_ENUM, TREE_NODE> prod in productions.Entries) { if (symbol.Equals(prod.LhsNonTerminal) || coverSets[symbol].Contains(SymbolChunk.Create(prod.LhsNonTerminal))) { continue; } for (int i = 0; i < prod.RhsSymbols.Count(); ++i) { // we are on our symbol on RHS of the production if (prod.RhsSymbols[i].Equals(symbol)) { // get first set of what can happen AFTER our symbol -- this will be our horizon SymbolChunkSet <SYMBOL_ENUM> src_set = firstSets.GetFirstsOf(prod.RhsSymbols.Skip(i + 1), terminals, syntaxErrorSymbol, lookaheadWidth); SymbolChunkSet <SYMBOL_ENUM> chunk_set = new SymbolChunkSet <SYMBOL_ENUM>(); // add follow set at the end of too short chunks foreach (SymbolChunk <SYMBOL_ENUM> chunk in src_set.Chunks) { if (chunk.Count < lookaheadWidth) { chunk_set.Add(SymbolChunkSet.MultiConcat(chunk, followSets[prod.LhsNonTerminal], lookaheadWidth)); } else { chunk_set.Add(chunk); } } if (chunk_set.IsEmpty) { chunk_set.Add(followSets[prod.LhsNonTerminal]); } current_set.Add(chunk_set); } } } }