Hacker News new | ask | show | jobs
by Eliah_Lakhin 742 days ago
I think it all depends on the language, but I found it (usually) easier to implement the recursive-descending parsers just manually. This may include combination approach too, but using my own combinatorial and domain-specific functions.

In a nutshell such a parser is PEG in a sense that the choice is ordered, but with little to no test expressions. In other words, I try to stick to lookahead-1 most of the time. Left recursion quite often could be resolved by lifting the branches to their siblings rather than re-parsing the same things many times using the cache (packrat). In fact both approaches, the packrat and the nodes lifting, are the same in a nutshell, but nodes lifting is usually easier to maintain (again, it all depends).

Writing the parser manually, or in other words a set of relatively simple mutually recursive functions, in my opinion, is not the hardest problem in practical engineering. At least it's not so hard when you have a mental model of the language's syntax upfront.

If the language fits specific class of formal grammars very well, perhaps it would be not so hard to implement it using the parsers generator tool. But it is likely there will be edge cases that are hard to express properly using the formal grammar, and fighting with the tool specifics will waste a lot of your time rather than benefit you.

2 comments

> I think it all depends on the language, but I found it (usually) easier to implement the recursive-descending parsers just manually.

I think that packrat parsers are even easier to implement by hand, and even troubleshoot.

It's all procedural code, and you just call the next routine to figure out if you have a token match or not.

More importantly, PEGs promise to be easier to maintain in smaller custom parsers. To support an enum, all you need to do is add a function call, and that's it. One line of code. Can't beat that.

> I think it all depends on the language, but I found it (usually) easier to implement the recursive-descending parsers just manually. This may include combination approach too, but using my own combinatorial and domain-specific functions.

Working in what languages did you make this observation?

In something like C I would probably agree with you. But in eg Haskell or OCaml, I would probably prefer parser combinators.

In other functional languages I tend to reach for combinators, but in OCaml I either use Menhir or regret not using it.
I work with Rust most of the time. As of the pure functional languages, yes, perhaps using parser combinators is better.