優先順位は使わず規則だけで演算子の優先順位を
やってみた
class Parser options no_result_var rule expr : addsub addsub: addsub '+' muldiv { val[0] + val[2] } | addsub '-' muldiv { val[0] - val[2] } | muldiv muldiv: muldiv '*' primary { val[0] * val[2] } | muldiv '/' primary { val[0] / val[2] } | primary primary: NUM | '(' expr ')' { val[1] } end ---- inner def parse yyparse( self, :scan ) end def scan require 'strscan' s = StringScanner.new( gets ) until s.eos? next if s.skip( /\s+/ ) case when s.scan( /\d+/ ) yield :NUM, s.matched.to_i else yield s.getch, nil end end yield false, '$' end ---- footer p Parser.new.parse
右から左に結合する演算子
結合規則が右から左な演算子は
pow : primary POW_OP pow { val[0] ** val[2] } # 右から左の結合規則
のようにすればいい。
pow : pow POW_OP primary { val[0] ** val[2] } # これだと左から右になる
ではないことに注目。
単項演算子
uminus: '-' uminus { - val[1] }