BNF sounds like the standard approach. Are there any BNF parsers + generators usable from Javascript?
- Antlr (https://github.com/antlr/antlr4/blob/master/doc/javascript-target.md)
- PegJS (https://github.com/pegjs/pegjs)
- Nearley (https://github.com/kach/nearley)