Created
April 3, 2025 05:49
-
-
Save rndme/621e3ec29dea1b73a96d50b682684661 to your computer and use it in GitHub Desktop.
simple parser stack: tokenizer, ast builder, and evaluator for basic arithmetic expressions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function tokenize(s) { // OPS TERMS | |
return s.match(/([+*\-\/])|([\d\.]+)/g).map(function Token(t, i) { | |
return { | |
token: t, | |
type: isFinite(t) ? "num" : "op", | |
index: i, | |
value: isFinite(t) ? +t : "-+*\/".indexOf(t), // data value/op priority | |
}; | |
}); | |
}//end tokenize() | |
function AST(tokens){ | |
var sortedOps = tokens.filter(x=>x.type=='op').sort((a,b)=>b.value-a.value); | |
return sortedOps.map(function group(op){ | |
var buff = [op, tokens[op.index-1], tokens[op.index+1]]; | |
tokens[op.index-1] = null; | |
tokens[op.index+1] = null; | |
return buff; | |
}); | |
}//end AST() | |
function solve(ast){ | |
return ast.map(function expr2value(eq, i, whole){ | |
let a = eq[1] ? eq[1].value : whole[i-1], | |
b = eq[2] ? eq[2].value : whole[i-1]; | |
switch(eq[0].token){ // clobber eq with a mock result token: | |
case "*": return ast[i]= a * b; | |
case "/": return ast[i]= a / b; | |
case "+": return ast[i]= a + b; | |
case "-": return ast[i]= a - b; | |
} | |
}).pop(); // return final result | |
} // end solve() | |
solve(AST(tokenize("5 + 12 * 34 - 12"))); // == 401 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment