Ohm Arithmetic Expression Evaluation - CoffeeScript version

Simple example of using Ohm/JS to evaluate simple arithmetic expressions

by Ray Toal

HTML

<script src="http://www.cdglabs.org/ohm/dist/ohm.js"></script>
<script type="text/ohm-js">
// Based on http://jsfiddle.net/pdubroy/15k63qae/
Arithmetic {
  Exp     = Exp "+" Term      -- plus
          | Exp "-" Term      -- minus
          | Term
  Term    = Term "*" Factor   -- times
          | Term "/" Factor   -- divide
          | Factor
  Factor  = Primary
          | "-" Primary       -- negate
  Primary = "(" Exp ")"       -- paren
          | number
  number  = digit+ ("." digit+)?
}
</script>
<pre id="result"></pre>

CoffeeScript

g = ohm.grammarFromScriptElement()

semantics = g.semantics().addOperation('eval', {
  Exp_plus: (x, op, y) -> x.eval() + y.eval(),
  Exp_minus: (x, op, y) -> x.eval() - y.eval(),
  Term_times: (x, op, y) -> x.eval() * y.eval(),
  Term_divide: (x, op, y) -> x.eval() / y.eval(),
  Factor_negate: (op, x) -> -x.eval(),
  Primary_paren: (open, exp, close) -> exp.eval(),
  number: (main, dot, fraction) -> parseFloat @interval.contents,
})

m = g.match '11 / 3 + (-6.45*4) * 3 / 2'
result = if m.succeeded() then semantics(m).eval() else m.message
document.getElementById('result').textContent = result