Unified scanlet-parselet Pratt parser.
The engine reads directly from a source string. The grammar spec defines everything language-specific: character dispatch (scanlets), trivia classification, prefix parselets (nud), and postfix rules (led).
A scanlet is (fn [engine] → CST node). It consumes characters from the source string using engine primitives and produces a CST node.
Grammar spec shape: {:nud {char → scanlet-fn} :nud-pred [[pred scanlet-fn] ...] :trivia {char → trivia-consumer-fn} :trivia-pred [[pred trivia-consumer-fn] ...] :led [{:char c :bp n :when pred :fn scanlet-fn} ...]}
Parselet factories (nud-atom, nud-prefix, nud-delimited, etc.) generate common patterns. Custom parselets are plain functions.
Unified scanlet-parselet Pratt parser.
The engine reads directly from a source string. The grammar spec defines
everything language-specific: character dispatch (scanlets), trivia
classification, prefix parselets (nud), and postfix rules (led).
A scanlet is (fn [engine] → CST node). It consumes characters from the
source string using engine primitives and produces a CST node.
Grammar spec shape:
{:nud {char → scanlet-fn}
:nud-pred [[pred scanlet-fn] ...]
:trivia {char → trivia-consumer-fn}
:trivia-pred [[pred trivia-consumer-fn] ...]
:led [{:char c :bp n :when pred :fn scanlet-fn} ...]}
Parselet factories (nud-atom, nud-prefix, nud-delimited, etc.) generate
common patterns. Custom parselets are plain functions.(advance! engine n)Move cursor forward by n characters.
Move cursor forward by n characters.
(cursor engine)Current cursor position in source.
Current cursor position in source.
(eof? engine)Is cursor at or past end of source?
Is cursor at or past end of source?
(expect-close! engine close-char close-type)If the current character matches close-char, consume it and return a close token of the given type. Otherwise return nil (unclosed delimiter).
If the current character matches close-char, consume it and return a close token of the given type. Otherwise return nil (unclosed delimiter).
(led-call node-type close-char close-type)Factory: call parselet (head + delimited args).
Factory: call parselet (head + delimited args).
(led-infix node-type)(led-infix node-type right-bp)Factory: binary infix parselet.
Factory: binary infix parselet.
(make-token! engine type start)Produce a token map covering [start, cursor). Drains trivia-acc and attaches as :trivia/before. Token shape is identical to the legacy tokenizer output.
Produce a token map covering [start, cursor). Drains trivia-acc and attaches as :trivia/before. Token shape is identical to the legacy tokenizer output.
(make-trivia-token! engine type start)Produce a trivia token covering [start, cursor). Does NOT drain trivia-acc. Used by trivia consumers — the token is pushed onto trivia-acc by skip-trivia!.
Produce a trivia token covering [start, cursor). Does NOT drain trivia-acc. Used by trivia consumers — the token is pushed onto trivia-acc by skip-trivia!.
(nud-atom _node-type)Factory: atom parselet (leaf node, no operands).
Factory: atom parselet (leaf node, no operands).
(nud-delimited node-type close-char close-type)Factory: delimited parselet (consume children until close char).
Factory: delimited parselet (consume children until close char).
(nud-empty-or-error empty-node-type close-char close-type error-message)Factory: empty-or-error parselet (empty list or bare parens error).
Factory: empty-or-error parselet (empty list or bare parens error).
(nud-prefix node-type)(nud-prefix node-type bp)Factory: prefix parselet (consume 1 operand).
Factory: prefix parselet (consume 1 operand).
(nud-prefix-two node-type first-key second-key)(nud-prefix-two node-type first-key second-key bp)Factory: prefix parselet consuming 2 operands (e.g., metadata).
Factory: prefix parselet consuming 2 operands (e.g., metadata).
(nud-prefixed-delimited node-type open-char open-type close-char close-type)(nud-prefixed-delimited node-type
open-char
open-type
close-char
close-type
extra-fn)Factory: prefixed-delimited parselet (prefix token + delimited body). extra-fn: optional (fn [prefix-tok] → extra-fields-map).
Factory: prefixed-delimited parselet (prefix token + delimited body). extra-fn: optional (fn [prefix-tok] → extra-fields-map).
(parse source spec)Parse a source string into a vector of CST nodes using the given grammar spec.
Parse a source string into a vector of CST nodes using the given grammar spec.
(parse-expr engine min-bp)Parse one expression at the given minimum binding power.
Parse one expression at the given minimum binding power.
(parse-until engine close-char close-type)Parse expressions until a closing character. Returns [nodes close-tok]. close-tok is nil if EOF is reached before the close character.
Parse expressions until a closing character. Returns [nodes close-tok]. close-tok is nil if EOF is reached before the close character.
(peek-char engine)(peek-char engine offset)Character at cursor, or nil if at EOF.
Character at cursor, or nil if at EOF.
(pos-at engine offset)Compute {:line :col} for a character offset. Line/col are 1-indexed.
Compute {:line :col} for a character offset. Line/col are 1-indexed.
(set-pos! engine pos)Set cursor to an absolute position.
Set cursor to an absolute position.
(skip-trivia! engine)Consume trivia characters, accumulating trivia tokens in trivia-acc. A trivia consumer may return nil to signal no match (e.g., BOM not at position 0). In that case, stop the trivia loop.
Consume trivia characters, accumulating trivia tokens in trivia-acc. A trivia consumer may return nil to signal no match (e.g., BOM not at position 0). In that case, stop the trivia loop.
(source-len engine)Length of source string.
Length of source string.
(source-str engine)The full source string.
The full source string.
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 |