èæ¯
ãã¾ã¾ã§ãã¡ããã¨ãã¼ãµã¨ãããã®ãæ¸ãããã¨ããªãã£ãã®ã§åå¼·ã®ããã«ã¢ã¬ã³ã¬èããªãããã£ã¦ã¿ããã¨æã£ã¦ãç°¡åãªæ°å¼ãæ¨ã«ãããã¼ãµãæ¸ãã¦ã¿ããã¨æã£ãã®ã§ãï¼ï¼
ä»åä½ããã¼ãµã®ä»æ§
- ãã¼ã¹ããæ°å¼ã®æ¼ç®åã¯äºé æ¼ç®å + - * / ã¨åé æ¼ç®å + - ã ãã
- æ¬å¼§ã¨ãã¯ä½¿ããªãã
- æ¼ç®ã®åªå é ä½ã¯ * / ã®ã»ãã + - ããé«ããã¤ã¾ãã 1 + 1 * 1 㯠1 + (1 * 1)
- åé æ¼ç®åã¯äºé æ¼ç®åããåªå é ä½ãé«ããã¤ã¾ãã - 1 + 1 㯠(-1) + 1
ã§ãä½ã£ã¦ã¿ãï¼
ã½ã¼ã¹ã³ã¼ã
filter é¢æ°ã¨ã使ã£ã¦ãã®ã§ã Firefox only ã§ãã
var parse = function(source) { var tokens = source.match(/[-+*/]|[^-+*/\s]+|\s+/g).filter(/^[^\s]/); var index = 0; var binarys = {'*':2,'/':2,'-':1,'+':1}; var unarys = {'-':1,'+':1}; var stack = []; while (tokens[index] != undefined) { var expression = (function() { var token = tokens[index++]; if (unarys[token]) return [token, arguments.callee()] return token; })(); var operator = tokens[index++]; precedence = (operator == undefined) ? 0: binarys[operator]; while (stack.length && precedence <= binarys[stack[stack.length-1]]) { expression = [stack.pop(), stack.pop(), expression] } stack.push(expression, operator); } return expression; };
å®é使ãã¨ãããªæã
var tree = parse('- 1 * 2 + -3 / -4 * 5'); alert(tree); // ["+", ["*", ["-", "1"], "2"], ["*", ["/", ["-", "3"], ["-", "4"]], "5"]]
ããããããã
ã½ã¼ã¹ã®è§£èª¬
èªåã®åå¿é²ã®ããã«ãã½ã¼ã¹ã解説ãã¾ãã
var tokens = source.match(/[-+*/]|[^-+*/\s]+|\s+/g).filter(/^[^\s]/);
ããã¯ãã½ã¼ã¹ããã¼ã¯ã³ã«åãåãã¦ãã¾ããã¾ãã空ç½ãæ¼ç®åããã®ä»ã«åãã¦ã filter ã§ç©ºç½ãåé¤ãã¦ãã¾ãã
var binarys = {'*':2,'/':2,'-':1,'+':1}; var unarys = {'-':1,'+':1};
binarys ã¯äºé æ¼ç®åã®å®ç¾©ã¨åªå 度ã§ããunarys ã¯åé æ¼ç®åã®å®ç¾©ã¨åªå 度ã§ããæ°å¤ã大ããã»ã©åªå ããã¾ãã
while (tokens[index] != undefined) { .. }
ãã¼ã¯ã³ãç¡ããªãã¾ã§ã«ã¼ããããã§ãã
var expression = (function() { var token = tokens[index++]; if (unarys[token]) return [token, arguments.callee()] return token; })();
å帰å¦çã§åé æ¼ç®åãæ¨ã«ãã¾ããexpression ã¨ããã®ã¯åé æ¼ç®ã解æããï¼é¨åï¼æ¨ã§ããæ¨ã¯é åã§è¡¨ç¾ãã¦ãã¾ãã
['-', 'a']
ãã¨ãã°ã -a ãªã©ã¯ãã®æç¹ã§ä¸ã®ãããªæ¨ï¼é åï¼ã«ãªãã¾ãã
var operator = tokens[index++]; precedence = (operator == undefined) ? 0: binarys[operator];
ããã§ã® operator ã¯äºé æ¼ç®åã§ããprecedence ã¯ãã®æ¼ç®åã®åªå 度ã§ããæ°å¼ã®æ«å°¾ã®å ´åã¯ãåªå 度 0 ã«ãªãã¾ãã
while (stack.length && precedence <= binarys[stack[stack.length-1]]) { expression = [stack.pop(), stack.pop(), expression] }
ããã®è¡ã¯ãæåã®ï¼ã«ã¼ãç®ã§ã¯é£ã°ããã¾ããï¼stack ã空ã ãã
stack.push(expression, operator);
ããã§ã¯ expression ï¼å·¦è¾ºã®é¨åæ¨ï¼ã¨ operator ï¼äºé æ¼ç®åï¼ãã¹ã¿ãã¯ã«ä¿åãã¦ããã¾ãã
while (stack.length && precedence <= binarys[stack[stack.length-1]]) { expression = [stack.pop(), stack.pop(), expression] }
ãããï¼ã«ã¼ãç®ã§ä¸ã¤ä¸ã®è¡ã«æ»ã£ã¦ãã¾ããããã㧠expression ã¯ï¼ã«ã¼ãç®ããè¦ããå³è¾ºã«å½ããã¾ãã左辺ã¨æ¼ç®åã¯ã¹ã¿ãã¯ã«ããã¾ããprecedence ã¯æ¬¡ã®æ¼ç®åã®åªå
度ã«ãªãã¾ãã
ããã§ã operator 㨠stack ã®æ¼ç®åã®åªå
度ãæ¯è¼ãã¾ããããã§ãåªå
度ãåãã ã£ãããstack ã®æ¼ç®åã®ã»ããé«ãå ´åã¯ããã¾ã§ã®è¨ç®ã¯å
ã«ãã¦ãããã¯ããªã®ã§ãäºé
æ¼ç®ã®æ¨ãä½ãã¾ãã
ä¾ãã°ãä¸ã®ãããªæ¼ç®ãæ³åãã¦ã¿ã¦ãã ããã
1 * 2 + 3 * 4
1 * 2 + ã¾ã§èªãã æç¹ã§ 1 * 2 ã¯è¨ç®ãã¦ãã¾ã£ã¦ãããã¨åããã¯ãã§ãã
ãã®ããã«ã次ã
ã¨æ¼ç®åãèªã¿è¾¼ãã§ã¯åªå
度çã«çµã¿åããã¦ãã¾ã£ã¦ãããå¼ãé¨åæ¨ã«ãã¦ããã®ã§ãã
æ°å¼ã®æ«å°¾ã¾ã§ããã¨åªå
度 0 ã«ãªãã®ã§ããã¹ã¦ã®æ°å¼ãæ¨ã«ãªãã¾ãã
以ä¸ã§ãã½ã¼ã¹ã®è§£èª¬ã¯çµããã§ãã
ã¾ã¨ã
ãã¼ãµã¨ãæ¸ãããã¨ã®ãªãç´ äººãªã®ã§ãç¨èªã¨ããæå³ä¸æã ã¨æãã¾ãï¼ï¼
ä¸å¿ãèªåç¨ã®ã¡ã¢ãªã®ã§è¨±ãã¦ãã ããï¼ï¼
åå¼·ã«ãªãã¾ããï¼