All symbols are in parseus.core.
Result contract: every parser is a function String → [value rest] on success, [] on failure.
parse(parse p s) → result
Applies parser p to string s. Returns [value remaining] or [].
p-satisfy(p-satisfy pred)
Matches a single character satisfying pred. Fails on empty input or when the predicate returns false. Foundation for all character-level parsers.
(parse (p-satisfy #(Character/isUpperCase %)) "Hello") ;=> [\H "ello"]
(parse (p-satisfy #(Character/isUpperCase %)) "hello") ;=> []
p-char(p-char) ; matches any single character
(p-char c) ; matches the specific character c
Returns the matched Character and the remaining string.
(parse (p-char \a) "abc") ;=> [\a "bc"]
(parse (p-char \a) "xyz") ;=> []
(parse (p-char) "xyz") ;=> [\x "yz"]
p-digit(p-digit) ; matches any digit 0–9
(p-digit n) ; matches only the digit n (Integer)
Returns the matched digit as an Integer.
(parse (p-digit) "9 foo") ;=> [9 " foo"]
(parse (p-digit 3) "3 foo") ;=> [3 " foo"]
(parse (p-digit 3) "9 foo") ;=> []
p-any-of(p-any-of chars)
Matches a single character that is a member of chars.
(parse (p-any-of [\a \e \i \o \u]) "apricot") ;=> [\a "pricot"]
(parse (p-any-of [\a \e \i \o \u]) "fruit") ;=> []
p-none-of(p-none-of chars)
Matches a single character that is not in chars.
(parse (p-none-of [\, \;]) "abc,") ;=> [\a "bc,"]
(parse (p-none-of [\, \;]) ",abc") ;=> []
p-eofp-eof
Succeeds only at end of input, returning [nil ""]. Use to assert a complete parse.
(parse p-eof "") ;=> [nil ""]
(parse p-eof "abc") ;=> []
p-or(p-or p1 p2)
Ordered alternation. Tries p1; if it fails, tries p2 on the same input (implicit backtrack).
(parse (p-or (p-digit) (p-char \x)) "x!") ;=> [\x "!"]
(parse (p-or (p-digit) (p-char \x)) "5!") ;=> [5 "!"]
(parse (p-or (p-digit) (p-char \x)) "y!") ;=> []
p-some(p-some p)
Zero-or-more repetition (EBNF { }). Always succeeds. Returns [[:none] rest] on zero matches; [[v1 v2 ...] rest] otherwise. Use some-value to normalise.
(parse (p-some (p-digit)) "123x") ;=> [[1 2 3] "x"]
(parse (p-some (p-digit)) "x") ;=> [[:none] "x"]
p-many(p-many p)
One-or-more repetition. Like p-some but fails when zero matches occur.
(parse (p-many (p-digit)) "123x") ;=> [(1 2 3) "x"]
(parse (p-many (p-digit)) "x") ;=> []
p-optional(p-optional p)
Runs p; if it fails returns [nil rest] instead of []. Never fails.
(parse (p-optional (p-char \-)) "-42") ;=> [\- "42"]
(parse (p-optional (p-char \-)) "42") ;=> [nil "42"]
p-seq(p-seq expr* (return value))
Sequences multiple parsers left-to-right. Short-circuits on the first failure. Bind intermediate results with :=; a step without := runs for effect only.
(:= name parser) ; bind result of parser to name
(return expr) ; produce expr as the result of the whole p-seq
(parse (p-seq (:= a (p-digit))
(p-char \-)
(:= b (p-digit))
(return (+ a b)))
"3-7done")
;=> [10 "done"]
p-collect(p-collect p1 p2 ...)
Runs each parser in sequence and collects all results into a vector. Fails if any parser fails.
(parse (p-collect (p-char \c) (p-char \+) (p-char \+)) "c++ rocks")
;=> [[\c \+ \+] " rocks"]
p-str(p-str s)
Matches the literal string s character by character, returning a vector of matched characters. Use str-value to convert back to a string.
(parse (p-str "if") "if (x)") ;=> [[\i \f] " (x)"]
(str-value (first *1)) ;=> "if"
p-keyword(p-keyword kw)
Like p-str but asserts the next character is not a letter or digit. Prevents "if" from matching the prefix of "iffy".
(parse (p-keyword "if") "if (x)") ;=> ["if" " (x)"]
(parse (p-keyword "if") "iffy") ;=> []
p-between(p-between open close p)
Runs open, then p, then close; returns the result of p.
(parse (p-between (p-char \() (p-char \)) (p-many (p-digit))) "(123)rest")
;=> [(1 2 3) "rest"]
p-sep-by1(p-sep-by1 p sep)
Parses one-or-more occurrences of p separated by sep. Returns a seq of parsed values.
(parse (p-sep-by1 (p-many (p-digit)) (p-char \,)) "1,22,333end")
;=> [((1) (2 2) (3 3 3)) "end"]
p-sep-by(p-sep-by p sep)
Like p-sep-by1 but zero-or-more. Returns [[] rest] when nothing matches.
(parse (p-sep-by (p-digit) (p-char \,)) "1,2,3rest") ;=> [(1 2 3) "rest"]
(parse (p-sep-by (p-digit) (p-char \,)) "rest") ;=> [[] "rest"]
p-chain-left(p-chain-left p op)
Parses p (op p)* and folds results left-associatively. op must return a two-argument function.
; 10 - 3 - 2 = (10-3)-2 = 5
(parse (p-chain-left p-num (p-fmap {\- -} (p-char \-))) "10-3-2")
;=> [5 ""]
p-chain-right(p-chain-right p op)
Like p-chain-left but folds right-associatively.
; 1 - 2 - 3 = 1-(2-3) = 2
(parse (p-chain-right p-num (p-fmap {\- -} (p-char \-))) "1-2-3")
;=> [2 ""]
p-look-ahead(p-look-ahead p)
Runs p and returns its result but does not consume any input.
(parse (p-look-ahead (p-digit)) "3abc") ;=> [3 "3abc"]
p-not-followed-by(p-not-followed-by p)
Succeeds (returning [nil rest]) if p would fail at the current position; consumes nothing. Used to assert a boundary.
(parse (p-not-followed-by (p-digit)) "abc") ;=> [nil "abc"]
(parse (p-not-followed-by (p-digit)) "3abc") ;=> []
p-skip(p-skip p)
Runs p and discards its value, returning [nil rest]. Propagates failure.
(parse (p-seq (p-skip (p-char \())
(:= n (p-digit))
(p-skip (p-char \)))
(return n))
"(7)rest")
;=> [7 "rest"]
p-whitespacep-whitespace
Skips zero-or-more whitespace characters (space, tab, newline). Always succeeds.
(parse p-whitespace " abc") ;=> [... "abc"]
(parse p-whitespace "abc") ;=> [... "abc"]
p-token(p-token p)
Skips leading whitespace then runs p. Use to wrap every terminal in a whitespace-insensitive grammar.
(parse (p-token (p-many (p-digit))) " 42rest") ;=> [[4 2] "rest"]
p-commentp-comment
Skips a (* ... *) comment, including nested comments. Returns [nil rest].
(parse p-comment "(* hello (* nested *) world *)rest")
;=> [nil "rest"]
p-fmap(p-fmap f p)
fmap for parsers. Applies f to the parsed value on success; propagates failure unchanged.
(parse (p-fmap #(* % 10) (p-digit)) "3abc") ;=> [30 "abc"]
(parse (p-fmap str-value (p-many (p-char))) "hi!") ;=> ["hi!" ""]
p-ref(p-ref v)
Macro. Wraps a declared var so it is resolved lazily at parse time rather than at definition time. Required for mutually recursive parsers.
(declare p-expr)
(def p-atom
(p-or (p-between (p-char \() (p-char \)) (p-ref p-expr))
(p-fmap num-value (p-many (p-digit)))))
(def p-expr
(p-chain-left p-atom (p-fmap {\+ +} (p-char \+))))
fail?(fail? result) → boolean
Returns true when result is [] (a failed parse).
some-value(some-value sm) → seq-or-[]
Unwraps a p-some result. Converts the zero-match sentinel [:none] to [].
(some-value [1 2 3]) ;=> [1 2 3]
(some-value [:none]) ;=> []
num-value(num-value digit-list) → Integer
Converts a list of digit integers (as returned by p-digit or p-many/p-some of p-digit) into a single integer.
(num-value [1 2 3]) ;=> 123
(num-value []) ;=> 0
str-value(str-value char-list) → String
Converts a list of characters into a string.
(str-value [\h \i]) ;=> "hi"
(str-value []) ;=> ""
(def p-number
(p-fmap num-value (p-many (p-digit))))
(def p-word
(p-fmap str-value
(p-many (p-satisfy #(Character/isLetter %)))))
(def p-ident
(p-seq (:= first-char (p-satisfy #(Character/isLetter %)))
(:= rest (p-some (p-satisfy #(Character/isLetterOrDigit %))))
(return (str-value (cons first-char (some-value rest))))))
(p-sep-by1 p-number (p-token (p-char \,)))
(p-between (p-token (p-char \())
(p-token (p-char \)))
p-expr)
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |