---- title: klipspringer – a combinatorial parser generator SPDX-FileCopyrightText: 2025 Norman Gray SPDX-License-Identifier: BSD-2-Clause This is a simple implementation of a combinatorial parser. In the type declarations below, * `LEXEME?` is whatever lexemes the functions are expected to parse; ie, it is whatever `lexeme-source?` returns * `LEXEME-SOURCE?` is a function `(-> (or/c lexeme? eof/c))`. This consumes the source – that is, each time this function is called, it returns a lexeme which it will not return again. This function is supplied by the user of the library. The function must return `#` when the list of lexemes is exhausted. * `VALUE?` is whatever the results are (eg, xexprs) * `PARSER?` is `(input? -> (or/c consumed? empty?)` This module is an implementation of the ‘parsec’ Haskell library described in [leijen01][], which in turn expands on the general description of this class of parsers in [hutton96][]. The interface, however, _closely_ follows that of the Racket implementation of this approach, [parsack](https://docs.racket-lang.org/parsack/index.html). There is an alternative Racket implementation called [megaparsack](https://docs.racket-lang.org/megaparsack/index.html). The [klipspringer](https://en.wikipedia.org/wiki/Klipspringer) is a small robust (and unutterably cute) antelope. That is, it is of the same bovid family as the bison and the yak. ![A friendly Klipspringer](klipspringer.jpg) References: @techreport{hutton96, author = {Graham Hutton and Erik Meijer}, institution = {University of Nottingham}, title = {Monadic Parser Combinators}, url = {https://nottingham-repository.worktribe.com/output/1024440}, year = 1996} @techreport{leijen01, author = {Daan Leijen and Erik Meijer}, institution = {University of Utrecht}, note = {Cited as 'Electronic Notes in Theoretical Computer Science 41 No. 1 (2001)', but that doesn't seem to actually exist. I could find it only at Researchgate}, title = {Parsec: A Practical Parser Library}, url = {https://www.researchgate.net/publication/2534571_Parsec_Direct_Style_Monadic_Parser_Combinators_For_The_Real_World}, year = 2001} [hutton96]: https://nottingham-repository.worktribe.com/output/1024440 [leijen01]: https://www.researchgate.net/publication/2534571_Parsec_Direct_Style_Monadic_Parser_Combinators_For_The_Real_World Basic operations ================ **This documentation is _very_ flimsy, so far.** Right now, the best documentation is the implementation this is based on, namely [Racket parsack](https://docs.racket-lang.org/parsack/index.html). I haven't implemented everything there, but the functions I have implemented, should have the same semantics. This module is designed for internal use only so far, but I expect to make it a little more public in time, after it has settled down a bit. A parser is a function that consumes a sequence of lexemes, and returns a parse result. The result is not constrained by the functions here, but depends on the outputs of the functions bound to the individual parsers. (parse-result (>>= (char #\() (λ (skip1) (>>= $letter (λ (x) (>>= (char #\)) (λ (skip2) (return x))))))) "(a)") => #\a