Postfix Calculator in Scala

Element.scala

package calculator

trait Element {

}

NumberElement.scala

package calculator

class NumberElement(numberArg: String) extends Element {
  var number: Double = numberArg.toDouble
  
  def getNumber = number
  
  override def toString() : String = {
    return number.toString()
  }
}

OperatorElement.scala

package calculator

sealed trait OperatorType
case object MULTIPLY extends OperatorType
case object DIVIDE extends OperatorType
case object ADD extends OperatorType
case object SUBTRACT extends OperatorType
case object EXPONENTIAL extends OperatorType
case object OPAREN extends OperatorType
case object CPAREN extends OperatorType
case object NULL extends OperatorType
  
class OperatorElement(operator: Character) extends Element {
  var type1 : OperatorType = NULL
  
  var c : Character = operator
  
  if(operator == '+')
    type1 = ADD
  else if(operator == '-')
    type1 = SUBTRACT
  else if(operator == '*')
    type1 = MULTIPLY
  else if(operator == '/')
    type1 = DIVIDE
  else if(operator == '^')
    type1 = EXPONENTIAL
  else if(operator == '(')
    type1 = OPAREN
  else if(operator == ')')
    type1 = CPAREN
    
  override def toString() : String = {
    return c.toString()
  }
}

Parser.scala

package calculator

import scala.collection.mutable.ArrayBuffer

class Parser {
  def Parse(s: String) : ArrayBuffer[Element] = 
  {
    var e = new ArrayBuffer[Element]()
    var sb = new StringBuilder()
    var i = 0
    for(i <- 0 until s.length()) 
    {
      var c = s.charAt(i)
      if(Character.isDigit(c))
        sb.append(c)
      if(i + 1 < s.length())
      {
        var d = s.charAt(i + 1)
        if(Character.isDigit(d) == false && sb.length() > 0)
        {
          e.append(new NumberElement(sb.toString()))
          sb.clear()
          
        }
      }
      
      if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '(' || c == ')')
        e.append(new OperatorElement(c));
    }
    
    if(sb.length() > 0)
      e.append(new NumberElement(sb.toString()));
    
    return e
  }
}

InfixToPostfix.scala

package calculator

import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Stack
import util.control.Breaks._

class InfixToPostfix {
  private var converted: ArrayBuffer[Element] = new ArrayBuffer[Element]

  def Precedence(c: OperatorElement) : Int = 
  {
    if(c.type1 == EXPONENTIAL)
    {
      return 2
    }
    else if(c.type1 == MULTIPLY || c.type1 == DIVIDE)
    {
      return 3
    }
    else if(c.type1 == ADD || c.type1 == SUBTRACT)
    {
      return 4
    }
    else
      return Int.MaxValue  
  }
  
  def ProcessOperators(st: Stack[Element], element: Element, top: Element)
  {
    var top1 = top;
    breakable
    {
	  while(st.size > 0 && Precedence(element.asInstanceOf[OperatorElement]) >= Precedence(top1.asInstanceOf[OperatorElement]))
	  {
	    var p = st.pop()
	    if(p.asInstanceOf[OperatorElement].type1 == OPAREN)
	      break
	    converted.append(p)
	    if(st.size > 0)
	      top1 = st.top
	  }
    }
  }
  
  def ConvertFromInfixToPostFix(e: ArrayBuffer[Element]) : ArrayBuffer[Element] = 
  {
    var stack1: ArrayBuffer[Element] = new ArrayBuffer[Element]()
    e.copyToBuffer(stack1)
    var st: Stack[Element] = new Stack[Element]()
    
    var i: Int = 0
    for(i <- 0 until stack1.length)
    {
      var element = stack1(i)
      if(element.isInstanceOf[OperatorElement])
      {
        if(st.isEmpty || element.asInstanceOf[OperatorElement].type1 == OPAREN)
          st.push(element);
        else
        {
          var top = st.top;
	      if(element.asInstanceOf[OperatorElement].type1 == CPAREN)
	          ProcessOperators(st, element, top);
	      else if(Precedence(element.asInstanceOf[OperatorElement]) < Precedence(top.asInstanceOf[OperatorElement]))
	          st.push(element);
	      else
	      {
	          ProcessOperators(st, element, top);
	          st.push(element);
	      }
        }
      }
      else
        converted.append(element);
    }
    
    while(st.size > 0)
    {
        var b1 = st.pop()
        converted.append(b1)
    } 
    return converted
  }
  
