Complete rewrite of the arithmetics example grammar

This is a complete rewrite of the arithmetics example grammar. It now
allows whitespace between tokens, supports "-" and "/" operators, and
gets the operator associativity right. Also, rule names now match the usual
conventions (term, factor,...).

Beside this, the rewrite reflects how I write grammars today (as opposed
to few years ago) and what style I would recommend to others.
redux
David Majda 10 years ago
parent 93d3c6a250
commit f5443d2bf1

@ -1,22 +1,44 @@
/*
* Classic example grammar, which recognizes simple arithmetic expressions like
* "2*(3+4)". The parser generated from this grammar then computes their value.
* Simple Arithmetics Grammar
* ==========================
*
* Accepts expressions like "2 * (3 + 4)" and computes their value.
*/
start
= additive
{
function combine(first, rest, combiners) {
var result = first, i;
additive
= left:multiplicative "+" right:additive { return left + right; }
/ multiplicative
for (i = 0; i < rest.length; i++) {
result = combiners[rest[i][1]](result, rest[i][3]);
}
multiplicative
= left:primary "*" right:multiplicative { return left * right; }
/ primary
return result;
}
}
primary
= integer
/ "(" additive:additive ")" { return additive; }
Expression
= first:Term rest:(_ ("+" / "-") _ Term)* {
return combine(first, rest, {
"+": function(left, right) { return left + right; },
"-": function(left, right) { return left - right; }
});
}
integer "integer"
= digits:$[0-9]+ { return parseInt(digits, 10); }
Term
= first:Factor rest:(_ ("*" / "/") _ Factor)* {
return combine(first, rest, {
"*": function(left, right) { return left * right; },
"/": function(left, right) { return left / right; }
});
}
Factor
= "(" _ expr:Expression _ ")" { return expr; }
/ Integer
Integer "integer"
= [0-9]+ { return parseInt(text(), 10); }
_ = "whitespace"
[ \t\n\r]*

Loading…
Cancel
Save