Learn how to implement a string parser in JavaScript that solves basic mathematical expressions.

How to implement a basic mathematical expression calculator in JavaScript with MathCalc

The Good Ol' days in the School in Math class, where teachers didn't allow the usage of Calculators in the classroom. As a kid i was (and maybe still) very lazy, so the possibility to have an electronic device that could solve any mathematical operation (cheap advertising for Casio Calculators) was simply awesome. Now, although I don't use daily a Calculator, as a developer is interesting for me to see how other developers solve such problems. Now, in JavaScript the execution of mathematical operations with code is pretty simple, at least just for the programmer, but what if is the user the one that needs to execute some math operation? Today I want to share an useful code snippet namely MathCalc that allows you to use a very ellaborated function that solves basic mathematical expressions, from a simple string. Yeah, in the same way you did with a calculator, typing values and replacing the values in some formula.

1. Add MathCalc script

The MathCalc script has been written by @paiv and its basic idea is, although tricky to achieve, very simple to use and work with. The script parses a mathematical expression from a string, like an operation like: (1 + 2 + 3) / (2), which should return 2 as result.

The script is hosted in GithubHist, so you can get a copy of the MathCalc script:

Then include the script from the file in your HTML document using a script tag:

<!-- Include MathCalc -->
<script src="mathcalc.js"></script>

You can visit the homepage of the script that explains more possible use cases and so. The parser uses a shift-reduce parser implementation that is very efficient and has no dependencies. The library supports the following operators:

  • ( )
  • func(x) (call)
  • - (unary)
  • ^ (power, right associative)
  • * / %
  • + -
  • =
  • , (tuple constructor)

Numbers: 42.3, 1e-7

2. Using MathCalc script

MathCalc offers different features that are meant to be described and used as well. We are going to explain you all of them with examples:

Basic usage

The basic usage is to solve a simple mathematical operation from a string representation, in this case we are going to solve a simple addition and division shown in the variable expression, creating a new instance of the library allows you to use the parse method of it that expects the expression as first argument. The parser verifies if the syntax is correct, and you can execute an action in case it's not. If is correct, you can use the eval method to solve the expression and that's it:

// Create instance of MathCalc
var calc = new MathCalc();

// Your mathematical operation
var expression = '(1 + 2 + 3) / 3';

// Evaluate expression
var parser = calc.parse(expression);

// Check if there's a syntax error
if (parser.error) {
    console.error(
        'The expression "' + expression + '" has an error',
        expr.error.text 
    );

// Proceed to solve
}else {
    // The result will be a JS number, not a string
    var result = parser.eval();
    
    // Displays 2 as results (as expected) !
    console.log(
        'The expression "' + expression + '" generates:',
        result
    );
}

Note that the result of the eval method is a number, not a string and according to the operation, it may return NaN (not a number) as well.

Using variables

To use variables as a lot of math operations do, you can declare them in the parser as first argument inside an object. For example, our expression will be simple in this case x + y, where x will have a value of 1 and y of 2:

// Create instance of MathCalc
var calc = new MathCalc();

// Your mathematical operation
var expression = 'x + y';

// Evaluate result
var parser = calc.parse(expression);

// Check if there's a syntax error
if (parser.error) {
    console.error(
        'The expression "' + expression + '" has an error',
        expr.error.text 
    );

// Proceed to solve
}else {
    // The result will be a JS number, not a string
    // Insert the variables value
    var result = parser.eval({
        x: 1,
        y: 2
    });
    
    // Displays 3 as results (as expected) !
    console.log(
        'The expression "' + expression + '" generates:',
        result
    );
}

Creating custom math functions

Like the root square function works (sqrt(25) equal to 5), you can declare your own functions too. For example,

// Create instance of MathCalc
var calc = new MathCalc();

// Your mathematical operation
var expression = 'addNumbers(1 , 3)';

// Evaluate result
var parser = calc.parse(expression);

// Declare addNumbers function in the parser
parser.scope.addNumbers = function(a, b) { 
    return a + b; 
};

// Check if there's a syntax error
if (parser.error) {
    console.error(
        'The expression "' + expression + '" has an error',
        expr.error.text 
    );

// Proceed to solve
}else {
    // The result will be a JS number, not a string
    // Insert the variables value
    var result = parser.eval();
    
    // Displays 4 as results (as expected) !
    console.log(
        'The expression "' + expression + '" generates:',
        result
    );
}

Handle Runtime Errors

If the custom implemented function doesn't work as expected, you may don't know what happened without the properly handle process. Check if the scope has a runtimeError property to check if your custom functions triggered an error:

// Create instance of MathCalc
var calc = new MathCalc();

// Your mathematical operation
var expression = 'functionThatDoesnExist(1 , 3)';

// Evaluate result
var parser = calc.parse(expression);

// Check if there's a syntax error
if (parser.error) {
    console.error(
        'The expression "' + expression + '" has an error',
        expr.error.text 
    );

// Proceed to solve
}else {
    // The result will be a JS number, not a string
    // Insert the variables value
    var result = parser.eval();

    if (parser.scope.runtimeError) {
        alert('Runtime JS Error');
    }
    
    // Displays 4 as results (as expected) !
    console.log(
        'The expression "' + expression + '" generates:',
        result
    );
}

Live example

The following fiddle implements a very basic implementation of the script. The input, that acts as a screen where you can insert your expression and a button that calculates the result:

Happy coding !


Senior Software Engineer at Software Medico. Interested in programming since he was 14 years old, Carlos is a self-taught programmer and founder and author of most of the articles at Our Code World.

Sponsors