Beispiel #1
0
        /// <summary>
        /// Gets the index of the terminal with the highest priority that is possible in the contexts
        /// </summary>
        /// <param name="state">The DFA state</param>
        /// <param name="provider">The current applicable contexts</param>
        /// <returns>The index of the terminal</returns>
        private int GetTerminalFor(int state, IContextProvider provider)
        {
            AutomatonState  stateData     = automaton.GetState(state);
            MatchedTerminal mt            = stateData.GetTerminal(0);
            int             id            = symTerminals[mt.Index].ID;
            int             currentResult = mt.Index;

            if (id == separatorID)
            {
                // the separator trumps all
                return(currentResult);
            }
            int currentPriority = provider.GetContextPriority(mt.Context, id);

            for (int i = 1; i != stateData.TerminalsCount; i++)
            {
                mt = stateData.GetTerminal(i);
                id = symTerminals[mt.Index].ID;
                if (id == separatorID)
                {
                    // the separator trumps all
                    return(mt.Index);
                }
                int priority = provider.GetContextPriority(mt.Context, id);
                if (currentPriority < 0 || (priority >= 0 && priority < currentPriority))
                {
                    currentResult   = mt.Index;
                    currentPriority = priority;
                }
            }
            return(currentResult);
        }
Beispiel #2
0
        /// <summary>
        /// Inspects a head with a specified character ahead
        /// </summary>
        /// <param name="head">The head to inspect</param>
        /// <param name="offset">The current offset from the original index</param>
        /// <param name="current">The leading character in the input</param>
        private void Inspect(Head head, int offset, char current)
        {
            AutomatonState stateData = automaton.GetState(head.State);

            // is it a matching state
            if (stateData.TerminalsCount != 0 && stateData.GetTerminal(0).Index != separator)
            {
                OnMatchingHead(head, offset);
            }
            if (head.Distance >= maxDistance || stateData.IsDeadEnd)
            {
                // cannot stray further
                return;
            }
            // could be a straight match
            int target = stateData.GetTargetBy(current);

            if (target != Automaton.DEAD_STATE)
            {
                // it is!
                PushHead(head, target);
            }
            // could try a drop
            PushHead(head, head.State, offset);
            // lookup the transitions
            ExploreTransitions(head, stateData, offset, false);
            ExploreInsertions(head, offset, false, current);
        }
Beispiel #3
0
        /// <summary>
        /// Inspects a head while at the end of the input
        /// </summary>
        /// <param name="head">The head to inspect</param>
        /// <param name="offset">The current offset from the original index</param>
        private void InspectAtEnd(Head head, int offset)
        {
            AutomatonState stateData = automaton.GetState(head.State);

            // is it a matching state
            if (stateData.TerminalsCount != 0 && stateData.GetTerminal(0).Index != separator)
            {
                OnMatchingHead(head, offset);
            }
            if (head.Distance >= maxDistance || stateData.IsDeadEnd)
            {
                // cannot stray further
                return;
            }
            // lookup the transitions
            ExploreTransitions(head, stateData, offset, true);
            ExploreInsertions(head, offset, true, '\0');
        }
Beispiel #4
0
        /// <summary>
        /// Explores an insertion
        /// </summary>
        /// <param name="head">The head to inspect</param>
        /// <param name="offset">The current offset from the original index</param>
        /// <param name="atEnd">Whether the current index is at the end of the input</param>
        /// <param name="current">The leading character in the input</param>
        /// <param name="state">The DFA state for the insertion</param>
        /// <param name="distance">The distance associated to this insertion</param>
        private void ExploreInsertion(Head head, int offset, bool atEnd, char current, int state, int distance)
        {
            AutomatonState stateData = automaton.GetState(state);

            if (stateData.TerminalsCount != 0 && stateData.GetTerminal(0).Index != separator)
            {
                OnMatchingInsertion(head, offset, state, distance);
            }
            if (!atEnd)
            {
                int target = stateData.GetTargetBy(current);
                if (target != Automaton.DEAD_STATE)
                {
                    PushHead(head, target, offset, distance);
                }
            }
            if (distance >= maxDistance)
            {
                return;
            }
            // continue insertion
            ExploreTransitions(head, stateData, offset, true);
        }