[讨论] Treetop 讨论

night_stalker 2010-02-12
啊,看错了……写那论文的人用 happy 做对比,不是用 happy
RednaxelaFX 2010-02-12
night_stalker 写道
啊,看错了……写那论文的人用 happy 做对比,不是用 happy

packrat的话你是想用pappy么……
night_stalker 2010-02-12
frisby 和 pappy 都在调查中,貌似也比较丑 ...
RednaxelaFX 2010-02-12
好吧我也来Treetop tutorial一把。接触解析器生成器必出四则混合运算计算器作为hello world。
首先是基础语法,用了Kleene star与plus
grammar Arithmetic
  rule expr
    term ([\+\-] term)*
  end
  
  rule term
    factor ([\*\/] factor)*
  end

  rule factor
    '(' expr ')' / number
  end
  
  rule number
    [1-9] [0-9]*
  end
end

然后是在基础语法上加了语义动作的PEG SDT:
grammar Arithmetic
  rule expr
    left:term right_opt:(op:[\+\-] right:term)* {
      def value
        right_opt.elements.inject(left.value) {|acc, plus_and_right|
          acc.send(plus_and_right.op.text_value.to_sym,
            plus_and_right.right.value)
        }
      end
    }
  end
  
  rule term
    left:factor right_opt:(op:[\*\/] right:factor)* {
      def value
        right_opt.elements.inject(left.value) {|acc, mul_and_right|
          acc.send(mul_and_right.op.text_value.to_sym,
            mul_and_right.right.value)
        }
      end
    }
  end

  rule factor
    '(' expr ')' {
      def value
        expr.value
      end
    }
    /
    number
  end
  
  rule number
    [1-9] [0-9]* {
      def value
        text_value.to_f
      end
    }
  end
end

也是保存为little.tt,用
tt little.tt

生成little.rb,然后在irb里测试:
irb(main):001:0> require 'rubygems'
=> false
irb(main):002:0> require 'treetop'
=> true
irb(main):003:0> require 'little'
=> true
irb(main):004:0> p = ArithmeticParser.new
=> #<ArithmeticParser:0x3383df0 @consume_all_input=true>
irb(main):005:0> p.parse('1+2-3*4*5/((2*3)+6)-7').value
=> -9.0


(吐槽:官网上的教程居然有错……照那样直接map是不行滴 T T)
Global site tag (gtag.js) - Google Analytics