var input, current, index; var _OPERATOR = 1; var _NUMBER = 2; var _EOF = 3; function next() { var char, token = {}; while(index < input.length) { char = input.charAt(index++); switch(char) { case '+': case '-': case '*': case '/': case '(': case ')': token.operator = char; token.type = _OPERATOR; return token; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': token.value = char; token.type = _NUMBER; return token; default: throw "Unexpected character: " + c; } } token.type = _EOF; return token; } function peek() { if(!current) current = next(); return current; } function skip() { if(!current) current = next(); current = undefined; } function parseString(str) { input = str; index = 0; return tree(); } function tree() { return add(); } function add() { var left = multDivide(); var token = peek(); while(token.type == _OPERATOR && (token.operator == '+' || token.operator == '-') ) { skip(); var node = {}; node.operator = token.operator; node.left = left; node.right = multDivide(); left = node; token = peek(); } return left; } function multDivide() { var left = root(); var token = peek(); while(token.type == _OPERATOR && (token.operator == '*' || token.operator == '/') ) { skip(); var node = {}; node.operator = token.operator; node.left = left; node.right = root(); left = node; token = peek(); } return left; } function root() { var token = peek(); if(token.type == _NUMBER) { skip(); node = {}; node.value = token.value; return node; } }