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
parent
93d3c6a250
commit
f5443d2bf1
@ -1,22 +1,44 @@
|
|||||||
/*
|
/*
|
||||||
* Classic example grammar, which recognizes simple arithmetic expressions like
|
* Simple Arithmetics Grammar
|
||||||
* "2*(3+4)". The parser generated from this grammar then computes their value.
|
* ==========================
|
||||||
|
*
|
||||||
|
* Accepts expressions like "2 * (3 + 4)" and computes their value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
start
|
{
|
||||||
= additive
|
function combine(first, rest, combiners) {
|
||||||
|
var result = first, i;
|
||||||
|
|
||||||
additive
|
for (i = 0; i < rest.length; i++) {
|
||||||
= left:multiplicative "+" right:additive { return left + right; }
|
result = combiners[rest[i][1]](result, rest[i][3]);
|
||||||
/ multiplicative
|
}
|
||||||
|
|
||||||
multiplicative
|
return result;
|
||||||
= left:primary "*" right:multiplicative { return left * right; }
|
}
|
||||||
/ primary
|
}
|
||||||
|
|
||||||
primary
|
Expression
|
||||||
= integer
|
= first:Term rest:(_ ("+" / "-") _ Term)* {
|
||||||
/ "(" additive:additive ")" { return additive; }
|
return combine(first, rest, {
|
||||||
|
"+": function(left, right) { return left + right; },
|
||||||
|
"-": function(left, right) { return left - right; }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
integer "integer"
|
Term
|
||||||
= digits:$[0-9]+ { return parseInt(digits, 10); }
|
= 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…
Reference in New Issue