} // ReadNextToken // Parse an identifier beginning at the current stream location. private Token ParseIdentifier(SrcLoc loc) { // Get a buffer from which we can parse the identifier. char[] charBuf; int startPos; int bufLen = buffer.GetBuffer(maxTokenLen, out charBuf, out startPos); if (bufLen > maxTokenLen) { bufLen = maxTokenLen; } // Find the last character in the identifier. We begin // at 1 because we know (from matcher.Match returning // TokDispatch.ident) that the identifier is at least // one character long. int tokenLen = 1; while (tokenLen < bufLen && CharUtils.IsIdentifierChar(charBuf[startPos + tokenLen])) { tokenLen++; } Identifier token = new Identifier(); token.rawText = buffer.ConsumeString(tokenLen); loc.len = tokenLen; token.loc = loc; return(token); } // ParseIdentifier
} // AddString // If the current position of the TextReaderBuffer matches any // of our registered strings, then set length to the length of the // longest such string, set info to the value supplied in AddString, // and return true. Otherwise leave length and info undefined, and // return false. public bool Match(TextReaderBuffer reader, out int length, out int info) { // We don't really need to assign length and info here, but we do so // so that the compiler won't complain on any of the "return false" // paths. length = 0; info = 0; char[] buffer; int bufStart; int bufLen = reader.GetBuffer(maxLen, out buffer, out bufStart); if (bufLen <= 0) { return(false); } // NOTE (snewman 7/12/01): this is currently implemented as a // simple linear search over all registered strings, after // discriminating by the initial character. Many more efficient // algorithms are possible, such as binary search or tries. Doesn't // seem worthwhile. int initialChar = buffer[bufStart]; bufStart++; bufLen--; if (initialChar >= strings.Length) { return(false); } for (StringEntry candidate = strings[initialChar]; candidate != null; candidate = candidate.next) { if (bufLen >= candidate.headlessString.Length && MatchChars(buffer, bufStart, candidate.headlessString)) { if (!candidate.isIdentifier || bufLen == candidate.headlessString.Length || !CharUtils.IsIdentifierChar(buffer[bufStart + candidate.headlessString.Length])) { length = candidate.headlessString.Length + 1; info = candidate.info; return(true); } } } return(false); } // Match