In the whole grammar I wasn't able to find a consistent system in where you put `_` and `__`. For example, `int` and `string` seem to me as rules on the same level, but one has `_`'s around it, the other has not. It's not obvious why.

Personally, I use one of two consistent systems for grammars that have clear lexical part:

  * I make rule for each token (including things like `","`) and make sure an equivalent of your `_` rule is at the end of rule's expression. That way inter-token whitespace & comments are resolved in the lexical part of the grammar and I don't have to deal with them at all in high level rules.

  * I put an equivalent of your `_` rule explicitly around tokens at appropriate places in high level rules. This is more verbose, but you don't have to have rules for things like `","`. This approach is also useful for grammars where whitespace & comments are sometimes significant.

I should add that handling of ignored comments/whitespace/whatever is one of the weaker parts of PEG.js and I want to address it at some point. I am not sure how exactly yet though.