Top Down Operator Precedence

beautiful codeの 9章 下向き演算子順位解析を写経してみたら,いろいろ端折ったのに500行以上になった.思ったより長い.

最初の所はこんな感じ:

$original_symbol = Prototype.new
$original_symbol.error = lambda() {|x| raise x }
$original_symbol.nud = lambda() { self.error "undefined." }
$original_symbol.led = lambda() { self.error "missing operator." }

$symbol_table = {}

def symbol( id, bp=0)
  s = $symbol_table[id]
  if s
    s.lbp = bp if bp >= s.lbp
  else
    s = $original_symbol.clone
    s.tok = s.value = id
    s.lbp = bp
    $symbol_table[id] = s
  end
  s
end

%w": ; , ) ] } else (end) (name)".each{|x|
  symbol x
}

symbol("(literal)").nud = lambda() { self }

symbol("this").nud = lambda() {
  $scope.reserve(self)
  self.arity = "this"
  self
}

Prototypeはhttp://d.hatena.ne.jp/iken0/20080625/p1で定義したやつ.

関数とブロック付きの関数呼び出しの両方で文法を定義するのが微妙な感じがする.