using System.Collections.Generic;
static bool running = true;
public static void Main()
Console.WriteLine("Enter an expression, or \"stop\" to exit.");
var input = Console.ReadLine();
var tokenList = Tokenizer.Tokenize(input);
Console.WriteLine("Tokenizer output:");
foreach (var t in tokenList.Tokens)
if (t.Type == TokenType.ClosedParanthesis || t.Type == TokenType.ClosedAbsolute)
for (var i = 0; i < depth; i++)
var output = space + t.Value;
var toAdd = 15 - output.Length;
for (var i = 0; i < toAdd; i++)
Console.WriteLine(output + t.StartIndex.ToString("000") + " : " + t.Type);
if (t.Type == TokenType.OpenParanthesis || t.Type == TokenType.OpenAbsolute)
public int StartIndex { get; set; }
public TokenType Type { get; set; }
public string Value { get; set; }
public Token(TokenType type, string value, int start)
public static class TokenExtensions
public static List<TokenType> OperatorTokenTypes = new List<TokenType>()
TokenType.Multiplacation,
public static List<TokenType> OperandTokenTypes = new List<TokenType>()
public static bool IsOperator(this TokenType type)
return OperatorTokenTypes.Contains(type);
public static bool IsOperand(this TokenType type)
return OperandTokenTypes.Contains(type);
public static class Tokenizer
public static List<char> AllowedVariables = new List<char>()
public static TokenList Tokenize(string input)
var matchQuery = from word in input.ToCharArray()
if (matchQuery.Count() > 1)
throw new InvalidEquationExpressionException("More than one equals sign!");
var matchQuery2 = from word in input.ToCharArray()
where word == searchTerm2
var matchQuery3 = from word in input.ToCharArray()
where word == searchTerm3
if (matchQuery2.Count() != matchQuery3.Count())
throw new InvalidEquationExpressionException("Different counts of open paranthesis as closed paranthesis!");
var tokens = new List<Token>();
var inputChars = input.ToCharArray();
for (var i = 0; i < inputChars.Length; i++)
var type = TokenType.Undetermined;
var character = inputChars[i];
type = TokenType.ClosedParanthesis;
type = TokenType.Addition;
type = TokenType.Division;
type = TokenType.Multiplacation;
type = TokenType.Exponent;
type = TokenType.ClosedAbsolute;
if (type != TokenType.Undetermined)
tokens.Add(new Token(type, character + "", index));
if (character == '(' || character == '{')
tokens.Add(new Token(character == '(' ? TokenType.OpenParanthesis : TokenType.OpenAbsolute, character + "", index));
var lastToken = tokens.LastOrDefault();
if (lastToken.Type == TokenType.Number || lastToken.Type == TokenType.Variable)
tokens.Add(new Token(TokenType.Multiplacation, "*", index));
tokens.Add(new Token(character == '(' ? TokenType.OpenParanthesis : TokenType.OpenAbsolute, character + "", index));
tokens.Add(new Token(character == '(' ? TokenType.OpenParanthesis : TokenType.OpenAbsolute, character + "", index));
tokens.LastOrDefault().Type == TokenType.OpenParanthesis ||
tokens.LastOrDefault().Type == TokenType.OpenAbsolute)
tokens.Add(new Token(TokenType.Number, "-", index));
tokens.Add(new Token(TokenType.Subtraction, "-", index));
if (Int32.TryParse(character + "", out b) || character == '.')
if (AllowedVariables.Contains(character))
if (tokens.LastOrDefault().Type == TokenType.Number)
type = TokenType.Multiplacation;
tokens.Add(new Token(type, "*", index));
type = TokenType.Variable;
if (tokens.Count == 0 || type != tokens[tokens.Count - 1].Type || type == TokenType.Variable)
tokens.Add(new Token(type, character + "", index));
tokens[tokens.Count - 1].Value += character;
return new TokenList(tokens);
public class InvalidEquationExpressionException : Exception
public string Error { get; set; }
public InvalidEquationExpressionException(string error)
public List<Token> Tokens {get; set;}
public TokenList(List<Token> tokens)
public int CountType(TokenType type)
foreach (var t in Tokens)
public class BinaryTokenTree
public BinaryNode Root { get; set; }
public static BinaryTokenTree Parse(TokenList tokenList)
var hasEquals = tokenList.CountType(TokenType.Equals) == 1;
Root = new BinaryNode(null);
public BinaryNode Parent { get; set; }
public BinaryNode Left { get; set; }
public BinaryNode Right { get; set; }
if (Token.Type.IsOperand())
return NodeType.Operator;
public BinaryNode(BinaryNode parent, Token t)