Skip to content

Instantly share code, notes, and snippets.

@uiur
Created February 7, 2013 02:55
Show Gist options
  • Select an option

  • Save uiur/4728033 to your computer and use it in GitHub Desktop.

Select an option

Save uiur/4728033 to your computer and use it in GitHub Desktop.
電卓パーサ
(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