Parsers combinator implementation functions.
Although these functions can be used directly, the namespace
crustimoney.combinator-grammar
offers a far better API. The most
extensive documentation for the each of the combinators can be found
there as well.
If you want to implement your own parser combinator though, read on.
Each combinator here receives at least one argument, a property map. The rest of the arguments are the child parsers.
The parsers returned by the combinators do not call other parsers
directly, as this could lead to stack overflows. So next to a
->success
or ->error
result, it can also return a ->push
result. This pushes another parser onto the virtual stack.
For this reason, a parser function has the following signature:
(fn
([text index]
...)
([text index result state]
...))
The 2-arity variant is called when the parser was pushed onto the
stack. It receives the entire text and the index it should begin
parsing. If it returns a push
result, the 4-arity variant is
called when that parser is done. It again receives the text and the
original index, but also the result of the pushed parser and any
state that was pushed with it.
Both arities can return a success, a set of errors, or a push. The
crustimoney.results
namespace should be used for creating and
reading these results.
Before you write your own combinator, do realise that the provided combinators are complete in the sense that they can parse any text.
Parsers combinator implementation functions. Although these functions can be used directly, the namespace `crustimoney.combinator-grammar` offers a far better API. The most extensive documentation for the each of the combinators can be found there as well. If you want to implement your own parser combinator though, read on. Each combinator here receives at least one argument, a property map. The rest of the arguments are the child parsers. The parsers returned by the combinators do not call other parsers directly, as this could lead to stack overflows. So next to a `->success` or `->error` result, it can also return a `->push` result. This pushes another parser onto the virtual stack. For this reason, a parser function has the following signature: (fn ([text index] ...) ([text index result state] ...)) The 2-arity variant is called when the parser was pushed onto the stack. It receives the entire text and the index it should begin parsing. If it returns a `push` result, the 4-arity variant is called when that parser is done. It again receives the text and the original index, but also the result of the pushed parser and any state that was pushed with it. Both arities can return a success, a set of errors, or a push. The `crustimoney.results` namespace should be used for creating and reading these results. Before you write your own combinator, do realise that the provided combinators are complete in the sense that they can parse any text.
(chain _ & parsers)
Chain multiple consecutive parsers.
Chain multiple consecutive parsers.
(choice _ & parsers)
Match the first of the ordered parsers that is successful.
Match the first of the ordered parsers that is successful.
(eof _)
Succeed only if the entire text has been parsed.
Succeed only if the entire text has been parsed.
(literal {:keys [text]})
A parser that matches an exact literal string.
A parser that matches an exact literal string.
(lookahead _ parser)
Lookahead for the given parser, i.e. succeed if the parser does, without advancing the parsing position.
Lookahead for the given parser, i.e. succeed if the parser does, without advancing the parsing position.
(maybe _ parser)
Try to parse the given parser, but succeed anyway.
Try to parse the given parser, but succeed anyway.
(negate _ parser)
Negative lookahead for the given parser, i.e. this succeeds if the parser does not.
Negative lookahead for the given parser, i.e. this succeeds if the parser does not.
(ref {:keys [to]})
Refer to another parser, by its key in a recursive grammar. Only
valid inside a with-scope
, for example:
(with-scope
{:foo (literal {:text "foo"})
:root (ref {:to :foo})})
The ref
is now bound to the referred parser. Updating the map does
not update the binding!
Refer to another parser, by its key in a recursive grammar. Only valid inside a `with-scope`, for example: (with-scope {:foo (literal {:text "foo"}) :root (ref {:to :foo})}) The `ref` is now bound to the referred parser. Updating the map does not update the binding!
(regex {:keys [pattern]})
A parser that matches the given regular expression (string or pattern).
A parser that matches the given regular expression (string or pattern).
(repeat* _ parser)
Eagerly try to match the given parser as many times as possible.
Eagerly try to match the given parser as many times as possible.
(repeat+ _ parser)
Eagerly try to match the parser as many times as possible, expecting at least one match.
Eagerly try to match the parser as many times as possible, expecting at least one match.
(with-error {:keys [key]} parser)
Wrap the parser, replacing any errors with a single error with the supplied error key.
Wrap the parser, replacing any errors with a single error with the supplied error key.
(with-name {:keys [key]} parser)
Wrap the parser, assigning a name to the (success) result of the parser. Nameless parsers are filtered out by default during parsing.
Wrap the parser, assigning a name to the (success) result of the parser. Nameless parsers are filtered out by default during parsing.
(with-scope & body)
Takes a grammar map, defining a scope for the ref
function. Returns
the same map, where ref
s have been bound. Updating the map
afterwards does not update the ref
bindings!
As with any recursive grammar, you can auto-capture a rule by adding
the =
postfix to its name.
Throws an error when a ref
points to a non-existent rule.
Scopes can be nested, applying lexical scoping for the ref
s.
Takes a grammar map, defining a scope for the `ref` function. Returns the same map, where `ref`s have been bound. Updating the map afterwards does not update the `ref` bindings! As with any recursive grammar, you can auto-capture a rule by adding the `=` postfix to its name. Throws an error when a `ref` points to a non-existent rule. Scopes can be nested, applying lexical scoping for the `ref`s.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close