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
|
||||
* "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…
Reference in New Issue