JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://gist.github.com/aaditmshah/6683499/raw/875c795ec9160e095a4030e82d5a6e3416d9fdc7/shunt.js"></script>
<script src="https://raw.github.com/aaditmshah/lexer/master/lexer.js"></script>
JavaScript
var lexer = new Lexer;
lexer.addRule(/\s+/, function () {
/* skip whitespace */
});
lexer.addRule(/[a-z]/, function (lexeme) {
return lexeme; // symbols
});
lexer.addRule(/[\(\+\-\*\/\)]/, function (lexeme) {
return lexeme; // punctuation (i.e. "(", "+", "-", "*", "/", ")")
});
var factor = {
precedence: 2,
associativity: "left"
};
var term = {
precedence: 1,
associativity: "left"
};
var parser = new Parser({
"+": term,
"-": term,
"*": factor,
"/": factor
});
function parse(input) {
lexer.setInput(input);
var tokens = [], token;
while (token = lexer.lex()) tokens.push(token);
return parser.parse(tokens);
}
var stack = [];
var context = {
"a": 1,
"b": 2,
"c": 3,
"d": 4,
"e": 5
};
var operator = {
"+": function (a, b) { return a + b; },
"-": function (a, b) { return a - b; },
"*": function (a, b) { return a * b; },
"/": function (a, b) { return a / b; }
};
parse("e*((a*(b+c))+d)").forEach(function (c) {
switch (c) {
case "+":
case "-":
case "*":
case "/":
var b =+ stack.pop();
var a =+ stack.pop();
stack.push(operator[c](a, b));
break;
default:
stack.push(context[c]);
}
});
var output = stack.pop();
alert(output);