Beispiel #1
0
        //rekurzivně projde ještě neexistující graf stavů automatu; nové vrcholy objevuje zkoumáním
        //ItemSetu
        private void exploreTransitions(State thisState)
        {
            //symboly, jež příslušejí hranám vedoucím z tohoto stavu
            IEnumerable <int> appropriateSymbols = (from item in thisState.ItemSet
                                                    where !item.IsFinal
                                                    select item.Production.RHSSymbols[item.Position]).Distinct();

            foreach (int symbol in appropriateSymbols)
            {
                ItemSet successorIS = thisState.ItemSet.NucleusAfterTransition(symbol);
                successorIS.CloseItemSet(grammar);

                //podíváme se, jestli jsme na stav s tímto ItemSetem už nenarazili
                int successorIndex;
                for (successorIndex = 0; successorIndex < parserStates.Count; successorIndex++)
                {
                    if (successorIS.SetEquals(parserStates[successorIndex].ItemSet))
                    {
                        break;
                    }
                }

                State successorState;
                if (successorIndex == parserStates.Count)
                {
                    successorState = new State(successorIndex, successorIS);
                    parserStates.Add(successorState);

                    exploreTransitions(successorState);
                }
                else
                {
                    successorState = parserStates[successorIndex];
                }


                Transition newTransition;
                if (symbol < grammar.NumTerminals)
                {
                    newTransition = new TerminalTransition(thisState, successorState, symbol);
                }
                else
                {
                    newTransition = new NonterminalTransition(thisState, successorState, symbol, numNonterminalTransitions++);
                }

                thisState.Transitions.Add(newTransition);
                successorState.AccessingStates.Add(thisState);

                if (newTransition is NonterminalTransition)
                {
                    transitionsByNonterminals[symbol - grammar.NumTerminals].Add(newTransition as NonterminalTransition);
                }
            }
        }
