On this page:
5.1 Primitives
parser?
parser/  c
parse
parse-error->string
parse-result!
exn:  fail:  read:  megaparsack
syntax-box
message
void/  p
or/  p
try/  p
lookahead/  p
satisfy/  p
eof/  p
label/  p
hidden/  p
syntax/  p
syntax-box/  p
fail/  p
many/  p
many+  /  p
repeat/  p
==/  p
one-of/  p
guard/  p
list/  p
5.1.1 Parser Parameters
make-parser-parameter
parser-parameter?
parameterize/  p
5.2 Parsing Text
parse-string
parse-syntax-string
char/  p
char-not/  p
char-ci/  p
char-between/  p
char-in/  p
char-not-in/  p
any-char/  p
letter/  p
digit/  p
symbolic/  p
space/  p
integer/  p
string/  p
string-ci/  p
5.3 Parsing with parser-tools/  lex
parse-tokens
token/  p
5.4 Deprecated Forms and Functions
many*/  p
many/  sep*/  p
many/  sep+  /  p
8.2

5 API Reference

A parser is a value that represents a method of turning a syntax object or sequence of syntax objects an arbitrary Racket value. Parsers can be created using various primitives, then sequenced together using parser combinators to create larger parsers.

Parsers are functors, applicative functors, and monads, which allows them to be mapped over and sequenced together using the corresponding generic interfaces.

5.1 Primitives

procedure

(parser? v)  boolean?

  v : any/c
Returns #t if v is a parser, otherwise returns #f.

procedure

(parser/c in-ctc out-ctc)  contract?

  in-ctc : contract?
  out-ctc : contract?
Produces a contract that recognizes parsers. Tokens consumed by the parser must match in-ctc, and values returned by the parser must match out-ctc.

If both in-ctc and out-ctc are chaperone contracts, then the result will also be a chaperone contract.

procedure

(parse parser boxes)  (either/c message? any/c)

  parser : parser?
  boxes : (listof syntax-box?)
Runs parser on boxes and returns either the result of a successful parse or a value that includes information about the parse failure.

procedure

(parse-error->string message)  string?

  message : message?
Converts a parse error to a human-readable string. This is used by parse-result! to format the message used in the exception, but it can also be used if you want to display the error in other ways.

procedure

(parse-result! result)  any/c

  result : (either/c message? any/c)
Extracts a successful parse value from result. If result is a failure, raises exn:fail:read:megaparsack with the failure message converted to a string using parse-error->string.

struct

(struct exn:fail:read:megaparsack exn:fail:read (unexpected
    expected)
    #:transparent)
  unexpected : any/c
  expected : (listof string?)
Raised by parse-result! when given a parse failure.

struct

(struct syntax-box (datum srcloc)
    #:transparent)
  datum : any/c
  srcloc : srcloc?
Represents a single parsable entity. Just like syntax objects, a syntax box associates some source location information with an arbitrary datum. However, unlike ordinary syntax objects, values like lists and vectors can be stored in a syntax box without being recursively wrapped in additional layers of syntax objects.

The datum can be anything at all, but usually it is either a character or some token produced as the result of lexing. It is unlikely that you will need to create syntax-box values yourself; rather, use higher-level functions like parse-string that create these values for you.

struct

(struct message (srcloc unexpected expected)
    #:transparent)
  srcloc : srcloc?
  unexpected : any/c
  expected : (listof string?)
Represents a parse error. Generally you will not need to construct or use these yourself, since they will be automatically constructed when parsers fail, and you can convert them to a human-readable error message using parse-error->string. For more complicated use cases, though, you may want to raise custom parse errors using fail/p or format your own error messages, so you can use this structure directly.

value

void/p : (parser/c any/c void?)

A parser that always succeeds and always returns #<void>.

procedure

(or/p parser ...+)  parser?

  parser : parser?
Tries each parser in succession until one either succeeds or consumes input, at which point its result will be returned as the result of the overall parse. Parsers that consume input but fail will halt further parsers from being tried and will simply return an error; if backtracking is desired, the parser should be wrapped with try/p.

Changed in version 1.5 of package megaparsack-lib: Changed to always return the first successful result, rather than continuing to try parsers until one consumes input. The new behavior is more predictable and more consistent with existing Parsec implementations, though the old behavior was more consistent with the presentation in the original paper.

procedure

(try/p parser)  parser?

  parser : parser?
Creates a new parser like parser, except that it does not consume input if parser fails. This allows the parser to backtrack and try other alternatives when used inside a or/p combinator.

procedure

(lookahead/p parser)  parser?

  parser : parser?
Creates a new parser like parser, except that it does not consume input if parser succeeds, so subsequent parsers will continue from the same location in the input stream. This allows a parser to ensure something will appear in future input without immediately consuming it.

For example, lookahead/p can be used to implement a parser that only succeeds at the end of a line, but does not consume the newline character itself:

> (define end-of-line/p (lookahead/p (char/p #\newline)))

This can be used to parse, for example, line comments that span to the end of the current line, while still allowing a later parser to consume the newline character:

> (define rest-of-line/p
    (or/p (do end-of-line/p (pure ""))
          (do [c <- any-char/p]
              [cs <- rest-of-line/p]
              (pure (string-append (string c) cs)))))
> (define line-comment/p
    (do (try/p (string/p "# "))
        rest-of-line/p))
> (parse-string (many/p (do [line <- line-comment/p]
                            (char/p #\newline)
                            (pure line)))
                (string-append "# hello\n"
                               "# world\n"))

(success '("hello" "world"))

Note that if parser fails, lookahead/p has no effect; if it consumed input before failing, it will not try other alternatives in an enclosing or/p. Wrap parser with try/p if this behavior is undesirable.

Added in version 1.5 of package megaparsack-lib.

procedure

(satisfy/p proc)  parser?

  proc : (any/c . -> . any/c)
Creates a parser that checks if proc produces a non-#f value when applied to a single datum. If so, it consumes the datum and returns successfully; otherwise, it fails without consuming input.

value

eof/p : (parser/c any/c void?)

A parser that only succeeds when there is no more input left to consume. It always returns #<void>.

procedure

(label/p label parser)  parser?

  label : string?
  parser : parser?
Creates a parser like parser, except that failures are reported in terms of label instead of whatever names would have been used instead.

procedure

(hidden/p parser)  parser?

  parser : parser?
Like label/p, adjusts how failures are reported for parser, but hidden/p completely hides any failure information produced by parser when reporting errors. (This is useful when parsing things like whitespace which are usually not useful to include in error messages.)

procedure

(syntax/p parser)  (parser/c any/c syntax?)

  parser : parser?
Produces a parser like parser, except that its result is wrapped in a syntax object that automatically incorporates source location information from the input stream. This allows parsers to add a sort of automated source location tracking to their output.

The syntax/p combinator makes source location wrapping opt-in, which is desirable since it is often useful to return values from combinators that are intermediate values not intended to be wrapped in syntax (for example, many/p returns a list of results, not a syntax list).

procedure

(syntax-box/p parser)  (parser/c any/c syntax-box?)

  parser : parser?
Like syntax/p, but wraps the result in a syntax-box instead of a syntax object. This is useful if you want to get the source location information from a parse result, but you want to ensure the underlying datum remains untouched.

procedure

(fail/p msg)  (parser/c any/c none/c)

  msg : message?
Produces a parser that always fails and produces msg as the error message. This is the lowest-level way to report errors, but many cases in which you would want to raise a custom failure message can be replaced with guard/p instead, which is slightly higher level.

procedure

(many/p parser    
  [#:sep sep    
  #:min min-count    
  #:max max-count])  (parser/c any/c list?)
  parser : parser?
  sep : parser? = void/p
  min-count : exact-nonnegative-integer? = 0
  max-count : (or/c exact-nonnegative-integer? +inf.0) = +inf.0
Produces a parser that attempts parser at least min-count times and at most max-count times, with attempts separated by sep. The returned parser produces a list of results of successful attempts of parser. Results of sep are ignored.

Examples:
> (define letters/p (many/p letter/p))
> (parse-result! (parse-string letters/p "abc"))

'(#\a #\b #\c)

> (define dotted-letters/p
    (many/p letter/p #:sep (char/p #\.) #:min 2 #:max 4))
> (parse-result! (parse-string dotted-letters/p "a.b.c"))

'(#\a #\b #\c)

> (parse-result! (parse-string dotted-letters/p "abc"))

string:1:1: parse error

  unexpected: b

  expected: '.'

> (parse-result! (parse-string dotted-letters/p "a"))

string:1:0: parse error

  unexpected: end of input

  expected: '.'

> (parse-result! (parse-string dotted-letters/p "a.b.c.d.e"))

'(#\a #\b #\c #\d)

Added in version 1.1 of package megaparsack-lib.

procedure

(many+/p parser [#:sep sep #:max max-count])

  (parser/c any/c list?)
  parser : parser?
  sep : parser? = void/p
  max-count : (or/c exact-nonnegative-integer? +inf.0) = +inf.0
Like many/p, but attempts parser at least once. Equivalent to (many/p parser #:sep sep #:min 1 #:max max-count).

Changed in version 1.1 of package megaparsack-lib: Added support for #:sep and #:max keyword arguments for consistency with many/p.

procedure

(repeat/p n parser)  (parser/c any/c list?)

  n : exact-nonnegative-integer?
  parser : parser?
Produces a parser that attempts parser exactly n times and returns a list of the results. Equivalent to (many/p parser #:min n #:max n).

procedure

(==/p v [=?])  parser?

  v : any/c
  =? : (any/c any/c . -> . any/c) = equal?
Produces a parser that succeeds when a single datum is equal to v, as determined by =?. Like satisfy/p, it consumes a single datum upon success but does not consume anything upon failure.

procedure

(one-of/p vs [=?])  parser?

  vs : list?
  =? : (any/c any/c . -> . any/c) = equal?
Like (or/p (one-of/p v =?) ...). Produces a parser that succeeds when a single datum is equal to any of the elements of vs, as determined by =?. Like satisfy/p, it consumes a single datum upon success but does not consume anything upon failure.

Examples:
> (parse-result! (parse-string (one-of/p '(#\a #\b)) "a"))

#\a

> (parse-result! (parse-string (one-of/p '(#\a #\b)) "b"))

#\b

> (parse-result! (parse-string (one-of/p '(#\a #\b)) "c"))

string:1:0: parse error

  unexpected: c

  expected: a or b

Added in version 1.2 of package megaparsack-lib.

procedure

(guard/p parser    
  pred?    
  [expected    
  make-unexpected])  parser?
  parser : parser?
  pred? : (any/c . -> . any/c)
  expected : (or/c string? #f) = #f
  make-unexpected : (any/c . -> . any/c) = identity
Produces a parser that runs parser, then applies a guard predicate pred? to the result. If the result of pred? is #f, then the parser fails, otherwise the parser succeeds and produces the same result as parser.

If the parser fails and expected is a string, then expected is used to add expected information to the parser error. Additionally, the make-unexpected function is applied to the result of parser to produce the unexpected field of the parse error.

Examples:
> (define small-integer/p
    (guard/p integer/p (λ (x) (<= x 100))
             "integer in range [0,100]"))
> (parse-result! (parse-string small-integer/p "42"))

42

> (parse-result! (parse-string small-integer/p "300"))

string:1:0: parse error

  unexpected: 300

  expected: integer in range [0,100]

procedure

(list/p parser ... [#:sep sep])  (parser/c any? list?)

  parser : parser?
  sep : parser? = void/p
Returns a parser that runs each parser in sequence separated by sep and produces a list containing the results of each parser. The results of sep are ignored.

Examples:
> (define dotted-let-digit-let/p
    (list/p letter/p digit/p letter/p #:sep (char/p #\.)))
> (parse-result! (parse-string dotted-let-digit-let/p "a.1.b"))

'(#\a #\1 #\b)

> (parse-result! (parse-string dotted-let-digit-let/p "a1c"))

string:1:1: parse error

  unexpected: 1

  expected: '.'

> (parse-result! (parse-string dotted-let-digit-let/p "a.1"))

string:1:2: parse error

  unexpected: end of input

  expected: '.'

Using a separator parser that consumes no input (such as the default separator, void/p) is equivalent to not using a separator at all.

Examples:
> (define let-digit-let/p (list/p letter/p digit/p letter/p))
> (parse-result! (parse-string let-digit-let/p "a1b"))

'(#\a #\1 #\b)

5.1.1 Parser Parameters

procedure

(make-parser-parameter v)  parser-parameter?

  v : any/c
Returns a new parser parameter. A parser parameter is like an ordinary parameter, but instead of its state being scoped to a particular thread, a parser parameter’s state is scoped to a particular call to parse. Furthermore, modifications to parser parameters are discarded if the parser backtracks past the point of modification, which ensures that only modifications from successful parse branches are retained.

Like ordinary parameters, parser parameters are procedures that accept zero or one argument. Unlike ordinary parameters, the result of applying a parser parameter procedure is a parser, which must be monadically sequenced with other parsers to have any effect.

Examples:
> (define param (make-parser-parameter #f))
> (parse-result! (parse-string (param) ""))

#f

> (parse-result! (parse-string (do (param #t) (param)) ""))

#t

Each call to parse is executed with a distinct parser parameterization, which means modifications to parser parameters are only visible during that particular parser execution. The v argument passed to make-parser-parameter is used as the created parser parameter’s initial value in each distinct parser parameterization.

Parser parameters are useful for tracking state needed by context-sensitive parsers, but they can also be used to provide values with dynamic extent using parameterize/p, just as ordinary parameters can be locally modified via parameterize.

Added in version 1.4 of package megaparsack-lib.

procedure

(parser-parameter? v)  boolean?

  v : any/c
Returns #t if v is a parser parameter, otherwise returns #f.

Added in version 1.4 of package megaparsack-lib.

syntax

(parameterize/p ([param-expr val-expr] ...) parser-expr)

 
  param-expr : parser-parameter?
  parser-expr : parser?
Returns a new parser that behaves just like parser-expr, except that the value of each parser parameter param-expr is given by the corresponding val-expr during the dynamic extent of the parser’s execution.

Examples:
> (define param (make-parser-parameter #f))
> (parse-result! (parse-string (do [a <- (param)]
                                   [b <- (parameterize/p ([param #t])
                                           (param))]
                                   [c <- (param)]
                                   (pure (list a b c)))
                               ""))

'(#f #t #f)

If any of the param-expr’s values are modified by parser-expr via a direct call to the parser parameter procedure, the value remains modified until control leaves the enclosing parameterize/p parser, after which the value is restored. (This behavior is precisely analogous to modifying an ordinary parameter within the body of a parameterize expression.)

Examples:
> (define param (make-parser-parameter #f))
> (parse-result! (parse-string (do (param 1)
                                   [a <- (parameterize/p ([param 2])
                                           (do (param 3)
                                               (param)))]
                                   [b <- (param)]
                                   (pure (list a b)))
                               ""))

'(3 1)

Added in version 1.4 of package megaparsack-lib.

5.2 Parsing Text

 (require megaparsack/text) package: megaparsack-lib

procedure

(parse-string parser str [src-name])  (either/c message? any/c)

  parser : (parser/c char? any/c)
  str : string?
  src-name : any/c = 'string
Parses str using parser, which must consume character datums. The value provided for src-name is used in error reporting when displaying source location information.

procedure

(parse-syntax-string parser stx-str)  (either/c message? any/c)

  parser : (parser/c char? any/c)
  stx-str : (syntax/c string?)
Like parse-string, but uses the source location information from stx-str to initialize the source location tracking. The result of (syntax-source stx-str) is used in place of the src-name argument.

procedure

(char/p c)  (parser/c char? char?)

  c : char?
Parses a single datum that is equal to c.

procedure

(char-not/p c)  (parser/c char? char?)

  c : char?
Parses a single datum that is different from c.

Added in version 1.3 of package megaparsack-lib.

procedure

(char-ci/p c)  (parser/c char? char?)

  c : char?
Parses a single datum that is case-insensitively equal to c, as determined by char-ci=?.

procedure

(char-between/p low high)  (parser/c char? char?)

  low : char?
  high : char?
Parses a single character that is between low and high according to char<=?.

Examples:
> (parse-result! (parse-string (char-between/p #\a #\z) "d"))

#\d

> (parse-result! (parse-string (char-between/p #\a #\z) "D"))

string:1:0: parse error

  unexpected: D

  expected: a character between 'a' and 'z'

Added in version 1.2 of package megaparsack-lib.

procedure

(char-in/p alphabet)  (parser/c char? char?)

  alphabet : string?
Returns a parser that parses a single character that is in alphabet.

Examples:
> (parse-result! (parse-string (char-in/p "aeiou") "i"))

#\i

> (parse-result! (parse-string (char-in/p "aeiou") "z"))

string:1:0: parse error

  unexpected: z

  expected: 'a', 'e', 'i', 'o', or 'u'

Added in version 1.2 of package megaparsack-lib.

procedure

(char-not-in/p alphabet)  (parser/c char? char?)

  alphabet : string?
Returns a parser that parses a single character that is not in alphabet.

Added in version 1.3 of package megaparsack-lib.

Returns a parser that parses a single character.

Added in version 1.3 of package megaparsack-lib.

Parses an alphabetic letter, as determined by char-alphabetic?.

Parses a single digit, as determined by char-numeric?.

Parses a symbolic character, as determined by char-symbolic?.

Parses a single whitespace character, as determined by char-whitespace? or char-blank?.

Parses a sequence of digits as an integer. Does not handle negative numbers or numeric separators.

procedure

(string/p str)  (parser/c char? string?)

  str : string?
Parses a sequence of characters that is case-insensitively equal to str and returns str as its result.

procedure

(string-ci/p str)  (parser/c char? string?)

  str : string?
Parses a sequence of characters equal to str (as determined by char-ci=?) and returns str as its result.

Added in version 1.3 of package megaparsack-lib.

5.3 Parsing with parser-tools/lex

 (require megaparsack/parser-tools/lex)
  package: megaparsack-parser-tools

Sometimes it is useful to run a lexing pass over an input stream before parsing, in which case megaparsack/text is not appropriate. The parser-tools package provides the parser-tools/lex library, which implements a lexer that produces tokens.

When using parser-tools/lex, use lexer-src-pos instead of lexer to enable the built-in source location tracking. This will produce a sequence of position-token elements, which can then be passed to parse-tokens and detected with token/p.

procedure

(parse-tokens parser tokens [source-name])  syntax?

  parser : parser?
  tokens : (listof position-token?)
  source-name : any/c = 'tokens
Parses a stream of tokens, tokens, produced from lexer-src-pos from parser-tools/lex.

procedure

(token/p name)  (parser/c (or/c symbol? token?) any/c)

  name : symbol?
Produces a parser that expects a single token with name, as produced by token-name.

5.4 Deprecated Forms and Functions

procedure

(many*/p parser)  (parser/c list?)

  parser : parser?

NOTE: This function is deprecated; use many/p, instead.

procedure

(many/sep*/p parser sep)  parser?

  parser : parser?
  sep : parser?

NOTE: This function is deprecated; use (many/p parser #:sep sep), instead.

procedure

(many/sep+/p parser sep)  parser?

  parser : parser?
  sep : parser?

NOTE: This function is deprecated; use (many+/p parser #:sep sep), instead.