From f5443d2bf115c55900234baa083608fa219d6356 Mon Sep 17 00:00:00 2001 From: David Majda Date: Wed, 12 Mar 2014 19:05:26 +0100 Subject: [PATCH] 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. --- examples/arithmetics.pegjs | 52 +++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/examples/arithmetics.pegjs b/examples/arithmetics.pegjs index a0b7bc0..ce56d09 100644 --- a/examples/arithmetics.pegjs +++ b/examples/arithmetics.pegjs @@ -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]*