
Understanding Parser Combinators (2015) - signa11
https://fsharpforfunandprofit.com/posts/understanding-parser-combinators/
======
MaxGabriel
This is a pretty in-depth look into parser combinators in F#. If you’d like
something higher level/easier, I wrote an intro to using them in
TypeScript/JavaScript: [https://medium.com/mercury-bank/a-magic-date-input-
using-par...](https://medium.com/mercury-bank/a-magic-date-input-using-parser-
combinators-in-typescript-3c779741bf4c)

------
gameswithgo
I'm curious about the performance of parser combinator approaches to other
parsing methods. It seems that generally they are slower, but is this an
innate problem, or could clever techniques improve on this? Anyone done
work/research in this area?

~~~
Tarean
So the main performance penalty is that you want to parse

    
    
        foobar | foobaz
    

As

    
    
        fooba(r|z)
    

But this requires you to analyse your parsers. Virtually all parser combinator
libraries in haskell are monadic and most others follow suit. This means you
can parse turing complete languages and parsers are very pleasant to write but
also all predicates are undecidable and therefore you can't optimize well.

There are a couple ways around this:

\- rewrite into non-turing-complete parsers when possible using heuristics.
Ghc supports this, the original motivation was implicit parallelism for
facebooks anti-abuse infrastructure

\- use a non-monadic dsl. This either makes coding more awkward or forces you
to reimplement a bunch of things like if statements

\- if you really need performance and error messages use a parser generator
instead of an embedded dsl

Ghc inlines functions incredibly aggressively so the higher order combinators
don't have a huge cost. Doing this in a jit compiled language will be more
expensive. There are also tradeoffs in the primitives you use - you could only
have a primitive to check a single char and then use it in a loop to check
strings. But even when inlined you won't beat a fine tuned string comparison
function this way.

~~~
abecedarius
Right, I think you only need monadic bind for semantic predicates. Ordinary
semantic actions (i.e. ones that don't feed back into deciding how to parse
the rest of the input) can fit smoothly into a parser combinator design
without monads, but AFAIK that's not how it's usually done.

------
nixpulvis
Shameless repost of a parser combinator I wrote for a JSON lab back when I was
a TA at Northeastern.

If you like parsers and Racket this may interest you. I've been wanting to
write up a post kinda like this myself, but haven't found the time.

[https://github.com/nixpulvis/parser-
combinator](https://github.com/nixpulvis/parser-combinator)

~~~
nixpulvis
The beauty of parser combinators is how closely they can follow the
description of languages like JSON. Just compare
[https://json.org](https://json.org) to [https://github.com/nixpulvis/parser-
combinator/blob/master/j...](https://github.com/nixpulvis/parser-
combinator/blob/master/json.rkt) for example.

------
vlowrian
Anyone interested in that matter might enjoy these two blog posts by a
colleague of mine:

1\. [https://medium.com/@armin.heller/using-parser-combinators-
in...](https://medium.com/@armin.heller/using-parser-combinators-in-
go-e63b3ad69c94) 2\. [https://medium.com/@armin.heller/parser-combinator-
gotchas-2...](https://medium.com/@armin.heller/parser-combinator-
gotchas-2792deac4531)

They highlight the typical pitfalls of implementing your own parser
combinators and I found them very helpful for my understanding of parser
combinators.

------
LeanderK
I would really recommend anyone who want's to get a taste of "real" function
programming to develop some parser with parser combinators (I developed a
java-parser). I started to understand a great deal of functional-programming
concepts by using them...and they are so awesome! They are, in my optinion, a
prime example where functional programming shines. I think they really had an
impact on my journy through programming languages.

I am just not sure about f#, but that's probably because I am so used to
haskell.

------
gnufx
it's a long time since I read it, but I remember the treatment in Burge's 1975
"Recursive Programming Techniques" being clear, along with other techniques,
if you can find a library copy. As far as I know, combinator parsing was
introduced there, and I find it's normally worth reading the original
literature on a topic. Burge is a classic generally as a follow-on to "The
Next 700 Programming Languages".

------
nuclx
Very good tutorial. Could easily follow, although I don't know F#, just some
Haskell.

