public Tokenizer(string input) { RootToken = currentToken = new Token(TokenType.Root, "", null); StringReader reader = new StringReader(input); while (true) { int nextCharNum = reader.Read(); if (nextCharNum == -1) //end of expression { RootToken.AddChild(new Token(TokenType.EOF, "", null)); break; } char nextChar = (char)nextCharNum; if (Char.IsWhiteSpace(nextChar)) { continue; } if (Char.IsNumber(nextChar) || (nextChar == '-' && Char.IsNumber((char)reader.Peek()))) //number, or minus sign before number { string fullNum = nextChar.ToString(); while (Char.IsNumber((char)reader.Peek()) || (char)reader.Peek() == '.') { fullNum += (char)reader.Read(); //get the full number } double temp; if (!double.TryParse(fullNum, out temp)) { throw new ExpressionParseException(fullNum + " is not a valid number"); } Token t = new Token(TokenType.Number, fullNum, currentToken); currentToken.AddChild(t); } else if (Parser.Operators.ContainsKey(nextChar)) //operator { Token t = new Token(TokenType.Operator, nextChar.ToString(), currentToken); currentToken.AddChild(t); } else if (nextChar == ')') //end of function or group { currentToken = currentToken.Parent; } else if (nextChar == '(') //open of group { Token t = new Token(TokenType.Group, "", currentToken); currentToken.AddChild(t); currentToken = t; } else if (nextChar == ',') { if (currentToken.Type == TokenType.Root) { throw new ExpressionParseException("Argument seperator while not in function"); } Token t = new Token(TokenType.ArgSep, "", currentToken); currentToken.AddChild(t); } else { string functionName = nextChar.ToString(); while (true) { int c = reader.Peek(); if (c == -1) { throw new ExpressionParseException("End of string present before function end"); } if ((char)c == '(') // function name end, start of args { break; } functionName += (char)reader.Read(); } if (!Parser.Functions.ContainsKey(functionName)) { throw new ExpressionParseException("Unknown function '" + functionName + "'"); } Token t = new Token(TokenType.Function, functionName, currentToken); currentToken.AddChild(t); currentToken = t; } } }