Ejemplo n.º 1
0
        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);
                    }
                }
            }
        }
Ejemplo n.º 3
0
        private void resolveFollowSetsDependencies()
        {
            bool changed = true;

            while (changed)
            {
                changed = false;

                foreach (SymbolChunkSet <SYMBOL_ENUM> fset in followSets.Values)
                {
                    // only empty sets or without generators
                    if (fset.Chunks.All(chunk => !chunk.Symbols.Any() || !nonTerminals.Contains(chunk.Symbols.Last())))
                    {
                        continue;
                    }

                    var replacement = new SymbolChunkSet <SYMBOL_ENUM>();

                    foreach (SymbolChunk <SYMBOL_ENUM> chunk in fset.Chunks)
                    {
                        if (!chunk.Symbols.Any() || !nonTerminals.Contains(chunk.Symbols.Last()))
                        {
                            replacement.Add(chunk);
                        }
                        else
                        {
                            replacement.Add(SymbolChunkSet.MultiConcat(chunk.SkipLast(), followSets[chunk.Symbols.Last()], lookaheadWidth));
                        }
                    }

                    if (fset.Equals(replacement))
                    {
                        continue;
                    }

                    fset.Assign(replacement);
                    changed = true;
                }
            }
        }
Ejemplo n.º 4
0
        private CoverSets <SYMBOL_ENUM> initCoverSets()
        {
            var cover_sets = new CoverSets <SYMBOL_ENUM>();

            foreach (SYMBOL_ENUM sym in terminals)
            {
                var set = new SymbolChunkSet <SYMBOL_ENUM>();
                set.Add(SymbolChunk.Create(sym));
                cover_sets.Add(sym, set, sym);
            }

            // fill non terminals with everything found in the productions, terminals will stay as they are added here
            // non terminals will serve as generators
            foreach (SYMBOL_ENUM non_term in nonTerminals)
            {
                var set = new SymbolChunkSet <SYMBOL_ENUM>();
                foreach (Production <SYMBOL_ENUM, TREE_NODE> prod in productions.FilterByLhs(non_term))
                {
                    foreach (SYMBOL_ENUM sym in prod.RhsSymbols)
                    {
                        // if we have error symbol inside production it means LHS cover all non-terminals, because
                        // error symbol for that LHS covers everything except what stands after error symbol (stop marker)
                        // thus, everything except stop marker plus stop marker gives --> everything
                        if (sym.Equals(syntaxErrorSymbol))
                        {
                            set.Add(terminals.Select(it => SymbolChunk.Create(it)));
                        }
                        else
                        {
                            set.Add(SymbolChunk.Create(sym));
                        }
                    }
                }

                cover_sets.Add(non_term, set, non_term);
            }

            return(cover_sets);
        }
Ejemplo n.º 5
0
        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);
            }
        }