Ejemplo n.º 1
0
        // ugly, but fast (as little additions to hashset as possible)
        private static void bufferCombinedLookaheads(Dictionary <Production <SYMBOL_ENUM, TREE_NODE>, Dictionary <int, SymbolChunkSet <SYMBOL_ENUM> > > precomputedRhsFirsts,
                                                     Production <SYMBOL_ENUM, TREE_NODE> production,
                                                     int rhsSeenCount,
                                                     SymbolChunkSet <SYMBOL_ENUM> afterLookaheads,
                                                     int lookaheadWidth,
                                                     List <SymbolChunk <SYMBOL_ENUM> > buffer
                                                     )
        {
            int count = buffer.Count;

            foreach (SymbolChunk <SYMBOL_ENUM> chunk in precomputedRhsFirsts[production][rhsSeenCount].Chunks)
            {
                if (chunk.Count == lookaheadWidth)
                {
                    buffer.Add(chunk);
                }
                else
                {
                    buffer.AddRange(SymbolChunkSet.MultiConcat(chunk, afterLookaheads, lookaheadWidth));
                }
            }

            if (buffer.Count == count)
            {
                buffer.AddRange(afterLookaheads.Chunks);
            }
        }
Ejemplo n.º 2
0
 public static IEnumerable <uint> MultiConcat <SYMBOL_ENUM>(uint chunk1, SymbolChunkSet <SYMBOL_ENUM> set2, int lookaheadWidth)
     where SYMBOL_ENUM : struct
 {
     foreach (uint chunk2 in set2.Chunks)
     {
         yield return(Concat(chunk1, chunk2, lookaheadWidth));
     }
 }
Ejemplo n.º 3
0
        private static SymbolChunkSet <SYMBOL_ENUM> computeCombinedLookaheads(Dictionary <Production <SYMBOL_ENUM, TREE_NODE>, Dictionary <int, SymbolChunkSet <SYMBOL_ENUM> > > precomputedRhsFirsts,
                                                                              Production <SYMBOL_ENUM, TREE_NODE> production,
                                                                              int rhsSeenCount,
                                                                              SymbolChunkSet <SYMBOL_ENUM> afterLookaheads,
                                                                              int lookaheadWidth
                                                                              )
        {
            var buffer = new List <SymbolChunk <SYMBOL_ENUM> >(Math.Max(afterLookaheads.Count, precomputedRhsFirsts[production][rhsSeenCount].Count) + 1);

            bufferCombinedLookaheads(precomputedRhsFirsts, production, rhsSeenCount, afterLookaheads, lookaheadWidth, buffer);
            return(new SymbolChunkSet <SYMBOL_ENUM>(buffer));
        }
Ejemplo n.º 4
0
 private static string dumpSymbolChunkSet(SymbolChunkSet <int> set, string symbolTypeName, Func <int, string> symbolNameConvert)
 {
     if (set == null || set.IsEmpty)
     {
         return(null);
     }
     else
     {
         return(CodeWords.New + " SymbolChunkSet<" + symbolTypeName + ">("
                + set.Chunks.Select(chunk => "SymbolChunk.Create(" + chunk.Symbols.Select(s => symbolNameConvert(s)).Join(",") + ")").Join(",")
                + ")");
     }
 }
Ejemplo n.º 5
0
        internal bool Add(SYMBOL_ENUM symbol, SymbolChunkSet <SYMBOL_ENUM> set, SYMBOL_ENUM source)
        {
            bool change = false;

            foreach (SymbolChunk <SYMBOL_ENUM> chunk in set.Chunks)
            {
                if (!covers[symbol].ContainsKey(chunk))
                {
                    covers[symbol].Add(chunk, source);
                    change = true;
                }
            }

            return(change);
        }
Ejemplo n.º 6
0
        internal static ReductionAction <SYMBOL_ENUM, TREE_NODE> Create <SYMBOL_ENUM, TREE_NODE>(SingleState <SYMBOL_ENUM, TREE_NODE> state,
                                                                                                 CoverSets <SYMBOL_ENUM> coverSets,
                                                                                                 HorizonSets <SYMBOL_ENUM> horizonSets)
            where SYMBOL_ENUM : struct
            where TREE_NODE : class
        {
            SymbolChunkSet <SYMBOL_ENUM> cover   = coverSets[state.LhsSymbol];
            SymbolChunkSet <SYMBOL_ENUM> horizon = horizonSets[state.LhsSymbol];
            // if we have internal conflict between symbols, we cannot use horizon data (because we couldn't tell if we reached horizon)
            bool use_horizon = !horizon.IsEmpty && !cover.Overlaps(horizon);
            var  action      = new ReductionAction <SYMBOL_ENUM, TREE_NODE>(state.CreateCell(), use_horizon ? horizon : null,
                                                                            use_horizon ? new SymbolChunkSet <SYMBOL_ENUM>() : null);

            return(action);
        }
Ejemplo n.º 7
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);
                    }
                }
            }
        }
Ejemplo n.º 8
0
 public static IEnumerable <uint> MultiConcat <SYMBOL_ENUM>(uint chunk,
                                                            SymbolChunkSet <SYMBOL_ENUM> tailSet,
                                                            int limitLength)
     where SYMBOL_ENUM : struct
 {
     if (SymbolChunkTraits.Count(chunk) >= limitLength)
     {
         yield return(SymbolChunkTraits.GetFirsts(chunk, limitLength));
     }
     else
     {
         foreach (uint tail_chunk in tailSet.Chunks)
         {
             yield return(SymbolChunkTraits.Concat(chunk, tail_chunk, limitLength));
         }
     }
 }
        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.º 10
0
        public SymbolChunkSet <SYMBOL_ENUM> GetFirstsOf(IEnumerable <SYMBOL_ENUM> symbols, IEnumerable <SYMBOL_ENUM> terminals, SYMBOL_ENUM errorSymbol, int lookaheadWidth)
        {
            var         sets = new List <SymbolChunkSet <SYMBOL_ENUM> >();
            SYMBOL_ENUM?last = null;

            foreach (SYMBOL_ENUM sym in symbols.Reverse())
            {
                if (!sym.Equals(errorSymbol))
                {
                    sets.Add(this[sym]);
                }
                else
                {
                    sets.Add(SymbolChunkSet.MultiplyUpTo(terminals.Except(new[] { last.Value }), lookaheadWidth));
                }
                last = sym;
            }
            sets.Reverse();

            return(SymbolChunkSet.MultiConcat(sets.ToArray(), lookaheadWidth));
        }
Ejemplo n.º 11
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.º 12
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.º 13
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);
            }
        }
Ejemplo n.º 14
0
 private SymbolChunkSet <SYMBOL_ENUM> coverAsChunkSet(SYMBOL_ENUM symbol)
 {
     return(SymbolChunkSet.Create(covers[symbol].Keys));
 }
Ejemplo n.º 15
0
 public static ReductionAction <SYMBOL_ENUM, TREE_NODE> Create <SYMBOL_ENUM, TREE_NODE>(NfaCell <SYMBOL_ENUM, TREE_NODE> cell,
                                                                                        SymbolChunkSet <SYMBOL_ENUM> acceptHorizon, SymbolChunkSet <SYMBOL_ENUM> rejectHorizon)
     where SYMBOL_ENUM : struct
     where TREE_NODE : class
 {
     return(new ReductionAction <SYMBOL_ENUM, TREE_NODE>(cell, acceptHorizon, rejectHorizon));
 }
Ejemplo n.º 16
0
 public void Add(SYMBOL_ENUM symbol, SymbolChunkSet <SYMBOL_ENUM> set)
 {
     sets.Add(symbol, set);
 }