Browse Source
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
1 changed files with 37 additions and 15 deletions
@ -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