Beispiel #2
0
        private void printSymbolExplanations(State state, Item finalItem, BitVectorSet conflictSymbols, TextWriter writer)
        {
            //Vyrazíme ze všech vrcholů (vrcholy jsou tady neterminální hrany automatu)
            //ležících v lookback(state, finalItem), které mají ve follow množině nějaký konfliktní symbol.
            //Prohledáváním do hloubkyv grafu relace 'includes' najdeme nejbližší vrcholy, které mají v Read
            //množinách dohromady všechny hledané konfliktní symboly. Posléze vyrazíme z těchto nalezených vrcholů,
            //tentokrát po hranách relace 'reads' a budeme hledat nejbližší vrcholy, které mají v Direct Read množinách
            //dohromady všechny hledané symboly. Z posledně nalezených vrcholů už jsme vždy schopni vystopovat
            //cestu zpět přes reads, includes a lookback hrany až k původnímu konfliktnímu itemu.

            //pole předků a značky u navštívených vrcholů pro oba grafy
            NonterminalTransition[] includesPredecessors = new NonterminalTransition[numNonterminalTransitions];
            bool[] includesExplored = new bool[numNonterminalTransitions];
            NonterminalTransition[] readsPredecessors = new NonterminalTransition[numNonterminalTransitions];
            bool[] readsExplored = new bool[numNonterminalTransitions];

            BitVectorSet symbolsLeftToExplain = new BitVectorSet(conflictSymbols);

            //BFS fronty pro oba průchody obou grafů
            Queue <NonterminalTransition> includesTransitions = new Queue <NonterminalTransition>();
            Queue <NonterminalTransition> readsTransitions    = new Queue <NonterminalTransition>();

            //vrcholy, které mají v DR množinách konfliktní symboly
            List <NonterminalTransition> rootTransitions = new List <NonterminalTransition>();

            //procházení po lookback hranách
            foreach (NonterminalTransition trans in lookback(state, finalItem))
            {
                if (!follow[getTransNumber(trans)].IsDisjointWith(conflictSymbols))
                {
                    includesTransitions.Enqueue(trans);
                    includesExplored[getTransNumber(trans)] = true;
                }
            }

            //průchod přes includes hrany
            while ((includesTransitions.Count > 0) && (!symbolsLeftToExplain.IsEmpty()))
            {
                NonterminalTransition trans = includesTransitions.Dequeue();

                BitVectorSet readSet = read[getTransNumber(trans)];
                if (!readSet.IsDisjointWith(symbolsLeftToExplain))
                {
                    BitVectorSet symbolsJustExplained = readSet.GetIntersectionWith(symbolsLeftToExplain);
                    symbolsLeftToExplain -= symbolsJustExplained;
                    readsTransitions.Enqueue(trans);
                    readsExplored[getTransNumber(trans)] = true;
                }

                foreach (NonterminalTransition next in includes.GetNeighboursFor(trans))
                {
                    if (!includesExplored[getTransNumber(next)])
                    {
                        includesPredecessors[getTransNumber(next)] = trans;
                        includesExplored[getTransNumber(next)]     = true;
                        includesTransitions.Enqueue(next);
                    }
                }
            }

            //reset hledaných symbolů a průchod přes reads hrany
            symbolsLeftToExplain = new BitVectorSet(conflictSymbols);

            while ((readsTransitions.Count > 0) && (!symbolsLeftToExplain.IsEmpty()))
            {
                NonterminalTransition trans = readsTransitions.Dequeue();

                BitVectorSet DRSet = initDR(trans);
                if (!DRSet.IsDisjointWith(symbolsLeftToExplain))
                {
                    BitVectorSet symbolsJustExplained = DRSet.GetIntersectionWith(symbolsLeftToExplain);
                    symbolsLeftToExplain -= symbolsJustExplained;
                    rootTransitions.Add(trans);
                }

                foreach (NonterminalTransition next in reads.GetNeighboursFor(trans))
                {
                    if (!readsExplored[getTransNumber(next)])
                    {
                        readsPredecessors[getTransNumber(next)] = trans;
                        readsExplored[getTransNumber(next)]     = true;
                        readsTransitions.Enqueue(next);
                    }
                }
            }

            //teď už jen vystopujeme všechny potřebné cesty z neterminální hrany, která obsahovala konfliktní
            //symbol ve své DR množině, až k itemu, kde tímto symbolem přispěla a způsobila konflikt
            foreach (NonterminalTransition root in rootTransitions)
            {
                Stack <NonterminalTransition> readsPath    = new Stack <NonterminalTransition>();
                Stack <NonterminalTransition> includesPath = new Stack <NonterminalTransition>();

                NonterminalTransition trans = root;
                while (readsPredecessors[getTransNumber(trans)] != null)
                {
                    readsPath.Push(trans);
                    trans = readsPredecessors[getTransNumber(trans)];
                }

                while (includesPredecessors[getTransNumber(trans)] != null)
                {
                    includesPath.Push(trans);
                    trans = includesPredecessors[getTransNumber(trans)];
                }



                writer.Write("({0}, ", state.StateNumber);
                printItemHTML(finalItem, conflictSymbols, writer);
                writer.Write(") <b><i>lookback</i></b> (<a href=\"#State{0}\">{0}</a>, {1})", trans.Source.StateNumber,
                             getSymbolPrintName(trans.TransitionSymbol));

                foreach (NonterminalTransition transition in includesPath)
                {
                    writer.Write(" <b><i>includes</i></b> (<a href=\"#State{0}\">{0}</a>, {1})", transition.Source.StateNumber,
                                 getSymbolPrintName(transition.TransitionSymbol));
                }

                foreach (NonterminalTransition transition in readsPath)
                {
                    writer.Write(" <b><i>reads</i></b> (<a href=\"#State{0}\">{0}</a>, {1})", transition.Source.StateNumber,
                                 getSymbolPrintName(transition.TransitionSymbol));
                }

                writer.Write(" and {");

                StringBuilder explainedSymbolsString = new StringBuilder();
                foreach (int explainedSymbol in initDR(root).GetIntersectionWith(conflictSymbols))
                {
                    explainedSymbolsString.AppendFormat("<span style=\"color:red\">{0}</span>, ", getSymbolPrintName(explainedSymbol));
                }
                explainedSymbolsString.Remove(explainedSymbolsString.Length - 2, 2);

                writer.Write(explainedSymbolsString.ToString());
                writer.Write("} ⊂ <b>DR</b>(" + root.Source.StateNumber.ToString() + ", " + getSymbolPrintName(root.TransitionSymbol) + ")");

                writer.WriteLine("<br>");
            }
        }
