*This article is dedicated to my love Aida.*

## Introduction

This article describes a practical mathematical parser - an interactive program that can be used to perform basic arithmetic operations. In fact, in order to keep understanding of this article simple, I prefer to avoid any unnecessary items so you cannot rely on this program as a real calculator and it just works with integers and it can parse an expression with + , - , * , / , ( , ).

When I first started thinking about writing code to calculate a mathematical expression, I soon realized that it wasn't that easy [at least for me]. I had to delve into such concepts as parsing, tokens, lexical analysis, node trees and tables, etc.

The rules of the algorithm were the same ```
```

ones we learned in algebra. For example: multiply (or divide) before adding or subtracting; start with inner parentheses and work outwards; if a pair of binary operators have equal precedence, perform the left operator of the pair first.

Here is its screen shot:

## Using the Code

The idea of this calculator or better to say math parser is think in tree and node way. I think the following picture can explain the whole idea:

a+b*c*(d-e)

You can see the algorithm of multiplying (or dividing) before adding or subtracting; starting with inner parentheses and working outwards; if a pair of binary operators have equal precedence, performing the left operator of the pair first.

At first, I made `ParseExpr()`

function. This function + or - two operands with each other but before that checks if there is any * or / after each operand or not so it calls `ParseFactor() `

function which is made to * or / two operands. Of course it checks if there is any expression in a pair of parenthesis or not, so it calls `ParseTerm()`

function to check those expressions between braces, then at this point it reaches the value so we should parse it so then it calls `ParseNumber()`

.

For example above at first it calls `ParseExpr(Expression) -> ParseFactor(Expression) -> ParseTerm(Expression) -> ParseNumber(Expression)`

and it returns `a `

and then it cuts the Expression to `+b*c*(d-e)`

so the returned value from `ParseNumber `

goes to `op `

and then it checks the first character to see if it is plus and there it is, so it cuts the Expression to `b*c*(d-e)`

and then it repeats the last actions and makes up the above tree.

Blocks of code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace csharpcalc
{
class Expression
{
public int ParseExpr(ref string expr)
{
int op , op1;
op = ParseFactor(ref expr);
if (expr.Length != 0 )
{
if (expr[0] == '+')
{
expr = expr.Substring(1, expr.Length - 1);
op1 = ParseExpr(ref expr);
op += op1;
}
else if (expr[0] == '-')
{
expr = expr.Substring(1, expr.Length - 1);
op1 = ParseExpr(ref expr);
op -= op1;
}
}
return op;
}
public int ParseFactor(ref string expr)
{
int op, op1;
op = ParseTerm(ref expr);
if (expr.Length != 0)
{
if (expr[0] == '*')
{
expr = expr.Substring(1, expr.Length - 1);
op1 = ParseFactor(ref expr);
op *= op1;
}
else if (expr[0] == '/')
{
expr = expr.Substring(1, expr.Length - 1);
op1 = ParseFactor(ref expr);
op /= op1;
}
}
return op;
}
public int ParseTerm(ref string expr)
{
int returnValue = 0;
if (expr.Length != 0)
{
if (char.IsDigit(expr[0]))
{
returnValue = ParseNumber(ref expr);
return returnValue;
}
else if (expr[0] == '(')
{
expr = expr.Substring(1, expr.Length - 1);
returnValue = ParseExpr(ref expr);
return returnValue;
}
else if (expr[0] == ')')
expr = expr.Substring(1, expr.Length - 1);
}
return returnValue;
}
public int ParseNumber(ref string expr)
{
string numberTemp = "";
for (int i = 0; i < expr.Length && char.IsDigit(expr[i]); i++)
{
if (char.IsDigit(expr[0]))
{
numberTemp += expr[0];
expr = expr.Substring(1, expr.Length - 1);
}
}
return int.Parse(numberTemp);
}
}
}

## If You Want To ...

If you want to complete this project in order to accept double numbers too, you can add `if`

-block in `ParseNumber()`

method that even if `char.IsDigit() `

was `false`

, check if it is "`.`

" and if it is so, add it to the `numberTemp `

and then cast it.

If you want to add some other mathematical functions to this project such as `sin()`

, `cos()`

, etc., you can check the first `char `

of Expression in the `ParseTerm `

function to see if it is a letter or not (`char.IsLetter`

) and then call a function like `ParseWord()`

and thereafter splitting the word, you can use a `switch case`

block.

## Points of Interest

I am a Control Engineer, but I have always loved computer programming and this simple project brings life to my past dreams.

## History

Since I was a 16 year old student, I had a dream of writing a math parser but I have always had some other work to do. Finally I decided to write that. After searching the literature, I came across an outline of an algorithm for parsing arithmetic expressions in Principles of Systems Programming by Robert M. Graham (Wiley, 1975).