  override def toString(): String =
  {
    var sb: StringBuffer = new StringBuffer()
    converted.foreach(f => sb.append(f + " "))
    return sb.toString()
  }
}

PostFixEvaluator.scala

package calculator

import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Stack

class PostFixEvaluator {
  def calculate(left: NumberElement, right: NumberElement, op: OperatorElement): NumberElement = 
  {
    var temp = Double.MaxValue
    if(op.type1 == ADD)
    {
      temp = left.getNumber + right.getNumber
    }
    else if(op.type1 == SUBTRACT)
    {
      temp = left.getNumber - right.getNumber
    }
    else if(op.type1 == MULTIPLY)
    {
      temp = left.getNumber * right.getNumber
    }
    else if(op.type1 == DIVIDE)
    {
      temp = left.getNumber / right.getNumber
    }
    else if(op.type1 == EXPONENTIAL)
    {
      temp = Math.pow(left.getNumber, right.getNumber)
    }
    
    return new NumberElement(temp.toString)
  }
  
  def Evaluate(e: ArrayBuffer[Element]): Double = 
  {
    var stack: Stack[Element] = new Stack[Element]
    var v: ArrayBuffer[Element] = new ArrayBuffer[Element]
    e.copyToBuffer(v)
    
    var i: Int = 0
    for(i <- 0 until v.length)
    {
      var element = v(i)
      if(element.isInstanceOf[NumberElement])
        stack.push(element)
      if(element.isInstanceOf[OperatorElement])
      {
        var right = stack.pop()
        var left = stack.pop()
        var result = calculate(left.asInstanceOf[NumberElement], right.asInstanceOf[NumberElement], element.asInstanceOf[OperatorElement])
        stack.push(result)
      }
    }
    return stack.pop().asInstanceOf[NumberElement].getNumber
  }
}

Calculator.scala

package calculator

object Calculator {
  def main(args: Array[String]): Unit = {
    val t = "4+6+9*8-(5*6+9)^2"
    val p = new Parser()
    var e = p.Parse(t)
    var i = new InfixToPostfix()
    e = i.ConvertFromInfixToPostFix(e)
    println(i)
    var pfe = new PostFixEvaluator();
    var result = pfe.Evaluate(e);
    println(result)
  }
}

