Skip to content

Instantly share code, notes, and snippets.

@sanex3339
Last active October 20, 2015 06:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sanex3339/4bcb46c90ba859364038 to your computer and use it in GitHub Desktop.
Save sanex3339/4bcb46c90ba859364038 to your computer and use it in GitHub Desktop.
var StringExpressionParser = function () {
this.operators = [
'+', '-', '*', '/', '^'
];
this.priorities = [
['*', '/'],
['+', '-']
];
};
StringExpressionParser.prototype.parse = function (expression) {
return this.toInfixNotation(expression);
}
StringExpressionParser.prototype.toInfixNotation = function (expression) {
var output = [],
stack = [];
expression = expression
.trim()
.replace(/\,/g, '.')
.replace(/x/g, '*')
.replace(/([[0-9]*(?:\.?[0-9]+)*|[\(|\)])/g, ' $1 ')
.split(' ')
.filter(Boolean);
for (var i = 0; i < expression.length; i++) {
if (/[0-9]/.test(expression[i])) {
output.push(expression[i]);
continue;
}
if (this.operators.indexOf(expression[i]) !== -1) {
while (stack.length > 0 && this.checkPreorities(expression[i], stack[stack.length-1])) {
output.push(stack.pop());
}
stack.push(expression[i]);
continue;
}
if (expression[i] === '(') {
stack.push(expression[i]);
continue;
}
if (expression[i] === ')') {
while (stack[stack.length - 1] !== '(') {
output.push(stack.pop());
}
stack.pop();
continue;
}
}
while (stack.length > 0) {
output.push(stack.pop());
}
return this.toPostfix(output).join('');
};
StringExpressionParser.prototype.toPostfix = function (expression) {
var output = [];
for (var i = 0; i < expression.length; i++) {
if (/[0-9]/.test(expression[i])) {
output.push(parseFloat(expression[i]));
continue;
}
if (this.operators.indexOf(expression[i]) !== -1) {
var result = this.calculate(output[output.length - 2], output[output.length - 1], expression[i]);
output = output.slice(0, -2);
output.push(result)
continue;
}
}
return output;
}
StringExpressionParser.prototype.checkPreorities = function (operator1, operator2) {
for (var i = 0; i < this.priorities.length; i++) {
if (
(
this.priorities[i].indexOf(operator1) !== -1 &&
this.priorities[i].indexOf(operator2) !== -1
) ||
(
this.priorities[i].indexOf(operator2) !== -1 &&
this.priorities[i + 1] !== undefined &&
this.priorities[i + 1].indexOf(operator1) !== -1
)
) {
return true;
}
}
return false;
}
StringExpressionParser.prototype.calculate = function (a, b, operator) {
switch (operator) {
case '+':
return a + b;
case '-':
return a - b;
case '*':
return a * b;
case '/':
return a / b;
case '^':
return Math.pow(a, b);
}
}
var stringParser = new StringExpressionParser();
console.log(stringParser.parse('3+4*2/(1-5)^2'));
console.log(stringParser.parse('5+((1+2)*4)-3'));
console.log(stringParser.parse('(100/20+5)-(10/2)*5+((20*2)-(20/4))'));
console.log(stringParser.parse('1.5*2+4'));
console.log(stringParser.parse('5,5 + 2'));
console.log(stringParser.parse('.5 + 2'));
console.log(stringParser.parse('5x2'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment