Hi all,

As some of you may know, I am the maintainer of the Megaparsack
<https://docs.racket-lang.org/megaparsack/index.html> package, a
Parsec-style parser combinator library. Though it’s mostly been in
maintenance mode for some time, the latest release adds a significant new
feature: *user-defined parser state*. This closes the main expressivity gap
Megaparsack has historically had relative to Parsack (though Parsack
continues to be more performant).

As a quick overview to pique your interest, Megaparsack 1.4 provides a new
abstraction called a *parser parameter*. Parser parameters are similar to
ordinary Racket parameters, but their state is associated with a parsing
context rather than with a thread. Their interface should already look
familiar to Racketeers, so here is an example that uses parser parameters
to implement an indentation-sensitive syntax:

(define current-indent (make-parser-parameter 0))

(define skip-current-indent/p
  (do [cols <- (current-indent)]
      (repeat/p cols (char/p #\space))))

(define markdown-like-list/p
  (do (string/p "* ")
      [blk <- block/p]
      [cols <- (current-indent)]
      [blks <- (parameterize/p ([current-indent (+ cols 2)])
                 (many/p block/p))]
      (pure (cons blk blks))))

Modifications to parser parameters are automatically reverted when the
parser backtracks past the point of modification, which allows them to be
used for accumulating information during parsing even if the current parse
branch is tentative. To illustrate, note that this example results in 10
rather than 15:

(define current-count (make-parser-parameter 0))

(define (increment/p n)
  (do [count <- (current-count)]
      (current-count (+ count n))))

> (parse-string
   (do (or/p (try/p (do (string/p "!") (increment/p 5) eof/p))
             (do (string/p "!!") (increment/p 10) eof/p))
       (current-count))
   "!!")
(success 10)

I generally don’t post about releases to this list, but I happen to know
Megaparsack has at least a few active users, and this is the first major
update in a long while, so I figured I’d give a heads-up. If you’ve counted
the library out in the past for missing this feature, consider giving it
another look. And if you’re interested in learning more, the gory details
are described in the documentation, along with some additional examples (at
the time of this writing, pkg-build hasn’t rebuilt the docs just yet, but
that should be resolved with tomorrow’s daily refresh).

Happy parsing,
Alexis

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAA8dsaf1%2B%2BSwHiuEr0zd4iFutb5tK2UAgMmXShk%2B20p4W3kaag%40mail.gmail.com.

Reply via email to