Parser combinators for lazy streams can be written as recursive descent and perform as, more or less, generalized LR parsing (exploring all tree branches &quot;simultaneously&quot;).<p><a href="http:&#x2F;&#x2F;www.cs.nott.ac.uk&#x2F;~pszgmh&#x2F;monparsing.pdf" rel="nofollow">http:&#x2F;&#x2F;www.cs.nott.ac.uk&#x2F;~pszgmh&#x2F;monparsing.pdf</a><p>What is more, these combinators can express context-sensitive grammars: <a href="https:&#x2F;&#x2F;www.cs.york.ac.uk&#x2F;plasma&#x2F;publications&#x2F;pdf&#x2F;partialparse.pdf" rel="nofollow">https:&#x2F;&#x2F;www.cs.york.ac.uk&#x2F;plasma&#x2F;publications&#x2F;pdf&#x2F;partialpar...</a> (page 5).<p>And, by tweaking combinators, you can arrive to the wonders of stream processing parsing without (mostly) space leaks: <a href="http:&#x2F;&#x2F;www.cse.chalmers.se&#x2F;edu&#x2F;year&#x2F;2015&#x2F;course&#x2F;afp&#x2F;Papers&#x2F;parser-claessen.pdf" rel="nofollow">http:&#x2F;&#x2F;www.cse.chalmers.se&#x2F;edu&#x2F;year&#x2F;2015&#x2F;course&#x2F;afp&#x2F;Papers&#x2F;p...</a><p>It is easy to add syntax error position reporting, also it is easy to add syntax error corrections. All this can be done in under a day.<p>For me it offers good things from both worlds - declarative specification of parser generators and easy modifications from &quot;parse damn thing by hand&quot;.<p>I actually encountered one case where that approach shines incommensurably: supporting old languages like VHDL. VHDL fits every parser formalism <i>almost without seams</i> but still has one place where you cannot do things either efficiently or elegantly: character literals and attributes. &#x27;a&#x27; is a character literal, a&#x27;a is an invocation of attribute a on the object a. The ambiguity is in the lexing level, needing feedback from parsing level. Usual parsing tools cannot do that good enough, with parsing combinators it is trivial.