Download and use

To use this module in Racket, download the code, place it in the same directory as your code, and then require it:

    (require "derivative-parsers.rkt")
   

Warnings

This version of the code still uses fixed points internally. David Darais found a way to eliminate fixed points, which substantially speeds up parsing. derp will eliminate fixed points internally soon, but the performance-conscious may want to wait until then.

Documentation

A language is a first-class value with derp.

The macro lang creates a language.

Atomic languages

Within lang there are several atomic subforms:

To make it easier to write terminals (token classes) in the grammar, several literal forms are available:

The procedure literal->language can be set with set-literal->language!.

Compound languages

There are a few core compound language subforms:

When the (seq ...) subform produces a parse tree, it conses their results.

When the (rep ...) subform parses into a proper list of matches.

Meta-syncatic sugar

There are several non-core forms that expand into core forms; these are convenient for parsing:

Parsing interface

To parse a stream with respect to a language L, use (parse L stream). Streams are available in srfi/41.

Example

To parse (lexed) comma-separated values:

(define SYMBOL (lang (? symbol? 'symbol)))

(define csv (lang (or (@--> (seq! `SYMBOL "," `csv) cons)
                      ($--> SYMBOL (list $$)))))

(parse csv (stream 'foo "," 'bar "," 'baz))
; => (set '(foo bar baz))