Sha256: 7e60d2145b2835ce5a588b26986a7307ca6892835db84f9002d6debc635ebb3d

Contents?: true

Size: 1.86 KB

Versions: 3

Compression:

Stored size: 1.86 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.2.2 examples/calc.citrus
citrus-2.2.1 examples/calc.citrus
citrus-2.2.0 examples/calc.citrus