示例#1
0
        /// <summary>
        /// Loads the specified DFA automaton
        /// </summary>
        /// <param name="automaton">An automaton</param>
        private void LoadDFA(Automaton automaton)
        {
            dfa = new Automata.DFA();
            for (int i = 0; i != automaton.StatesCount; i++)
            {
                dfa.CreateState();
            }
            for (int i = 0; i != automaton.StatesCount; i++)
            {
                Automata.DFAState current   = dfa.States[i];
                AutomatonState    stateData = automaton.GetState(i);
                // retrieve the matched terminals
                for (int j = 0; j != stateData.TerminalsCount; j++)
                {
                    MatchedTerminal mt       = stateData.GetTerminal(j);
                    Terminal        terminal = terminals[mt.Index];
                    current.AddItem(terminal);
                    if (mt.Context != 0)
                    {
                        terminals[mt.Index].Context = mt.Context;
                    }
                }
                // retrieve the transitions
                for (int j = 0; j != 256; j++)
                {
                    int  next = stateData.GetCachedTransition(j);
                    char c    = Convert.ToChar(j);
                    if (next != Automaton.DEAD_STATE)
                    {
                        current.AddTransition(new CharSpan(c, c), dfa.States[next]);
                    }
                }

                for (int j = 0; j != stateData.BulkTransitionsCount; j++)
                {
                    AutomatonTransition transition = stateData.GetBulkTransition(j);
                    current.AddTransition(new CharSpan(Convert.ToChar(transition.Start), Convert.ToChar(transition.End)), dfa.States[transition.Target]);
                }
                current.RepackTransitions();
            }
        }
示例#2
0
        /// <summary>
        /// Generates the given state binary data
        /// </summary>
        /// <param name="writer">The output writer</param>
        /// <param name="state">The state to export</param>
        private void GenerateDataFor(BinaryWriter writer, Automata.DFAState state)
        {
            // build the transition data
            ushort[] cache = new ushort[256];
            for (int i = 0; i != 256; i++)
            {
                cache[i] = Automaton.DEAD_STATE;
            }
            ushort cached = 0;           // the number of cached transitions
            ushort slow   = 0;           // the number of non-cached transitions

            foreach (CharSpan span in state.Transitions)
            {
                if (span.Begin <= 255)
                {
                    cached++;
                    int end = span.End;
                    if (end >= 256)
                    {
                        end = 255;
                        slow++;
                    }
                    for (int i = span.Begin; i <= end; i++)
                    {
                        cache[i] = (ushort)state.GetChildBy(span).ID;
                    }
                }
                else
                {
                    slow++;
                }
            }

            // build the matched terminals data
            List <ushort> contextIDs = new List <ushort>();
            List <ushort> matched    = new List <ushort>();

            foreach (Automata.FinalItem item in state.Items)
            {
                Grammars.Terminal terminal = item as Grammars.Terminal;
                if (!contextIDs.Contains((ushort)terminal.Context))
                {
                    // this is the first time this context is found in the current DFA state
                    // this is the terminal with the most priority for this context
                    contextIDs.Add((ushort)terminal.Context);
                    matched.Add((ushort)terminals.IndexOf(terminal));
                }
            }

            // write the number of matched terminals
            writer.Write((ushort)matched.Count);
            // write the total numer of transitions
            writer.Write((ushort)(slow + cached));
            // write the number of non-cached transitions
            writer.Write(slow);
            // write the matched terminals
            for (int i = 0; i != matched.Count; i++)
            {
                writer.Write(contextIDs[i]);
                writer.Write(matched[i]);
            }
            // write the cached transitions
            for (int i = 0; i != 256; i++)
            {
                writer.Write(cache[i]);
            }
            // write the non-cached transitions
            List <CharSpan> keys = new List <CharSpan>(state.Transitions);

            keys.Sort(new System.Comparison <CharSpan>(CharSpan.CompareReverse));
            foreach (CharSpan span in keys)
            {
                if (span.End <= 255)
                {
                    break;                     // the rest of the transitions are in the cache
                }
                ushort begin = span.Begin;
                if (begin <= 255)
                {
                    begin = 256;
                }
                writer.Write(begin);
                writer.Write(Convert.ToUInt16(span.End));
                writer.Write((ushort)state.GetChildBy(span).ID);
            }
        }