Sha256: 68c951f5af9e5f81ec5d882e97c970772deb56d8206792a0522dad0ee73a0c41

Contents?: true

Size: 1.91 KB

Versions: 2

Compression:

Stored size: 1.91 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. This grammar should provide the same interpretation
# as Ruby for all mathematical expressions.
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

2 entries across 2 versions & 1 rubygems

Version Path
citrus-2.3.4 examples/calc.citrus
citrus-2.3.3 examples/calc.citrus