Sha256: 65a57c12e2b5b54e76b4b90ef5142752053082fcc0a88830d97d4f6132c7c4cf
Contents?: true
Size: 1.79 KB
Versions: 5
Compression:
Stored size: 1.79 KB
Contents
require 'citrus' # A grammar for mathematical formulas that apply the basic four operations to # non-negative numbers (integers and floats), respecting operator precedence and # ignoring whitespace. module Calc include Citrus::Grammar module FirstValue def value first.value end end rule :term do ext(any(:additive, :factor), FirstValue) end rule :additive do all(:factor, label(:additive_op, :operator), :term) { def value operator.apply(factor.value, term.value) end } end rule :factor do ext(any(:multiplicative, :primary), FirstValue) end rule :multiplicative do all(:primary, label(:multiplicative_op, :operator), :factor) { def value operator.apply(primary.value, factor.value) end } end rule :primary do ext(any(:term_paren, :number), FirstValue) end rule :term_paren do all(:lparen, :term, :rparen) { def value term.value end } end rule :additive_op do any(:plus, :minus) { def apply(factor, term) text.strip == '+' ? factor + term : factor - term end } end rule :multiplicative_op do any(:star, :slash) { def apply(primary, factor) text.strip == '*' ? primary * factor : primary / factor end } end rule :number do ext(any(:float, :integer), FirstValue) end rule :float do all(/[0-9]+/, '.', /[0-9]+/, :space) { def value text.strip.to_f end } end rule :integer do all(/[0-9]+/, :space) { def value text.strip.to_i end } end rule :lparen, ['(', :space] rule :rparen, [')', :space] rule :plus, ['+', :space] rule :minus, ['-', :space] rule :star, ['*', :space] rule :slash, ['/', :space] rule :space, /[ \t\n\r]*/ end
Version data entries
5 entries across 5 versions & 1 rubygems
Version | Path |
---|---|
citrus-1.2.2 | examples/calc.rb |
citrus-1.2.1 | examples/calc.rb |
citrus-1.2.0 | examples/calc.rb |
citrus-1.1.0 | examples/calc.rb |
citrus-1.0.0 | examples/calc.rb |