100オーダーな優先順位付き演算子定義構文解析器
優先順位をリストで管理してやることで、とびとびの値の優先順位を付けられる
ようなパーサを作ってみました。
サンプル
http://sakurai.s59.xrea.com/diary/100order.html
以下ソース
<script> Object.prototype.toString = function() { var str = []; for (var i in this) str.push(i+":"+this[i]) return "{"+str.join(",")+"}" } function Operators(p,op,f,n) { this.priority = p this.operators = {} this.operators[op] = f this.next = n } Operators.prototype.set = function (op, no, f) {with(this){ if (priority == no) return operators[op]=f,this if (next == null) return next = new Operators(no, op, f, null) if (priority < no && next.priority > no) return next = new Operators(no, op, f, next) return next.set(op, no, f) }} var infixs = new Operators(0) infixs.set("+",100,function(a,b){return [a,"+",b]}) infixs.set("-",100,function(a,b){return [a,"-",b]}) infixs.set("*",200,function(a,b){return [a,"*",b]}) infixs.set("/",200,function(a,b){return [a,"/",b]}) Array.prototype.toString = function(){return "("+this.join(" ")+")"} function c() { document.getElementById("out").value = eval(document.getElementById("in").value) } function eval(str){ function peek() { return str.match(/^[ \r\n\t]*([0-9]+|\+|\-|\*|\/|\(|\)|$)/)[1] } function pop() { return peek(),str = RegExp.rightContext,RegExp.$1 } function exp() { return expn(infixs.next) } function expn(infixs) { if (infixs == null) return fact() var c = expn(infixs.next) var f = infixs.operators[peek()] if(f) return pop(), f(c,expn(infixs)) return c } function fact() { var c = pop() if(Number(c))return Number(c) if(c == "("){c = exp(); if(pop() == ")")return c} throw new Error("error") } return exp() } </script> <input id=in> <input id=out> <input type=button onclick=c()>