1 Quick Start
A Parser turns a string into a Value. The constructors given to seq and seq* decide what that Value is, so a grammar can compute the data the program needs while it parses.
Take numbers such as "0", "-7", and "140". A number is an optional minus sign followed by either a lone zero or a non-zero digit and any number of further digits. ZERO and NONZERO-DIGIT use string->number as their constructor, so the digit parsers produce each digit’s value instead of its text:
(require parser-combinator/parse) ; Parser ; matches the digit 0, producing its value (define-parser ZERO (seq* string->number (lit "0"))) ; Parser ; matches a digit 1 through 9, producing its value (define-parser NONZERO-DIGIT (seq* string->number (rx #rx"[1-9]"))) ; Parser ; matches any digit, producing its value (define-parser DIGIT (alt ZERO NONZERO-DIGIT))
A natural number other than zero starts with a non-zero digit, and foldl adds the digits after it from left to right. A missing sign is '(), and a minus sign negates the number:
; Natural Natural -> Natural ; adds the digit d to the end of n (define (add-digit d n) (+ (* 10 n) d)) ; Parser ; matches a natural number, producing its value (define-parser NATURAL (alt ZERO (seq (lambda (d ds) (foldl add-digit d ds)) NONZERO-DIGIT (star DIGIT)))) ; Parser ; matches an integer, producing its value (define-parser NUMBER (seq (lambda (sign n) (if (null? sign) n (- n))) (opt (lit "-")) NATURAL))
Running a parser with parse produces the number:
> (parse NUMBER "0") 0
> (parse NUMBER "-7") -7
> (parse NUMBER "140") 140
Input that is not in the grammar is an error:
> (parse NUMBER "007") bad input, had leftover text "07"
The source of parser-combinator/json builds its data the same way, for a larger grammar.