Postfix Calculator in C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace calculator
{
    public enum OperatorType { MULTIPLY, DIVIDE, ADD, SUBTRACT, EXPONENTIAL, OPAREN, CPAREN };
    public interface Element
    {
    }

    public class NumberElement : Element
    {
        double number;
        public Double getNumber()
        {
            return number;
        }

        public NumberElement(String number)
        {
            this.number = Double.Parse(number);
        }

        public override String ToString()
        {
            return ((int)number).ToString();
        }
    }

    public class OperatorElement : Element
    {
        public OperatorType type;
        char c;
        public OperatorElement(char op)
        {
            c = op;
            if (op == '+')
                type = OperatorType.ADD;
            else if (op == '-')
                type = OperatorType.SUBTRACT;
            else if (op == '*')
                type = OperatorType.MULTIPLY;
            else if (op == '/')
                type = OperatorType.DIVIDE;
            else if (op == '^')
                type = OperatorType.EXPONENTIAL;
            else if (op == '(')
                type = OperatorType.OPAREN;
            else if (op == ')')
                type = OperatorType.CPAREN;
        }

        public override String ToString()
        {
            return c.ToString();
        }
    }

    public class Parser
    {
        List<Element> e = new List<Element>();
        public List<Element> Parse(String s)
        {
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < s.Length; i++)
            {
                char c = s[i];
                if (Char.IsDigit(c))
                    sb.Append(c);
                if (i + 1 < s.Length)
                {
                    char d = s[i + 1];
                    if (Char.IsDigit(d) == false && sb.Length > 0)
                    {
                        e.Add(new NumberElement(sb.ToString()));
                        //clears stringbuilder
                        sb.Remove(0, sb.Length);
                    }
                }

                if (c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
                        || c == '(' || c == ')')
                    e.Add(new OperatorElement(c));
            }
            if (sb.Length > 0)
                e.Add(new NumberElement(sb.ToString()));

            return e;
        }
    }


    public class InfixToPostfix
    {
        List<Element> converted = new List<Element>();
        int Precedence(OperatorElement c)
        {
            if (c.type == OperatorType.EXPONENTIAL)
                return 2;
            else if (c.type == OperatorType.MULTIPLY || c.type == OperatorType.DIVIDE)
                return 3;
            else if (c.type == OperatorType.ADD || c.type == OperatorType.SUBTRACT)
                return 4;
            else
                return Int32.MaxValue;
        }

        public void ProcessOperators(Stack<Element> st, Element element, Element top)
        {
            while (st.Count > 0 && Precedence((OperatorElement)element) >= Precedence((OperatorElement)top))
            {
                Element p = st.Pop();
                if (((OperatorElement)p).type == OperatorType.OPAREN)
                    break;
                converted.Add(p);
                if (st.Count > 0)
                    top = st.First();
            }
        }
        public List<Element> ConvertFromInfixToPostFix(List<Element> e)
        {
            List<Element> stack1 = new List<Element>(e);
            Stack<Element> st = new Stack<Element>();
            for (int i = 0; i < stack1.Count; i++)
            {
                Element element = stack1[i];
                if (element.GetType().Equals(typeof(OperatorElement)))
                {
                    if (st.Count == 0 ||
                            ((OperatorElement)element).type == OperatorType.OPAREN)
                        st.Push(element);
                    else
                    {
                        Element top = st.First();
                        if (((OperatorElement)element).type == OperatorType.CPAREN)
                            ProcessOperators(st, element, top);
                        else if (Precedence((OperatorElement)element) < Precedence((OperatorElement)top))
                            st.Push(element);
                        else
                        {
                            ProcessOperators(st, element, top);
                            st.Push(element);
                        }
                    }
                }
                else
                    converted.Add(element);
            }

            //pop all operators in stack
            while (st.Count > 0)
            {
                Element b1 = st.Pop();
                converted.Add(b1);
            }

            return converted;
        }

        public override String ToString()
        {
            StringBuilder s = new StringBuilder();
            for (int j = 0; j < converted.Count; j++)
                s.Append(converted[j].ToString() + " ");
            return s.ToString();
        }
    }

    public class PostFixEvaluator
    {
        Stack<Element> stack = new Stack<Element>();

        NumberElement calculate(NumberElement left, NumberElement right, OperatorElement op)
        {
            Double temp = Double.MaxValue;
            if (op.type == OperatorType.ADD)
                temp = left.getNumber() + right.getNumber();
            else if (op.type == OperatorType.SUBTRACT)
                temp = left.getNumber() - right.getNumber();
            else if (op.type == OperatorType.MULTIPLY)
                temp = left.getNumber() * right.getNumber();
            else if (op.type == OperatorType.DIVIDE)
                temp = left.getNumber() / right.getNumber();
            else if (op.type == OperatorType.EXPONENTIAL)
                temp = Math.Pow(left.getNumber(), right.getNumber());

            return new NumberElement(temp.ToString());
        }
        public Double Evaluate(List<Element> e)
        {
            List<Element> v = new List<Element>(e);
            for (int i = 0; i < v.Count; i++)
            {
                Element element = v[i];
                if (element.GetType().Equals(typeof(NumberElement)))
                    stack.Push(element);
                if (element.GetType().Equals(typeof(OperatorElement)))
                {
                    NumberElement right = (NumberElement)stack.Pop();
                    NumberElement left = (NumberElement)stack.Pop();
                    NumberElement result = calculate(left, right, (OperatorElement)element);
                    stack.Push(result);
                }
            }
            return ((NumberElement)stack.Pop()).getNumber();
        }
    }

    class Program
    {
        public double Calculate(String s)
        {
            Parser p = new Parser();
            List<Element> e = p.Parse(s);
            InfixToPostfix i = new InfixToPostfix();
            e = i.ConvertFromInfixToPostFix(e);

            PostFixEvaluator pfe = new PostFixEvaluator();
            return pfe.Evaluate(e);
        }

        static void Main(string[] args)
        {
            Program c = new Program();
	        double d = c.Calculate("4+6+9*8-(5*6+9)^2");
            Console.WriteLine(d);
        }
    }
}

