Exemplo n.º 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);
        }
Exemplo n.º 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);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Explores a state transition
 /// </summary>
 /// <param name="head">The current head</param>
 /// <param name="stateData">The data of the DFA state</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>
 private void ExploreTransitions(Head head, AutomatonState stateData, int offset, bool atEnd)
 {
     for (int i = 0; i != 256; i++)
     {
         int target = stateData.GetCachedTransition(i);
         if (target == Automaton.DEAD_STATE)
         {
             continue;
         }
         ExploreTransitionToTarget(head, target, offset, atEnd);
     }
     for (int i = 0; i != stateData.BulkTransitionsCount; i++)
     {
         ExploreTransitionToTarget(head, stateData.GetBulkTransition(i).Target, offset, atEnd);
     }
 }
Exemplo n.º 4
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');
        }
Exemplo n.º 5
0
        /// <summary>
        /// Runs the lexer's DFA to match a terminal in the input ahead
        /// </summary>
        /// <param name="index">The current start index in the input text</param>
        /// <returns>The matching DFA state and length</returns>
        internal TokenMatch RunDFA(int index)
        {
            if (text.IsEnd(index))
            {
                // At the end of input
                // The only terminal matched at state index 0 is $
                return(new TokenMatch(0, 0));
            }

            TokenMatch result = new TokenMatch(0);
            int        state  = 0;
            int        i      = index;

            while (state != Automaton.DEAD_STATE)
            {
                AutomatonState stateData = automaton.GetState(state);
                // Is this state a matching state ?
                if (stateData.TerminalsCount != 0)
                {
                    result = new TokenMatch(state, i - index);
                }
                // No further transition => exit
                if (stateData.IsDeadEnd)
                {
                    break;
                }
                // At the end of the buffer
                if (text.IsEnd(i))
                {
                    break;
                }
                char current = text.GetValue(i);
                i++;
                // Try to find a transition from this state with the read character
                state = stateData.GetTargetBy(current);
            }
            return(result);
        }
Exemplo n.º 6
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);
        }