/** * Checks if the automaton matches an input stream. The * matching will be performed from a specified position. This * method will not read any characters from the stream, just * peek ahead. The comparison can be done either in * case-sensitive or case-insensitive mode. * * @param input the input stream to check * @param pos the starting position * @param caseInsensitive the case-insensitive flag * * @return the match value, or * null if no match was found * * @throws IOException if an I/O error occurred */ public TokenPattern Match(ReaderBuffer buffer, bool caseInsensitive) { TokenPattern result = null; DFAState state; int pos = 0; int c; c = buffer.Peek(0); if (c < 0) { return(null); } if (caseInsensitive) { c = Char.ToLower((char)c); } if (c < 128) { state = ascii[c]; if (state == null) { return(null); } else if (state.value != null) { result = state.value; } pos++; } else { state = nonAscii; } while ((c = buffer.Peek(pos)) >= 0) { state = state.tree.Find((char)c, caseInsensitive); if (state == null) { break; } else if (state.value != null) { result = state.value; } pos++; } return(result); }
/** * 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. this.queue.Clear(); peekChar = buffer.Peek(0); if (0 <= peekChar && peekChar < 128) { state = this.initialChar[peekChar]; if (state != null) { this.queue.AddLast(state); } } if (peekChar >= 0) { this.initial.MatchTransitions((char)peekChar, this.queue, true); } this.queue.MarkEnd(); peekChar = buffer.Peek(1); // The remaining match loop processes all subsequent states while (!this.queue.Empty) { if (this.queue.Marked) { pos++; peekChar = buffer.Peek(pos); this.queue.MarkEnd(); } state = this.queue.RemoveFirst(); if (state.value != null) { match.Update(pos, state.value); } if (peekChar >= 0) { state.MatchTransitions((char)peekChar, this.queue, false); } } return(length); }
/** * Checks if the start of the input stream matches this * regular expression. * * @param buffer the input buffer to check * * @return the longest match found, or * zero (0) if no match was found * * @throws IOException if an I/O error occurred */ public override int Match(ReaderBuffer buffer) { Match m; // Ugly hack since .NET doesn't have a flag for when the // end of the input string was encountered... buffer.Peek(1024 * 16); // Also, there is no API to limit the search to the specified // position, so we double-check the index afterwards instead. m = reg.Match(buffer.ToString(), buffer.Position); if (m.Success && m.Index == buffer.Position) { return(m.Length); } else { return(0); } }
/** * Finds the next token on the stream. This method will return * null when end of file has been reached. It will return a * parse exception if no token matched the input stream. * * @return the next token found, or * null if end of file was encountered * * @throws ParseException if the input stream couldn't be read or * parsed correctly */ private Token NextToken() { string str; int line; int column; try { lastMatch.Clear(); stringDfaMatcher.Match(buffer, lastMatch); nfaMatcher.Match(buffer, lastMatch); regExpMatcher.Match(buffer, lastMatch); if (lastMatch.Length > 0) { line = buffer.LineNumber; column = buffer.ColumnNumber; str = buffer.Read(lastMatch.Length); return(NewToken(lastMatch.Pattern, str, line, column)); } else if (buffer.Peek(0) < 0) { return(null); } else { line = buffer.LineNumber; column = buffer.ColumnNumber; throw new ParseException( ParseException.ErrorType.UNEXPECTED_CHAR, buffer.Read(1), line, column); } } catch (IOException e) { throw new ParseException(ParseException.ErrorType.IO, e.Message, -1, -1); } }