public TokenStream Tokenize(string source)
{
List<Token> tokens = new List<Token>();
using (StringReader reader = new StringReader(source))
{
while (true)
{
// Peek at the next value in the string.
if (reader.Peek() == -1)
{
break;
}
char value = (char)reader.Peek();
// Is the value numeric?
if (char.IsDigit(value))
{
tokens.Add(this.ParseNumber(reader));
}
// Is this a letter?
else if (char.IsLetter(value))
{
tokens.Add(this.ParseWord(reader));
}
// Left parenthesis?
else if (value == '(')
{
reader.Read();
tokens.Add(new Token(TokenType.OpeningParenthesis, '('));
}
// Left parenthesis?
else if (value == ')')
{
reader.Read();
tokens.Add(new Token(TokenType.ClosingParenthesis, ')'));
}
// Separator?
else if(value == ',')
{
reader.Read();
tokens.Add(new Token(TokenType.Separator, ','));
}
else if (char.IsWhiteSpace(value))
{
reader.Read();
continue;
}
else
{
reader.Read(); // Consume the character.
if (_operations.Contains(value))
{
// This is an arithmetic operation.
TokenType operation = TokenType.Unknown;
switch (value)
{
case '+': operation = TokenType.Addition; break;
case '-': operation = TokenType.Subtraction; break;
case '*': operation = TokenType.Multiplication; break;
case '/': operation = TokenType.Division; break;
case '%': operation = TokenType.Modulus; break;
case '^': operation = TokenType.Exponentiation; break;
}
if (operation != TokenType.Unknown)
{
tokens.Add(new Token(operation, value));
}
}
else
{
// We don't know how to process this token.
string message = string.Format("Unknown token '{0}' in expression.", value);
throw new MathExpressionException("Invalid expression.", message);
}
}
}
}
return new TokenStream(tokens, TokenNotation.Infix);
}