Beispiel #3
0
        private void printSymbolExplanations(State state, Item finalItem, BitVectorSet conflictSymbols, TextWriter writer)
        {
            //Vyrazíme ze všech vrcholů (vrcholy jsou tady neterminální hrany automatu)
            //ležících v lookback(state, finalItem), které mají ve follow množině nějaký konfliktní symbol.
            //Prohledáváním do hloubkyv grafu relace 'includes' najdeme nejbližší vrcholy, které mají v Read
            //množinách dohromady všechny hledané konfliktní symboly. Posléze vyrazíme z těchto nalezených vrcholů,
            //tentokrát po hranách relace 'reads' a budeme hledat nejbližší vrcholy, které mají v Direct Read množinách
            //dohromady všechny hledané symboly. Z posledně nalezených vrcholů už jsme vždy schopni vystopovat
            //cestu zpět přes reads, includes a lookback hrany až k původnímu konfliktnímu itemu.

            //pole předků a značky u navštívených vrcholů pro oba grafy
            NonterminalTransition[] includesPredecessors = new NonterminalTransition[numNonterminalTransitions];
            bool[] includesExplored = new bool[numNonterminalTransitions];
            NonterminalTransition[] readsPredecessors = new NonterminalTransition[numNonterminalTransitions];
            bool[] readsExplored = new bool[numNonterminalTransitions];

            BitVectorSet symbolsLeftToExplain = new BitVectorSet(conflictSymbols);

            //BFS fronty pro oba průchody obou grafů
            Queue<NonterminalTransition> includesTransitions = new Queue<NonterminalTransition>();
            Queue<NonterminalTransition> readsTransitions = new Queue<NonterminalTransition>();

            //vrcholy, které mají v DR množinách konfliktní symboly
            List<NonterminalTransition> rootTransitions = new List<NonterminalTransition>();

            //procházení po lookback hranách
            foreach (NonterminalTransition trans in lookback(state, finalItem))
            {
                if (!follow[getTransNumber(trans)].IsDisjointWith(conflictSymbols))
                {
                    includesTransitions.Enqueue(trans);
                    includesExplored[getTransNumber(trans)] = true;
                }
            }

            //průchod přes includes hrany
            while ((includesTransitions.Count > 0) && (!symbolsLeftToExplain.IsEmpty()))
            {
                NonterminalTransition trans = includesTransitions.Dequeue();

                BitVectorSet readSet = read[getTransNumber(trans)];
                if (!readSet.IsDisjointWith(symbolsLeftToExplain))
                {
                    BitVectorSet symbolsJustExplained = readSet.GetIntersectionWith(symbolsLeftToExplain);
                    symbolsLeftToExplain -= symbolsJustExplained;
                    readsTransitions.Enqueue(trans);
                    readsExplored[getTransNumber(trans)] = true;
                }

                foreach (NonterminalTransition next in includes.GetNeighboursFor(trans))
                    if (!includesExplored[getTransNumber(next)])
                    {
                        includesPredecessors[getTransNumber(next)] = trans;
                        includesExplored[getTransNumber(next)] = true;
                        includesTransitions.Enqueue(next);
                    }
            }

            //reset hledaných symbolů a průchod přes reads hrany
            symbolsLeftToExplain = new BitVectorSet(conflictSymbols);

            while ((readsTransitions.Count > 0) && (!symbolsLeftToExplain.IsEmpty()))
            {
                NonterminalTransition trans = readsTransitions.Dequeue();

                BitVectorSet DRSet = initDR(trans);
                if (!DRSet.IsDisjointWith(symbolsLeftToExplain))
                {
                    BitVectorSet symbolsJustExplained = DRSet.GetIntersectionWith(symbolsLeftToExplain);
                    symbolsLeftToExplain -= symbolsJustExplained;
                    rootTransitions.Add(trans);
                }

                foreach (NonterminalTransition next in reads.GetNeighboursFor(trans))
                    if (!readsExplored[getTransNumber(next)])
                    {
                        readsPredecessors[getTransNumber(next)] = trans;
                        readsExplored[getTransNumber(next)] = true;
                        readsTransitions.Enqueue(next);
                    }
            }

            //teď už jen vystopujeme všechny potřebné cesty z neterminální hrany, která obsahovala konfliktní
            //symbol ve své DR množině, až k itemu, kde tímto symbolem přispěla a způsobila konflikt
            foreach (NonterminalTransition root in rootTransitions)
            {
                Stack<NonterminalTransition> readsPath = new Stack<NonterminalTransition>();
                Stack<NonterminalTransition> includesPath = new Stack<NonterminalTransition>();

                NonterminalTransition trans = root;
                while (readsPredecessors[getTransNumber(trans)] != null)
                {
                    readsPath.Push(trans);
                    trans = readsPredecessors[getTransNumber(trans)];
                }

                while (includesPredecessors[getTransNumber(trans)] != null)
                {
                    includesPath.Push(trans);
                    trans = includesPredecessors[getTransNumber(trans)];
                }

                writer.Write("({0}, ", state.StateNumber);
                printItemHTML(finalItem, conflictSymbols, writer);
                writer.Write(") <b><i>lookback</i></b> (<a href=\"#State{0}\">{0}</a>, {1})", trans.Source.StateNumber,
                                                                getSymbolPrintName(trans.TransitionSymbol));

                foreach (NonterminalTransition transition in includesPath)
                    writer.Write(" <b><i>includes</i></b> (<a href=\"#State{0}\">{0}</a>, {1})", transition.Source.StateNumber,
                                                                getSymbolPrintName(transition.TransitionSymbol));

                foreach (NonterminalTransition transition in readsPath)
                    writer.Write(" <b><i>reads</i></b> (<a href=\"#State{0}\">{0}</a>, {1})", transition.Source.StateNumber,
                                                                getSymbolPrintName(transition.TransitionSymbol));

                writer.Write(" and {");

                StringBuilder explainedSymbolsString = new StringBuilder();
                foreach (int explainedSymbol in initDR(root).GetIntersectionWith(conflictSymbols))
                    explainedSymbolsString.AppendFormat("<span style=\"color:red\">{0}</span>, ", getSymbolPrintName(explainedSymbol));
                explainedSymbolsString.Remove(explainedSymbolsString.Length - 2, 2);

                writer.Write(explainedSymbolsString.ToString());
                writer.Write("} ⊂ <b>DR</b>(" + root.Source.StateNumber.ToString() + ", " + getSymbolPrintName(root.TransitionSymbol) + ")");

                writer.WriteLine("<br>");
            }
        }