Home > Development > Simple Calculation Parser

Simple Calculation Parser


Doesnt support brackets yet. Ill add that later.

using System;
using System.Collections.Generic;
using System.IO;

namespace MathsCalcReader
{
    public class Program
    {
        static void Main()
        {
            Interpretor interpretor = new Interpretor("123 + 5 + 3 - 100");
            Console.WriteLine(interpretor.CalculateMathsExpression());
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
    }

    public class Interpretor
    {
        private readonly string _expression;
        private Queue<Token> _tokens;

        public Interpretor(string expression)
        {
            _expression = expression;
            _tokens = new Queue<Token>();
        }

        public int CalculateMathsExpression()
        {
            StringReader reader = new StringReader(_expression);

            while (reader.Peek() != -1)
            {
                char c = (char)reader.Read();
                if (Char.IsWhiteSpace(c)) continue;
                if (Char.IsDigit(c))
                {
                    AddDigits(reader, c);
                }
                else if (c == '+' || c == '-' || c == '/' || c == '*')
                {
                    AddOperator(c);
                }
            }

            return AccumulateTotal();
        }

        private int AccumulateTotal()
        {
            int total = 0;
            bool firstrun = true;

            while(_tokens.Count != 0)
            {
                if(firstrun)
                {
                    var op1 = _tokens.Dequeue();
                    var op = _tokens.Dequeue();
                    var op2 = _tokens.Dequeue();
                    total += op.Operator.Calc((int)op1.Value, (int)op2.Value);
                    firstrun = false;
                    continue;
                }
                var aop = _tokens.Dequeue();
                var aop2 = _tokens.Dequeue();
                total = aop.Operator.Calc(total, (int)aop2.Value);
            }
            return total;
        }

        private void AddDigits(StringReader reader, char c)
        {
            string temp = c.ToString();
            char p = (char)reader.Peek();
            if (Char.IsDigit(p))
            {
                p = (char)reader.Read();
                while (Char.IsDigit(p))
                {
                    temp += p;
                    p = (char)reader.Read();
                }
            }
            _tokens.Enqueue(new Token(Convert.ToInt32(temp)));
        }

        private void AddOperator(char c)
        {
            switch (c)
            {
                case '+':
                    _tokens.Enqueue(new Token(MathOperator.Addition));
                    break;
                case '-':
                    _tokens.Enqueue(new Token(MathOperator.Subtraction));
                    break;
                case '*':
                    _tokens.Enqueue(new Token(MathOperator.Multiplication));
                    break;
                case '/':
                    _tokens.Enqueue(new Token(MathOperator.Division));
                    break;
            }
        }
    }

    public class MathOperator
    {
        public Func<int, int, int> Calc;
        public char Value { get; private set; }
        public MathOperator(char value, Func<int,int,int> calc)
        {
            Calc = calc;
            Value = value;
        }

        public static MathOperator Addition = new MathOperator('+',(a,b) => a + b);
        public static MathOperator Subtraction = new MathOperator('-',(a,b) => a - b);
        public static MathOperator Multiplication = new MathOperator('*',(a,b) => a * b);
        public static MathOperator Division = new MathOperator('/', (a,b) => a / b);
    }

    public class Token
    {
        public int? Value { get; set; }
        public MathOperator Operator { get; set; }

        public Token(int value)
        {
            Value = value;
        }

        public Token(MathOperator op)
        {
            Operator = op;
        }
    }
}

Advertisements
  1. ben
    March 27, 2011 at 1:20 am

    that’s nice, i was just thinking i could use a new calculator, one that would let me reverse an operation (a stack).
    watch out for operator precedence! i think you gonna need a tree. Or go polish. Reverse Polish.

    • March 27, 2011 at 3:06 pm

      Thanks Ben 🙂

      Reverse Polish Notation In the Works 🙂

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: