/** * Checks if this NFA matches the specified input text. The * matching will be performed from position zero (0) in the * buffer. This method will not read any characters from the * stream, just peek ahead. * * @param buffer the input buffer to check * @param match the token match to update * * @return the number of characters matched, or * zero (0) if no match was found * * @throws IOException if an I/O error occurred */ public int Match(ReaderBuffer buffer, TokenMatch match) { int length = 0; int pos = 1; int peekChar; NFAState state; // The first step of the match loop has been unrolled and // optimized for performance below. queue.Clear(); peekChar = buffer.Peek(0); if (0 <= peekChar && peekChar < 128) { state = initialChar[peekChar]; if (state != null) { queue.AddLast(state); } } if (peekChar >= 0) { initial.MatchTransitions((char)peekChar, queue, true); } queue.MarkEnd(); peekChar = buffer.Peek(1); // The remaining match loop processes all subsequent states while (!queue.Empty) { if (queue.Marked) { pos++; peekChar = buffer.Peek(pos); queue.MarkEnd(); } state = queue.RemoveFirst(); if (state.value != null) { match.Update(pos, state.value); } if (peekChar >= 0) { state.MatchTransitions((char)peekChar, queue, false); } } return(length); }
/** * Adds all the epsilon transition targets to the specified * queue. * * @param queue the state queue */ public void MatchEmpty(NFAStateQueue queue) { NFATransition trans; NFAState target; for (int i = 0; i < outgoing.Length; i++) { trans = outgoing[i]; if (trans is NFAEpsilonTransition) { target = trans.state; queue.AddLast(target); if (target.epsilonOut) { target.MatchEmpty(queue); } } } }
/** * Attempts a match on each of the transitions leading from * this state. If a match is found, its state will be added * to the queue. If the initial match flag is set, epsilon * transitions will also be matched (and their targets called * recursively). * * @param ch the character to match * @param queue the state queue * @param initial the initial match flag */ public void MatchTransitions(char ch, NFAStateQueue queue, bool initial) { NFATransition trans; NFAState target; for (int i = 0; i < outgoing.Length; i++) { trans = outgoing[i]; target = trans.state; if (initial && trans is NFAEpsilonTransition) { target.MatchTransitions(ch, queue, true); } else if (trans.Match(ch)) { queue.AddLast(target); if (target.epsilonOut) { target.MatchEmpty(queue); } } } }