Sha256: b0fbf24d176bf01e551f9e80c1bac06bfa2d562f88e922208226665432763d84

Contents?: true

Size: 1.89 KB

Versions: 3

Compression:

Stored size: 1.89 KB

Contents

# A grammar for mathematical formulas that apply basic mathematical operations
# to all numbers, respecting operator precedence and grouping of expressions
# while ignoring whitespace.
#
# An identical grammar that is written using pure Ruby can be found in calc.rb.
grammar Calc

  ## Hierarchical syntax

  rule term
    additive | factor
  end

  rule additive
    (factor additive_operator term) {
      additive_operator.value(factor.value, term.value)
    }
  end

  rule factor
    multiplicative | prefix
  end

  rule multiplicative
    (prefix multiplicative_operator factor) {
      multiplicative_operator.value(prefix.value, factor.value)
    }
  end

  rule prefix
    prefixed | exponent
  end

  rule prefixed
    (unary_operator prefix) {
      unary_operator.value(prefix.value)
    }
  end

  rule exponent
    exponential | primary
  end

  rule exponential
    (primary exponential_operator prefix) {
      exponential_operator.value(primary.value, prefix.value)
    }
  end

  rule primary
    group | number
  end

  rule group
    (lparen term rparen) {
      term.value
    }
  end

  ## Lexical syntax

  rule number
    float | integer
  end

  rule float
    (digits '.' digits space*) {
      strip.to_f
    }
  end

  rule integer
    (digits space*) {
      strip.to_i
    }
  end

  rule digits
    # Numbers may contain underscores in Ruby.
    [0-9]+ ('_' [0-9]+)*
  end

  rule additive_operator
    (('+' | '-') space*) { |a, b|
      a.send(strip, b)
    }
  end

  rule multiplicative_operator
    (('*' | '/' | '%') space*) { |a, b|
      a.send(strip, b)
    }
  end

  rule exponential_operator
    ('**' space*) { |a, b|
      a ** b
    }
  end

  rule unary_operator
    (('~' | '+' | '-') space*) { |n|
      # Unary + and - require an @.
      n.send(strip == '~' ? strip : '%s@' % strip)
    }
  end

  rule lparen '(' space* end
  rule rparen ')' space* end
  rule space  [ \t\n\r]  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
citrus-2.3.2 examples/calc.citrus
citrus-2.3.1 examples/calc.citrus
citrus-2.3.0 examples/calc.citrus