Hey Rich,
Case b can be handled pretty easily by adding a rule for matching zero or more whitespace characters and then putting it where whitespace may occur.
eg. I'd define my whitespace rule as follows:
_
= [ \t\r\n]*
then change the primary and integer rules as follows:
primary
= integer
/ _ "(" additive:additive ")" _ { return additive; }
integer "integer"
= _ digits:[0-9]+ _ { return parseInt(digits.join(""), 10); }
Case c is easy to handle if you only have a single line - just change the start rule as follows:
start
= additive:additive ("--" [^\r\n]*)? {return additive}
The last case requires more work, as you need to deal with multiple lines. Personally, I'd clean up comments and whitespace in one pass and then parse in another pass.
Here's a rough pass that doesn't cover all the cases - it should get you started though.
/* Parse zero or more lines */
start
= line*
line
= additive:additive comment? {return additive} / comment {return null}
additive
= left:multiplicative "+" right:additive { return left + right; }
/ multiplicative
multiplicative
= left:primary "*" right:multiplicative { return left * right; }
/ primary
primary
= integer
/ _ "(" additive:additive ")" _ { return additive; }
integer "integer"
= _ digits:[0-9]+ _ { return parseInt(digits.join(""), 10); }
comment
= "--" [^\n\r]* EOL
EOL
= [\n\r]{1,2} / !.
_
= [ \n\r\t]*
Cheers!
--zak