Postfix Calculator in Java

Element.java

package com.tutorial;

public interface Element {
}

NumberElement.java

package com.tutorial;

public class NumberElement implements Element {
	Double number;
	public Double getNumber() {
		return number;
	}

	public NumberElement(String number) {
		this.number = Double.parseDouble(number);
	}
	
	public String toString()
	{
		return ((Integer)number.intValue()).toString();
	}
}

OperatorElement.java

package com.tutorial;

public class OperatorElement implements Element{
	static public enum OperatorType {MULTIPLY, DIVIDE, ADD, SUBTRACT, EXPONENTIAL, OPAREN, CPAREN};
	OperatorType type;
	Character c;
	public OperatorElement(Character operator) {
		c = operator;
		if(operator == '+')
			type = OperatorType.ADD;
		else if(operator == '-')
			type = OperatorType.SUBTRACT;
		else if(operator == '*')
			type = OperatorType.MULTIPLY;
		else if(operator == '/')
			type = OperatorType.DIVIDE;
		else if(operator == '^')
			type = OperatorType.EXPONENTIAL;
		else if(operator == '(')
			type = OperatorType.OPAREN;
		else if(operator == ')')
			type = OperatorType.CPAREN;
	}
	
	public String toString()
	{
		return c.toString();
	}
}

Parser.java

package com.tutorial;

import java.util.Collection;
import java.util.Vector;

public class Parser {
	Vector <Element> e = new Vector<Element>();
	public Collection<Element> Parse(String s)
	{
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < s.length(); i++)
		{
			Character c = s.charAt(i);
			if(Character.isDigit(c))
				sb.append(c);
			if(i + 1 < s.length())
			{
				Character d = s.charAt(i + 1);
				if(Character.isDigit(d) == false && sb.length() > 0)
				{
					e.add(new NumberElement(sb.toString()));
					//clears stringbuilder
					sb.delete(0, sb.length());
				}
			}
			
			if(c == '+' || c == '-' || c == '*' || c == '/' || c == '^'
					|| c == '(' || c == ')')
				e.add(new OperatorElement(c));
		}
		if(sb.length() > 0)
			e.add(new NumberElement(sb.toString()));
		
		return e;
	}
}

InfixToPostfix.java

package com.tutorial;

import java.util.Collection;
import java.util.Stack;
import java.util.Vector;

import com.tutorial.OperatorElement.OperatorType;

public class InfixToPostfix {
	Vector <Element> converted = new Vector<Element>();
	int Precedence(OperatorElement c)
	{
		if(c.type == OperatorType.EXPONENTIAL)
			return 2;
		else if(c.type == OperatorType.MULTIPLY || c.type == OperatorType.DIVIDE)
			return 3;
		else if(c.type == OperatorType.ADD || c.type == OperatorType.SUBTRACT)
			return 4;
		else
			return Integer.MAX_VALUE;
	}
	
