Sha256: 4796b3e31855328f82527c32a5ec43d19518638b94eba35f60f7d6d3ea130bf1

Contents?: true

Size: 1.71 KB

Versions: 5

Compression:

Stored size: 1.71 KB

Contents

# A grammar for mathematical formulas that apply the basic four operations to
# non-negative numbers (integers and floats), respecting operator precedence and
# ignoring whitespace.
grammar Calc
  rule term
    (additive | factor) {
      def value
        first.value
      end
    }
  end

  rule additive
    (factor operator:additive_op term) {
      def value
        operator.apply(factor.value, term.value)
      end
    }
  end

  rule factor
    (multiplicative | primary) {
      def value
        first.value
      end
    }
  end

  rule multiplicative
    (primary operator:multiplicative_op factor) {
      def value
        operator.apply(primary.value, factor.value)
      end
    }
  end

  rule primary
    (term_paren | number) {
      def value
        first.value
      end
    }
  end

  rule term_paren
    (lparen term rparen) {
      def value
        term.value
      end
    }
  end

  rule additive_op
    (plus | minus) {
      def apply(factor, term)
        text.strip == '+' ? factor + term : factor - term
      end
    }
  end

  rule multiplicative_op
    (star | slash) {
      def apply(primary, factor)
        text.strip == '*' ? primary * factor : primary / factor
      end
    }
  end

  rule number
    (float | integer) {
      def value
        first.value
      end
    }
  end

  rule float
    ([0-9]+ '.' [0-9]+ space) {
      def value
        text.strip.to_f
      end
    }
  end

  rule integer
    ([0-9]+ space) {
      def value
        text.strip.to_i
      end
    }
  end

  rule lparen  '(' space  end
  rule rparen  ')' space  end
  rule plus    '+' space  end
  rule minus   '-' space  end
  rule star    '*' space  end
  rule slash   '/' space  end

  rule space
    [ \t\n\r]*
  end
end

Version data entries

5 entries across 5 versions & 1 rubygems

Version Path
citrus-1.2.2 examples/calc.citrus
citrus-1.2.1 examples/calc.citrus
citrus-1.2.0 examples/calc.citrus
citrus-1.1.0 examples/calc.citrus
citrus-1.0.0 examples/calc.citrus