Simple calculator application, written in Go.
Supports basic BODMAS
operations.
Example usage:
func main() {
c := calculator.New()
res, err := c.Eval("5+5")
fmt.Println(res, err) // 10, <nil>
}
Handling error cases:
func main() {
c := calculator.New()
res, err := c.Eval("?5+5")
fmt.Println(res, err) // 0, unknown character '?'
if e, ok := err.(lexer.UnknownSymbolError); ok {
fmt.Printf("cannot use %q symbol\n", e.Symbol)
}
}
func main() {
c := calculator.New()
input := "5+*5"
res, err := c.Eval(input)
fmt.Println(res, err) // 0, cannot have 2 operators side by side in position (2, 3)
if evalErr, ok := err.(calculator.EvalError); ok {
// show invalid char with 1 preceding and succeeding characters
from := max(0, evalErr.StartPos-1)
to := min(len(input), evalErr.EndPos+1)
invalidPart := input[from:to]
fmt.Printf("%v; %q", evalErr.Err, invalidPart) // cannot have 2 operators side by side; "+*5"
}
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
It goes through multiple steps to calculate the input expression.
-
First step is
lexical analysis
of the given input, and converting it into a slice of Token. You can think of a Token as akeyword
, or a character that has a meaning. It can also hold any value related to itself. In the context of this application, some of the Tokens are :- NUM
- ADD
- SUB
- MUL
- DIV
- POW
- L_PAR
- R_PAR
As an example, expression "1+2" after lexical analysis produces:
[Token(NUM, 1), Token(ADD), Token(NUM, 2)]
-
Second step is validating the tokenized input find and report errors and error positions. For example:
"(*4" -> [LEFT_PAR, MUL, NUM]
is an invalid expression. The position(index) where it starts being invalid is 1(MUL), and ends at 2, because we cannot have Multiplication after the opening-paracantesis. Here, we report the Error(ErrOperationAfterLeftParacantesis
), the start and endposition, so that we can show the incorrect part to the end-user. -
Parsing the Tokens, and building the Expression Tree. The way we build the expression tree is parsing the Tokens from
Infix notation
toPostfix
and then,Postfix
toExpression Tree
. Here in this application, this steps happen at the same time. You can learn more aboutInfix to Postfix
from this video. You can read this geeksforgeeks article on Program to convert Infix notation to Expression Tree to get learn more about the algorithm. -
Evaluating the Expression tree
recursively
and getting the result.