	public void ProcessOperators(Stack<Element> st, Element element, Element top)
	{
		while(st.size() > 0 && Precedence((OperatorElement)element) >= Precedence((OperatorElement)top))
		{
			Element p = st.pop();
			if(((OperatorElement)p).type == OperatorType.OPAREN)
				break;
			converted.add(p);
			if(st.size() > 0)
				top = st.lastElement();
		}
	}
	public Collection<Element> ConvertFromInfixToPostFix(Collection<Element> e)
	{
		Vector <Element> stack1 = new Vector<Element>(e);
		Stack<Element> st = new Stack<Element>();
		for(int i = 0; i < stack1.size(); i++)
		{
			Element element = stack1.elementAt(i);
			if(element instanceof OperatorElement)
			{
				if(st.empty() ||
						((OperatorElement)element).type == OperatorType.OPAREN)
					st.push(element);
				else
				{
					Element top = st.lastElement();
					if(((OperatorElement)element).type == OperatorType.CPAREN)
						ProcessOperators(st, element, top);
					else if(Precedence((OperatorElement)element) < Precedence((OperatorElement)top))
						st.push(element);
					else
					{
						ProcessOperators(st, element, top);
						st.push(element);
					}
				}
			}
			else
				converted.add(element);
		}
		
		//pop all operators in stack
		while(st.size() > 0)
		{
			Element b1 = st.pop();
			converted.add(b1);
		}
		
		return converted;
	}
	
	public String toString()
	{
		StringBuilder s = new StringBuilder();
		for(int j = 0; j < converted.size(); j++)
			s.append(converted.elementAt(j) + " ");
		return s.toString();
	}
}

PostFixEvaluator.java

package com.tutorial;

import java.util.Collection;
import java.util.Stack;
import java.util.Vector;

import com.tutorial.OperatorElement.OperatorType;

public class PostFixEvaluator {
	Stack<Element> stack = new Stack<Element>();
	
	NumberElement calculate(NumberElement left, NumberElement right, OperatorElement op)
	{
		Double temp = Double.MAX_VALUE;
		if(op.type == OperatorType.ADD)
			temp = left.getNumber() + right.getNumber();
		else if(op.type == OperatorType.SUBTRACT)
			temp = left.getNumber() - right.getNumber();
		else if(op.type == OperatorType.MULTIPLY)
			temp = left.getNumber() * right.getNumber();
		else if(op.type == OperatorType.DIVIDE)
			temp = left.getNumber() / right.getNumber();
		else if(op.type == OperatorType.EXPONENTIAL)
			temp = Math.pow(left.getNumber(), right.getNumber());
		
		return new NumberElement(temp.toString());
	}
	public Double Evaluate(Collection<Element> e)
	{
		Vector <Element> v = new Vector<Element>(e);
		for(int i = 0; i < v.size(); i++)
		{
			Element element = v.elementAt(i);
			if(element instanceof NumberElement)
				stack.push(element);
			if(element instanceof OperatorElement)
			{
				NumberElement right = (NumberElement) stack.pop();
				NumberElement left = (NumberElement) stack.pop();
				NumberElement result = calculate(left, right, (OperatorElement)element);
				stack.push(result);
			}
		}
		return ((NumberElement)stack.pop()).getNumber();
	}
}

CalculatorTest.java

package com.tutorial;

import java.util.Collection;

public class CalculatorTest {

	public double Calculate(String s)
	{
		Parser p = new Parser();
		Collection<Element> e = p.Parse(s);
		InfixToPostfix i = new InfixToPostfix();
		e = i.ConvertFromInfixToPostFix(e);
		
		//debugging
		System.out.println("DEBUGGING: " + i.toString());
		//
		
		PostFixEvaluator pfe = new PostFixEvaluator();
		return pfe.Evaluate(e);
	}
	
	public static void main(String[] args) {
		CalculatorTest c = new CalculatorTest();
		double d = c.Calculate("4+6+9*8-(5*6+9)^2");
		System.out.println(d);
	}
}

CSV Parser (using State Machine) in Java

import java.util.ArrayList;

public class CSVParser {

	public enum OPstates
	{
		INITIAL(0),
		NORMAL(1),
		COMMA(2),
		OPEN_QUOTATION(9),
		CLOSE_QUOTATION(4),
		WHITE_SPACE(5),
		QUOTATION_IN_TOKEN(6),
		CLOSE_QUOTATION_IN_TOKEN(8),
		ERROR(-1),
		NEW_LINE(200);

		int i;
		private OPstates(int i) {
			this.i = i;
		}

		public int getValue()
		{
			return i;
		}
	}
	int [][] state = {	{1, 2, 3, 200, 5},      //0 initial state
						{1, 2, -1, 200, 1},     //1 normal character state
						{1, 2, 3, 200, 5},      //2 comma state
						{9, 9, 4, -1, 9},       //3 open quotation
						{-1, 2, 6, 200, 5},     //4 close quotation or quotation in token state
						{1, 2, 3, 200, 5},      //5 whitespace state
						{6, 6, 7, 200, 6},      //6 quotation in token
						{-1, -1, 8, -1, -1},    //7 close quotation
						{9, -1, 4, 200, 9},     //8 close quotation
						{9, 9, 4, -1, 9}        //9 open quotation state
					 };

	ArrayList<String> tokens = new ArrayList<String>();
	int TokenState(char token)
	{
		if(token == ',')
			return 1;
		else if(token == '"')
			return 2;
		else if(token == '\n')
			return 3;
		else if(token == ' ')
			return 4;
		else
			return 0;
	}

	void Parse(String input)
	{
		int curState = 0;
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i < input.length(); i++)
		{
			char tokenChar = input.charAt(i);
			int tokenState = TokenState(tokenChar);
			curState = state[curState][tokenState];
			if(curState == OPstates.NORMAL.getValue() ||
					curState == OPstates.OPEN_QUOTATION.getValue() ||
					curState == OPstates.QUOTATION_IN_TOKEN.getValue() ||
					curState == OPstates.CLOSE_QUOTATION_IN_TOKEN.getValue())
				sb.append(tokenChar);

			if(curState == OPstates.COMMA.getValue() ||
					curState == OPstates.NEW_LINE.getValue())
			{
				tokens.add(sb.toString().trim());
				sb.delete(0, sb.length());

				if(curState == OPstates.NEW_LINE.getValue())
					break;
			}

			if(curState == OPstates.ERROR.getValue())
				throw new RuntimeException("Parse Error");
		}
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();

		for(int i = 0; i < tokens.size(); i++)
			sb.append("Token: " + tokens.get(i) + "\n");

		return sb.toString().trim() + "\n";
	}

	public CSVParser(String input) {
		Parse(input);
	}

	public static void main(String[] args) {
		String s = "   \"a\" ,    \"b,cd\"      ,   c ,\"vb,  n\",\",\"\n";
		System.out.println(s + new CSVParser(s));

		s = "    ,   a,b,\"c, l\",d,,5\n";
		System.out.println(s + new CSVParser(s));

		s = "h,\"john, jr\",a,b,\"c, l\",d,,5,\"e, jr\"\n";
		System.out.println(s + new CSVParser(s));

		s = "\"h, jk\",\"john, jr\",a,b,\"c, l\",d,,5,\"e's, jr\"\n";
		System.out.println(s + new CSVParser(s));

		s = "\"  e   \"\"abc\"\" n \"\"def\"\" \"\"buddy\"\"d\",\"b, jr\",  c dj n\n";
		System.out.println(s + new CSVParser(s));
	}
}