I've recently played with making simple JS-based parsers without reading anything about the theory. My conclusion was that making a parser by itself is a relatively easy task. The hard part is making grammars easy to read and write, as well as handling various errors.
My best stab at representing something like EBNF in JS looked like this:
class ArrayGrammar { //e.g: [1, 2, 3, [4, 5,],]
array =()=> ['[', this.entries, ']'];
entries =()=> many(this.entry);
entry =()=> [either(this.array, this.number, ''), /\s*,\s*/];
number =()=> /\d+/;
}
This is a grammar for "arrays" of positive integers. I tested it out and concluded that this is too awful to be of any practical use. Now I'm seeing something with significantly more involved representation making it to the front page of HN. Hm.---
Edit: Not much to look at, but here is the source code of the toy implementation if anyone is interested:
https://jsfiddle.net/306jrnt9/1/
The only "cool" part about it is that the parser implementation is close to 100 lines of code.