Created
February 7, 2013 02:55
-
-
Save uiur/4728033 to your computer and use it in GitHub Desktop.
電卓パーサ
This file contains hidden or 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(expose){ | |
| expose.execute = function (source) { | |
| var tree = parse(source); | |
| return execTree(tree); | |
| }; | |
| var execTree = function (tree) { | |
| if (typeof tree === 'number') { | |
| return tree; | |
| } | |
| if (tree instanceof Array && tree.length === 3) { | |
| var op = tree[0] | |
| , a = execTree(tree[1]) | |
| , b = execTree(tree[2]); | |
| if (op === '+') { | |
| return a + b; | |
| } | |
| if (op === '-') { | |
| return a - b; | |
| } | |
| if (op === '*') { | |
| return a * b; | |
| } | |
| if (op === '/') { | |
| return a / b; | |
| } | |
| } | |
| throw new Error('bad tree'); | |
| }; | |
| var parse = expose.parse = function () { | |
| var text | |
| , ch | |
| , at | |
| , result; | |
| function tuple(op, a, b) { | |
| if (typeof op !== 'string') { | |
| throw new Error('bad tuple'); | |
| } | |
| return [op, a, b]; | |
| } | |
| function expression() { | |
| var op, a, b; | |
| white(); | |
| a = term(); | |
| white(); | |
| if (ch === '+' || ch === '-') { | |
| op = ch; | |
| next(); | |
| b = expression(); | |
| } | |
| return op ? tuple(op, a, b) : a; | |
| } | |
| function term() { | |
| var op, a, b; | |
| a = factor(); | |
| white(); | |
| if (ch === '*' || ch === '/') { | |
| op = ch; | |
| next(); | |
| white(); | |
| b = term(); | |
| } | |
| return op ? tuple(op, a, b) : a; | |
| } | |
| function factor() { | |
| if (ch === '(') { | |
| next(); | |
| var value = expression(); | |
| white(); | |
| if (ch !== ')') throw new Error('expected ) but' + ch); | |
| next(); | |
| return value; | |
| } else { | |
| return number(); | |
| } | |
| } | |
| function number() { | |
| var match = (/[\+\-]?([1-9][0-9]+|[0-9])/).exec(text.slice(at-1)) | |
| , str = match[0] | |
| , num = +str; | |
| for (var i = 0; i < str.length; i++) { | |
| next(); | |
| } | |
| return num; | |
| } | |
| function white() { | |
| while (ch && ch <= ' ') { | |
| next(); | |
| } | |
| } | |
| function next() { | |
| ch = text.charAt(at); | |
| at += 1; | |
| return ch; | |
| } | |
| return function (source) { | |
| text = source; | |
| ch = " "; | |
| at = 0; | |
| result = expression(); | |
| white(); | |
| return result; | |
| }; | |
| }(); | |
| }(typeof exports === 'undefined' ? window.calc = {} : exports)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment