Ohm/JS Arithmetic Example
by Patrick Dubroy
HTML
<script src="https://unpkg.com/ohm-js@16/dist/ohm.min.js"></script>
<pre id="result"></pre>
JavaScript
// An Ohm grammar for arithmetic expressions.
// Syntax reference: https://github.com/harc/ohm/blob/master/doc/syntax-reference.md
const grammarSource = String.raw`
Arithmetic {
Exp = AddExp
AddExp = AddExp "+" PriExp -- plus
| AddExp "-" PriExp -- minus
| PriExp
PriExp = "(" Exp ")" -- paren
| number
number = digit+
}
`;
// Instantiate the grammar defined above.
const g = ohm.grammar(grammarSource);
// Define an operation named 'eval' which evaluates the expression.
// See https://github.com/cdglabs/ohm/blob/master/doc/api-reference.md#semantics
const semantics = g.createSemantics().addOperation('eval', {
Exp(e) {
return e.eval();
},
AddExp(e) {
return e.eval();
},
AddExp_plus(left, op, right) {
return left.eval() + right.eval();
},
AddExp_minus(left, op, right) {
return left.eval() - right.eval();
},
PriExp(e) {
return e.eval();
},
PriExp_paren(open, exp, close) {
return exp.eval();
},
number(chars) {
return parseInt(this.sourceString, 10);
},
});
let result;
const m = g.match('1 + 2 - 3');
if (m.succeeded()) {
result = semantics(m).eval(); // Evaluate the expression.
} else {
result = m.message; // Extract the error message.
}
document.getElementById('result').textContent = result;