Skip to content

Instantly share code, notes, and snippets.

@softwarespot
Last active September 28, 2015 10:02
Show Gist options
  • Save softwarespot/7f84975de9a3985b06ff to your computer and use it in GitHub Desktop.
Save softwarespot/7f84975de9a3985b06ff to your computer and use it in GitHub Desktop.
Infix to Postfix
// Based on the Shunting-Yard algorithm
function toPostfix(infix) {
// Convert a token to precedence value
const _precedenceValue = (token) => {
switch (token) {
case '+':
case '-':
return 4;
case '*':
case '/':
return 3;
case '^':
return 2;
case '(':
case ')':
return 1;
default:
return 0;
}
};
// Check if the first token has higher precedence than the second
const _hasHigherPrecedence = (token1, token2) => {
let value1 = _precedenceValue(token1);
let value2 = _precedenceValue(token2);
if (value1 === 0 && value2 === 0) {
return false;
}
return value1 <= value2;
};
// Stack to push results on to
const stack = [];
// Helper function: Peek at last stack item (Note: context of 'this' is set to the scope it resides in. Gotta love ES2015!)
const peek = () => {
return stack.length > 0 ? stack[stack.length - 1] : null;
};
// Helper function: Check if the stack is empty. (Note: context of 'this' is set to the scope it resides in. Gotta love ES2015!)
const empty = () => {
return stack.length === 0;
};
// Char buffer
const buffer = [];
// Add a trailing space to capture the last char
for (let token of infix + ' ') {
// Is an operand only, then push on to the buffer
if (/[0-9.]/.test(token)) {
buffer.push(token);
// Is an operator [ + - * / ^ ]
} else if (/[+\-*/\^]/.test(token)) {
// Whilst the stack is not empty, the stack token is not an open bracket and the stack token has higher precedence than
// the current token, pop off the stack and push on to the buffer
while (!empty() && peek() !== '(' && _hasHigherPrecedence(peek(), token)) {
buffer.push(stack.pop());
}
// Push the current token
stack.push(token);
} else if (token === '(') {
// Push the open bracket
stack.push(token);
} else if (token === ')') {
// Pop off everything on the stack up until the opening bracket
while (!empty() && peek() !== '(') {
buffer.push(stack.pop());
}
// Pop the last opening bracket
stack.pop();
}
}
// While operators are still on the stack, pop off the stack and push on to the buffer
while (!empty()) {
buffer.push(stack.pop());
}
// Create a new string out of the buffer
return buffer.join('');
}
// Example
console.log(toPostfix('2+(7*5)')); // 275*+
console.log(toPostfix('6^6+7-7*9')); // 66^7+79*-
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment