mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
48 lines
72 KiB
HTML
48 lines
72 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>CCParse (containers.CCParse)</title><link rel="stylesheet" href="../../_odoc-theme/odoc.css"/><meta charset="utf-8"/><meta name="generator" content="odoc 2.3.1"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><script src="../../highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body class="odoc"><nav class="odoc-nav"><a href="../index.html">Up</a> – <a href="../index.html">containers</a> » CCParse</nav><header class="odoc-preamble"><h1>Module <code><span>CCParse</span></code></h1><p>Very Simple Parser Combinators</p><p>These combinators can be used to write very simple parsers, for example to extract data from a line-oriented file, or as a replacement to <code>Scanf</code>.</p></header><nav class="odoc-toc"><ul><li><a href="#a-few-examples">A few examples</a><ul><li><a href="#parse-a-tree">Parse a tree</a></li><li><a href="#parse-a-list-of-words">Parse a list of words</a></li><li><a href="#stress-test">Stress Test</a></li></ul></li><li><a href="#stability-guarantees">Stability guarantees</a></li><li><a href="#input">Input</a></li><li><a href="#combinators">Combinators</a></li><li><a href="#infix">Infix</a></li><li><a href="#parse-input">Parse input</a></li></ul></nav><div class="odoc-content"><h3 id="a-few-examples"><a href="#a-few-examples" class="anchor"></a>A few examples</h3><p>Some more advanced example(s) can be found in the <code>/examples</code> directory.</p><h5 id="parse-a-tree"><a href="#parse-a-tree" class="anchor"></a>Parse a tree</h5><pre class="language-ocaml"><code>open CCParse;;
|
||
|
||
type tree = L of int | N of tree * tree;;
|
||
|
||
let mk_leaf x = L x
|
||
let mk_node x y = N(x,y)
|
||
|
||
let ptree = fix @@ fun self ->
|
||
skip_space *>
|
||
( (char '(' *> (pure mk_node <*> self <*> self) <* char ')')
|
||
<|>
|
||
(U.int >|= mk_leaf) )
|
||
;;
|
||
|
||
parse_string_exn ptree "(1 (2 3))" ;;
|
||
parse_string_exn ptree "((1 2) (3 (4 5)))" ;;</code></pre><h5 id="parse-a-list-of-words"><a href="#parse-a-list-of-words" class="anchor"></a>Parse a list of words</h5><pre class="language-ocaml"><code>open Containers.Parse;;
|
||
let p = U.list ~sep:"," U.word;;
|
||
parse_string_exn p "[abc , de, hello ,world ]";;</code></pre><h5 id="stress-test"><a href="#stress-test" class="anchor"></a>Stress Test</h5><p>This makes a list of 100_000 integers, prints it and parses it back.</p><pre class="language-ocaml"><code>let p = CCParse.(U.list ~sep:"," U.int);;
|
||
|
||
let l = CCList.(1 -- 100_000);;
|
||
let l_printed =
|
||
CCFormat.(to_string (within "[" "]" (list ~sep:(return ",@,") int))) l;;
|
||
|
||
let l' = CCParse.parse_string_exn p l_printed;;
|
||
|
||
assert (l=l');;</code></pre><h3 id="stability-guarantees"><a href="#stability-guarantees" class="anchor"></a>Stability guarantees</h3><p>Some functions are marked "experimental" and are still subject to change.</p><div class="odoc-spec"><div class="spec type anchored" id="type-position"><a href="#type-position" class="anchor"></a><code><span><span class="keyword">type</span> position</span></code></div><div class="spec-doc"><p>A position in the input. Typically it'll point at the <b>beginning</b> of an error location.</p></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Position"><a href="#module-Position" class="anchor"></a><code><span><span class="keyword">module</span> <a href="Position/index.html">Position</a></span><span> : <span class="keyword">sig</span> ... <span class="keyword">end</span></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Error"><a href="#module-Error" class="anchor"></a><code><span><span class="keyword">module</span> <a href="Error/index.html">Error</a></span><span> : <span class="keyword">sig</span> ... <span class="keyword">end</span></span></code></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-or_error"><a href="#type-or_error" class="anchor"></a><code><span><span class="keyword">type</span> <span>+'a or_error</span></span><span> = <span><span>(<span class="type-var">'a</span>, <a href="Error/index.html#type-t">Error.t</a>)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p><code>'a or_error</code> is either <code>Ok x</code> for some result <code>x : 'a</code>, or an error <a href="Error/index.html#type-t"><code>Error.t</code></a>.</p><p>See <a href="#val-stringify_result"><code>stringify_result</code></a> and <a href="Error/index.html#val-to_string"><code>Error.to_string</code></a> to print the error message.</p></div></div><div class="odoc-spec"><div class="spec exception anchored" id="exception-ParseError"><a href="#exception-ParseError" class="anchor"></a><code><span><span class="keyword">exception</span> </span><span><span class="exception">ParseError</span> <span class="keyword">of</span> <a href="Error/index.html#type-t">Error.t</a></span></code></div></div><h3 id="input"><a href="#input" class="anchor"></a>Input</h3><h3 id="combinators"><a href="#combinators" class="anchor"></a>Combinators</h3><div class="odoc-spec"><div class="spec type anchored" id="type-t"><a href="#type-t" class="anchor"></a><code><span><span class="keyword">type</span> <span>'a t</span></span></code></div><div class="spec-doc"><p>The abstract type of parsers that return a value of type <code>'a</code> (or fail).</p><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <a href="#exception-ParseError"><code>ParseError</code></a> <p>in case of failure.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6 the type is private.</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-return"><a href="#val-return" class="anchor"></a><code><span><span class="keyword">val</span> return : <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Always succeeds, without consuming its input.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-pure"><a href="#val-pure" class="anchor"></a><code><span><span class="keyword">val</span> pure : <span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Synonym to <a href="#val-return"><code>return</code></a>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-map"><a href="#val-map" class="anchor"></a><code><span><span class="keyword">val</span> map : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-map2"><a href="#val-map2" class="anchor"></a><code><span><span class="keyword">val</span> map2 : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span class="type-var">'c</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'c</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-map3"><a href="#val-map3" class="anchor"></a><code><span><span class="keyword">val</span> map3 : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <span class="arrow">-></span></span> <span><span class="type-var">'c</span> <span class="arrow">-></span></span> <span class="type-var">'d</span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'c</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'d</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-bind"><a href="#val-bind" class="anchor"></a><code><span><span class="keyword">val</span> bind : <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>bind f p</code> results in a new parser which behaves as <code>p</code> then, in case of success, applies <code>f</code> to the result.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-ap"><a href="#val-ap" class="anchor"></a><code><span><span class="keyword">val</span> ap : <span><span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Applicative.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-eoi"><a href="#val-eoi" class="anchor"></a><code><span><span class="keyword">val</span> eoi : <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Expect the end of input, fails otherwise.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-empty"><a href="#val-empty" class="anchor"></a><code><span><span class="keyword">val</span> empty : <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Succeed with <code>()</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fail"><a href="#val-fail" class="anchor"></a><code><span><span class="keyword">val</span> fail : <span>string <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>fail msg</code> fails with the given message. It can trigger a backtrack.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-failf"><a href="#val-failf" class="anchor"></a><code><span><span class="keyword">val</span> failf : <span><span><span>(<span class="type-var">'a</span>, unit, string, <span><span class="type-var">'b</span> <a href="#type-t">t</a></span>)</span> <a href="../../ocaml/Stdlib/index.html#type-format4">format4</a></span> <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p><code>Format.sprintf</code> version of <a href="#val-fail"><code>fail</code></a>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fail_lazy"><a href="#val-fail_lazy" class="anchor"></a><code><span><span class="keyword">val</span> fail_lazy : <span><span>(<span>unit <span class="arrow">-></span></span> string)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Like <a href="#val-fail"><code>fail</code></a>, but only produce an error message on demand.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parsing"><a href="#val-parsing" class="anchor"></a><code><span><span class="keyword">val</span> parsing : <span>string <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>parsing s p</code> behaves the same as <code>p</code>, with the information that we are parsing <code>s</code>, if <code>p</code> fails. The message <code>s</code> is added to the error, it does not replace it, not does the location change (the error still points to the same location as in <code>p</code>).</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-set_error_message"><a href="#val-set_error_message" class="anchor"></a><code><span><span class="keyword">val</span> set_error_message : <span>string <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>set_error_message msg p</code> behaves like <code>p</code>, but if <code>p</code> fails, <code>set_error_message msg p</code> fails with <code>msg</code> instead and at the current position. The internal error message of <code>p</code> is just discarded.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-pos"><a href="#val-pos" class="anchor"></a><code><span><span class="keyword">val</span> pos : <span><a href="#type-position">position</a> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>pos</code> returns the current position in the buffer.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.7</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-with_pos"><a href="#val-with_pos" class="anchor"></a><code><span><span class="keyword">val</span> with_pos : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <a href="#type-position">position</a>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>with_pos p</code> behaves like <code>p</code>, but returns the (starting) position along with <code>p</code>'s result.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-any_char"><a href="#val-any_char" class="anchor"></a><code><span><span class="keyword">val</span> any_char : <span>char <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>any_char</code> parses any character. It still fails if the end of input was reached.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-any_char_n"><a href="#val-any_char_n" class="anchor"></a><code><span><span class="keyword">val</span> any_char_n : <span>int <span class="arrow">-></span></span> <span>string <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>any_char_n len</code> parses exactly <code>len</code> characters from the input. Fails if the input doesn't contain at least <code>len</code> chars.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-char"><a href="#val-char" class="anchor"></a><code><span><span class="keyword">val</span> char : <span>char <span class="arrow">-></span></span> <span>char <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>char c</code> parses the character <code>c</code> and nothing else.</p></div></div><div class="odoc-spec"><div class="spec type anchored" id="type-slice"><a href="#type-slice" class="anchor"></a><code><span><span class="keyword">type</span> slice</span></code></div><div class="spec-doc"><p>A slice of the input, as returned by some combinators such as <a href="#val-split_1"><code>split_1</code></a> or <a href="#val-split_list"><code>split_list</code></a> or <a href="#val-take"><code>take</code></a>.</p><p>The idea is that one can use some parsers to cut the input into slices, e.g. split into lines, or split a line into fields (think CSV or TSV). Then a variety of parsers can be used on each slice to extract data from it using <a href="#val-recurse"><code>recurse</code></a>.</p><p>Slices contain enough information to make it possible for <code>recurse slice p</code> to report failures (if <code>p</code> fails) using locations from the original input, not relative to the slice. Therefore, even after splitting the input into lines using, say, <a href="#val-each_line"><code>each_line</code></a>, a failure to parse the 500th line will be reported at line 500 and not at line 1.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Slice"><a href="#module-Slice" class="anchor"></a><code><span><span class="keyword">module</span> <a href="Slice/index.html">Slice</a></span><span> : <span class="keyword">sig</span> ... <span class="keyword">end</span></span></code></div><div class="spec-doc"><p>Functions on slices.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-recurse"><a href="#val-recurse" class="anchor"></a><code><span><span class="keyword">val</span> recurse : <span><a href="#type-slice">slice</a> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>recurse slice p</code> parses the <code>slice</code> (most likely obtained via another combinator, such as <a href="#val-split_1"><code>split_1</code></a> or <a href="#val-split_list"><code>split_list</code></a>), using <code>p</code>.</p><p>The slice contains a position which is used to relocate error messages to their position in the whole input, not just relative to the slice.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-set_current_slice"><a href="#val-set_current_slice" class="anchor"></a><code><span><span class="keyword">val</span> set_current_slice : <span><a href="#type-slice">slice</a> <span class="arrow">-></span></span> <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>set_current_slice slice</code> replaces the parser's state with <code>slice</code>.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-chars_fold"><a href="#val-chars_fold" class="anchor"></a><code><span><span class="keyword">val</span> chars_fold :
|
||
<span><span class="label">f</span>:
|
||
<span>(<span><span class="type-var">'acc</span> <span class="arrow">-></span></span>
|
||
<span>char <span class="arrow">-></span></span>
|
||
<span>[ <span>`Continue of <span class="type-var">'acc</span></span>
|
||
<span><span>| `Consume_and_stop</span> of <span class="type-var">'acc</span></span>
|
||
<span><span>| `Stop</span> of <span class="type-var">'acc</span></span>
|
||
<span><span>| `Fail</span> of string</span> ]</span>)</span> <span class="arrow">-></span></span>
|
||
<span><span class="type-var">'acc</span> <span class="arrow">-></span></span>
|
||
<span><span>(<span class="type-var">'acc</span> * <a href="#type-slice">slice</a>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>chars_fold f acc0</code> folds over characters of the input. Each char <code>c</code> is passed, along with the current accumulator, to <code>f</code>; <code>f</code> can either:</p><ul><li>stop, by returning <code>`Stop acc</code>. In this case the final accumulator <code>acc</code> is returned, and <code>c</code> is not consumed.</li><li>consume char and stop, by returning <code>`Consume_and_stop acc</code>.</li><li>fail, by returning <code>`Fail msg</code>. In this case the parser fails with the given message.</li><li>continue, by returning <code>`Continue acc</code>. The parser continues to the next char with the new accumulator.</li></ul><p>This is a generalization of of <a href="#val-chars_if"><code>chars_if</code></a> that allows one to transform characters on the fly, skip some, handle escape sequences, etc. It can also be useful as a base component for a lexer.</p><ul class="at-tags"><li class="returns"><span class="at-tag">returns</span> <p>a pair of the final accumular, and the slice matched by the fold.</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-chars_fold_transduce"><a href="#val-chars_fold_transduce" class="anchor"></a><code><span><span class="keyword">val</span> chars_fold_transduce :
|
||
<span><span class="label">f</span>:
|
||
<span>(<span><span class="type-var">'acc</span> <span class="arrow">-></span></span>
|
||
<span>char <span class="arrow">-></span></span>
|
||
<span>[ <span>`Continue of <span class="type-var">'acc</span></span>
|
||
<span><span>| `Yield</span> of <span class="type-var">'acc</span> * char</span>
|
||
<span>| `Consume_and_stop</span>
|
||
<span>| `Stop</span>
|
||
<span><span>| `Fail</span> of string</span> ]</span>)</span> <span class="arrow">-></span></span>
|
||
<span><span class="type-var">'acc</span> <span class="arrow">-></span></span>
|
||
<span><span>(<span class="type-var">'acc</span> * string)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Same as <a href="#val-chars_fold"><code>chars_fold</code></a> but with the following differences:</p><ul><li>returns a string along with the accumulator, rather than the slice of all the characters accepted by <code>`Continue _</code>. The string is built from characters returned by <code>`Yield</code>.</li><li>new case <code>`Yield (acc, c)</code> adds <code>c</code> to the returned string and continues parsing with <code>acc</code>.</li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take_until_success"><a href="#val-take_until_success" class="anchor"></a><code><span><span class="keyword">val</span> take_until_success : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<a href="#type-slice">slice</a> * <span class="type-var">'a</span>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>take_until_success p</code> accumulates characters of the input into a slice, until <code>p</code> successfully parses a value <code>x</code>; then it returns <code>slice, x</code>.</p><p><b>NOTE</b> performance wise, if <code>p</code> does a lot of work at each position, this can be costly (thing naive substring search if <code>p</code> is <code>string "very long needle"</code>).</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.12</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take"><a href="#val-take" class="anchor"></a><code><span><span class="keyword">val</span> take : <span>int <span class="arrow">-></span></span> <span><a href="#type-slice">slice</a> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>take len</code> parses exactly <code>len</code> characters from the input. Fails if the input doesn't contain at least <code>len</code> chars.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take_if"><a href="#val-take_if" class="anchor"></a><code><span><span class="keyword">val</span> take_if : <span><span>(<span>char <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><a href="#type-slice">slice</a> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>take_if f</code> takes characters as long as they satisfy the predicate <code>f</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-take1_if"><a href="#val-take1_if" class="anchor"></a><code><span><span class="keyword">val</span> take1_if : <span><span class="optlabel">?descr</span>:string <span class="arrow">-></span></span> <span><span>(<span>char <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span><a href="#type-slice">slice</a> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>take1_if f</code> takes characters as long as they satisfy the predicate <code>f</code>. Fails if no character satisfies <code>f</code>.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">descr</span> <p>describes what kind of character was expected, in case of error</p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-char_if"><a href="#val-char_if" class="anchor"></a><code><span><span class="keyword">val</span> char_if : <span><span class="optlabel">?descr</span>:string <span class="arrow">-></span></span> <span><span>(<span>char <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span>char <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>char_if f</code> parses a character <code>c</code> if <code>f c = true</code>. Fails if the next char does not satisfy <code>f</code>.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">descr</span> <p>describes what kind of character was expected, in case of error</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-chars_if"><a href="#val-chars_if" class="anchor"></a><code><span><span class="keyword">val</span> chars_if : <span><span>(<span>char <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span>string <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>chars_if f</code> parses a string of chars that satisfy <code>f</code>. Cannot fail.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-chars1_if"><a href="#val-chars1_if" class="anchor"></a><code><span><span class="keyword">val</span> chars1_if : <span><span class="optlabel">?descr</span>:string <span class="arrow">-></span></span> <span><span>(<span>char <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span>string <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Like <a href="#val-chars_if"><code>chars_if</code></a>, but accepts only non-empty strings. <code>chars1_if p</code> fails if the string accepted by <code>chars_if p</code> is empty. <code>chars1_if p</code> is equivalent to <code>take1_if p >|= Slice.to_string</code>.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">descr</span> <p>describes what kind of character was expected, in case of error</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-endline"><a href="#val-endline" class="anchor"></a><code><span><span class="keyword">val</span> endline : <span>char <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Parse '\n'.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-space"><a href="#val-space" class="anchor"></a><code><span><span class="keyword">val</span> space : <span>char <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Tab or space.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-white"><a href="#val-white" class="anchor"></a><code><span><span class="keyword">val</span> white : <span>char <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Tab or space or newline.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-skip_chars"><a href="#val-skip_chars" class="anchor"></a><code><span><span class="keyword">val</span> skip_chars : <span><span>(<span>char <span class="arrow">-></span></span> bool)</span> <span class="arrow">-></span></span> <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Skip 0 or more chars satisfying the predicate.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-skip_space"><a href="#val-skip_space" class="anchor"></a><code><span><span class="keyword">val</span> skip_space : <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Skip ' ' and '\t'.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-skip_white"><a href="#val-skip_white" class="anchor"></a><code><span><span class="keyword">val</span> skip_white : <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Skip ' ' and '\t' and '\n'.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-is_alpha"><a href="#val-is_alpha" class="anchor"></a><code><span><span class="keyword">val</span> is_alpha : <span>char <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>Is the char a letter?</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-is_num"><a href="#val-is_num" class="anchor"></a><code><span><span class="keyword">val</span> is_num : <span>char <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>Is the char a digit?</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-is_alpha_num"><a href="#val-is_alpha_num" class="anchor"></a><code><span><span class="keyword">val</span> is_alpha_num : <span>char <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>Is the char a letter or a digit?</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-is_space"><a href="#val-is_space" class="anchor"></a><code><span><span class="keyword">val</span> is_space : <span>char <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>True on ' ' and '\t'.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-is_white"><a href="#val-is_white" class="anchor"></a><code><span><span class="keyword">val</span> is_white : <span>char <span class="arrow">-></span></span> bool</span></code></div><div class="spec-doc"><p>True on ' ' and '\t' and '\n'.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-suspend"><a href="#val-suspend" class="anchor"></a><code><span><span class="keyword">val</span> suspend : <span><span>(<span>unit <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>suspend f</code> is the same as <code>f ()</code>, but evaluates <code>f ()</code> only when needed.</p><p>A practical use case is to implement recursive parsers manually, as described in <a href="#val-fix"><code>fix</code></a>. The parser is <code>let rec p () = …</code>, and <code>suspend p</code> can be used in the definition to use <code>p</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-string"><a href="#val-string" class="anchor"></a><code><span><span class="keyword">val</span> string : <span>string <span class="arrow">-></span></span> <span>string <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>string s</code> parses exactly the string <code>s</code>, and nothing else.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-exact"><a href="#val-exact" class="anchor"></a><code><span><span class="keyword">val</span> exact : <span>string <span class="arrow">-></span></span> <span>string <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Alias to <a href="#val-string"><code>string</code></a>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-many"><a href="#val-many" class="anchor"></a><code><span><span class="keyword">val</span> many : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>many p</code> parses <code>p</code> repeatedly, until <code>p</code> fails, and collects the results into a list.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-optional"><a href="#val-optional" class="anchor"></a><code><span><span class="keyword">val</span> optional : <span><span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>optional p</code> tries to parse <code>p</code>, and return <code>()</code> whether it succeeded or failed. Cannot fail itself. It consumes input if <code>p</code> succeeded (as much as <code>p</code> consumed), but consumes not input if <code>p</code> failed.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-try_"><a href="#val-try_" class="anchor"></a><code><span><span class="keyword">val</span> try_ : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>try_ p</code> is just like <code>p</code> (it used to play a role in backtracking semantics but no more).</p><ul class="at-tags"><li class="deprecated"><span class="at-tag">deprecated</span> <p>since 3.6 it can just be removed. See <a href="#val-try_opt"><code>try_opt</code></a> if you want to detect failure.</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-try_opt"><a href="#val-try_opt" class="anchor"></a><code><span><span class="keyword">val</span> try_opt : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> option</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>try_opt p</code> tries to parse using <code>p</code>, and return <code>Some x</code> if <code>p</code> succeeded with <code>x</code> (and consumes what <code>p</code> consumed). Otherwise it returns <code>None</code> and consumes nothing. This cannot fail.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-many_until"><a href="#val-many_until" class="anchor"></a><code><span><span class="keyword">val</span> many_until : <span><span class="label">until</span>:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>many_until ~until p</code> parses as many <code>p</code> as it can until the <code>until</code> parser successfully returns. If <code>p</code> fails before that then <code>many_until ~until p</code> fails as well. Typically <code>until</code> can be a closing ')' or another termination condition, and what is consumed by <code>until</code> is also consumed by <code>many_until ~until p</code>.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-try_or"><a href="#val-try_or" class="anchor"></a><code><span><span class="keyword">val</span> try_or : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="label">f</span>:<span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span class="label">else_</span>:<span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>try_or p1 ~f ~else_:p2</code> attempts to parse <code>x</code> using <code>p1</code>, and then becomes <code>f x</code>. If <code>p1</code> fails, then it becomes <code>p2</code>. This can be useful if <code>f</code> is expensive but only ever works if <code>p1</code> matches (e.g. after an opening parenthesis or some sort of prefix).</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-try_or_l"><a href="#val-try_or_l" class="anchor"></a><code><span><span class="keyword">val</span> try_or_l : <span><span class="optlabel">?msg</span>:string <span class="arrow">-></span></span> <span><span class="optlabel">?else_</span>:<span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span>(<span>unit <a href="#type-t">t</a></span> * <span><span class="type-var">'a</span> <a href="#type-t">t</a></span>)</span> list</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>try_or_l ?else_ l</code> tries each pair <code>(test, p)</code> in order. If the n-th <code>test</code> succeeds, then <code>try_or_l l</code> behaves like n-th <code>p</code>, whether <code>p</code> fails or not. If <code>test</code> consumes input, the state is restored before calling <code>p</code>. If they all fail, and <code>else_</code> is defined, then it behaves like <code>else_</code>. If all fail, and <code>else_</code> is <code>None</code>, then it fails as well.</p><p>This is a performance optimization compared to <a href="#val-(<|>)"><code>(<|>)</code></a>. We commit to a branch if the test succeeds, without backtracking at all. It can also provide better error messages, because failures in the parser will not be reported as failures in <code>try_or_l</code>.</p><p>See <a href="#val-lookahead_ignore"><code>lookahead_ignore</code></a> for a convenient way of writing the test conditions.</p><ul class="at-tags"><li class="parameter"><span class="at-tag">parameter</span> <span class="value">msg</span> <p>error message if all options fail</p><p><b>EXPERIMENTAL</b></p></li></ul><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-or_"><a href="#val-or_" class="anchor"></a><code><span><span class="keyword">val</span> or_ : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>or_ p1 p2</code> tries to parse <code>p1</code>, and if it fails, tries <code>p2</code> from the same position.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-both"><a href="#val-both" class="anchor"></a><code><span><span class="keyword">val</span> both : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>both a b</code> parses <code>a</code>, then <code>b</code>, then returns the pair of their results.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-many1"><a href="#val-many1" class="anchor"></a><code><span><span class="keyword">val</span> many1 : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>many1 p</code> is like <code>many p</code> excepts it fails if the list is empty (i.e. it needs <code>p</code> to succeed at least once).</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-skip"><a href="#val-skip" class="anchor"></a><code><span><span class="keyword">val</span> skip : <span><span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>skip p</code> parses zero or more times <code>p</code> and ignores its result. It is eager, meaning it will continue as long as <code>p</code> succeeds. As soon as <code>p</code> fails, <code>skip p</code> stops consuming any input.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-sep"><a href="#val-sep" class="anchor"></a><code><span><span class="keyword">val</span> sep : <span><span class="label">by</span>:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>sep ~by p</code> parses a list of <code>p</code> separated by <code>by</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-sep_until"><a href="#val-sep_until" class="anchor"></a><code><span><span class="keyword">val</span> sep_until : <span><span class="label">until</span>:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="label">by</span>:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Same as <a href="#val-sep"><code>sep</code></a> but stop when <code>until</code> parses successfully.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-sep1"><a href="#val-sep1" class="anchor"></a><code><span><span class="keyword">val</span> sep1 : <span><span class="label">by</span>:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>sep1 ~by p</code> parses a non empty list of <code>p</code>, separated by <code>by</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-lookahead"><a href="#val-lookahead" class="anchor"></a><code><span><span class="keyword">val</span> lookahead : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>lookahead p</code> behaves like <code>p</code>, except it doesn't consume any input.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-lookahead_ignore"><a href="#val-lookahead_ignore" class="anchor"></a><code><span><span class="keyword">val</span> lookahead_ignore : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>unit <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>lookahead_ignore p</code> tries to parse input with <code>p</code>, and succeeds if <code>p</code> succeeds. However it doesn't consume any input and returns <code>()</code>, so in effect its only use-case is to detect whether <code>p</code> succeeds, e.g. in <a href="#val-try_or_l"><code>try_or_l</code></a>.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fix"><a href="#val-fix" class="anchor"></a><code><span><span class="keyword">val</span> fix : <span><span>(<span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Fixpoint combinator. <code>fix (fun self -> p)</code> is the parser <code>p</code>, in which <code>self</code> refers to the parser <code>p</code> itself (which is useful to parse recursive structures.</p><p>An alternative, manual implementation to <code>let p = fix (fun self -> q)</code> is:</p><pre class="language-ocaml"><code>let rec p () =
|
||
let self = suspend p in
|
||
q</code></pre></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-line"><a href="#val-line" class="anchor"></a><code><span><span class="keyword">val</span> line : <span><a href="#type-slice">slice</a> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Parse a line, <code>'\n'</code> excluded, and position the cursor after the <code>'\n'</code>.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-line_str"><a href="#val-line_str" class="anchor"></a><code><span><span class="keyword">val</span> line_str : <span>string <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>line_str</code> is <code>line >|= Slice.to_string</code>. It parses the next line and turns the slice into a string. The state points to the character immediately after the <code>'\n'</code> character.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-each_line"><a href="#val-each_line" class="anchor"></a><code><span><span class="keyword">val</span> each_line : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>each_line p</code> runs <code>p</code> on each line of the input. <b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-split_1"><a href="#val-split_1" class="anchor"></a><code><span><span class="keyword">val</span> split_1 : <span><span class="label">on_char</span>:char <span class="arrow">-></span></span> <span><span>(<a href="#type-slice">slice</a> * <span><a href="#type-slice">slice</a> option</span>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>split_1 ~on_char</code> looks for <code>on_char</code> in the input, and returns a pair <code>sl1, sl2</code>, where:</p><ul><li><code>sl1</code> is the slice of the input the precedes the first occurrence of <code>on_char</code>, or the whole input if <code>on_char</code> cannot be found. It does not contain <code>on_char</code>.</li><li><code>sl2</code> is the slice that comes after <code>on_char</code>, or <code>None</code> if <code>on_char</code> couldn't be found. It doesn't contain the first occurrence of <code>on_char</code> (if any).</li></ul><p>The parser is now positioned at the end of the input.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-split_list"><a href="#val-split_list" class="anchor"></a><code><span><span class="keyword">val</span> split_list : <span><span class="label">on_char</span>:char <span class="arrow">-></span></span> <span><span><a href="#type-slice">slice</a> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>split_list ~on_char</code> splits the input on all occurrences of <code>on_char</code>, returning a list of slices.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-split_list_at_most"><a href="#val-split_list_at_most" class="anchor"></a><code><span><span class="keyword">val</span> split_list_at_most : <span><span class="label">on_char</span>:char <span class="arrow">-></span></span> <span>int <span class="arrow">-></span></span> <span><span><a href="#type-slice">slice</a> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>split_list_at_most ~on_char n</code> applies <code>split_1 ~on_char</code> at most <code>n</code> times, to get a list of <code>n+1</code> elements. The last element might contain <code>on_char</code>. This is useful to limit the amount of work done by <a href="#val-split_list"><code>split_list</code></a>.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-split_2"><a href="#val-split_2" class="anchor"></a><code><span><span class="keyword">val</span> split_2 : <span><span class="label">on_char</span>:char <span class="arrow">-></span></span> <span><span>(<a href="#type-slice">slice</a> * <a href="#type-slice">slice</a>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>split_2 ~on_char</code> splits the input into exactly 2 fields, and fails if the split yields less or more than 2 items. <b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-split_3"><a href="#val-split_3" class="anchor"></a><code><span><span class="keyword">val</span> split_3 : <span><span class="label">on_char</span>:char <span class="arrow">-></span></span> <span><span>(<a href="#type-slice">slice</a> * <a href="#type-slice">slice</a> * <a href="#type-slice">slice</a>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>See <a href="#val-split_2"><code>split_2</code></a> <b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-split_4"><a href="#val-split_4" class="anchor"></a><code><span><span class="keyword">val</span> split_4 : <span><span class="label">on_char</span>:char <span class="arrow">-></span></span> <span><span>(<a href="#type-slice">slice</a> * <a href="#type-slice">slice</a> * <a href="#type-slice">slice</a> * <a href="#type-slice">slice</a>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>See <a href="#val-split_2"><code>split_2</code></a> <b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-each_split"><a href="#val-each_split" class="anchor"></a><code><span><span class="keyword">val</span> each_split : <span><span class="label">on_char</span>:char <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> list</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>split_list_map ~on_char p</code> uses <code>split_list ~on_char</code> to split the input, then parses each chunk of the input thus obtained using <code>p</code>.</p><p>The difference with <code>sep ~by:(char on_char) p</code> is that <code>sep</code> calls <code>p</code> first, and only tries to find <code>on_char</code> after <code>p</code> returns. While it is more flexible, this technique also means <code>p</code> has to be careful not to consume <code>on_char</code> by error.</p><p>A useful specialization of this is <a href="#val-each_line"><code>each_line</code></a>, which is basically <code>each_split ~on_char:'\n' p</code>.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-all"><a href="#val-all" class="anchor"></a><code><span><span class="keyword">val</span> all : <span><a href="#type-slice">slice</a> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>all</code> returns all the unconsumed input as a slice, and consumes it. Use <a href="Slice/index.html#val-to_string"><code>Slice.to_string</code></a> to turn it into a string.</p><p>Note that <code>lookahead all</code> can be used to <i>peek</i> at the rest of the input without consuming anything.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-all_str"><a href="#val-all_str" class="anchor"></a><code><span><span class="keyword">val</span> all_str : <span>string <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>all_str</code> accepts all the remaining chars and extracts them into a string. Similar to <a href="#val-all"><code>all</code></a> but with a string.</p><p><b>EXPERIMENTAL</b></p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-memo"><a href="#val-memo" class="anchor"></a><code><span><span class="keyword">val</span> memo : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Memoize the parser. <code>memo p</code> will behave like <code>p</code>, but when called in a state (read: position in input) it has already processed, <code>memo p</code> returns a result directly. The implementation uses an underlying hashtable. This can be costly in memory, but improve the run time a lot if there is a lot of backtracking involving <code>p</code>.</p><p>Do not call <a href="#val-memo"><code>memo</code></a> inside other functions, especially with <a href="#val-(>>=)"><code>(>>=)</code></a>, <a href="#val-map"><code>map</code></a>, etc. being so prevalent. Instead the correct way to use it is in a toplevel definition:</p><pre class="language-ocaml"><code>let my_expensive_parser = memo (foo *> bar >>= fun i -> …)</code></pre><p>This function is not thread-safe.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-fix_memo"><a href="#val-fix_memo" class="anchor"></a><code><span><span class="keyword">val</span> fix_memo : <span><span>(<span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Like <a href="#val-fix"><code>fix</code></a>, but the fixpoint is memoized.</p></div></div><h3 id="infix"><a href="#infix" class="anchor"></a>Infix</h3><div class="odoc-spec"><div class="spec module anchored" id="module-Infix"><a href="#module-Infix" class="anchor"></a><code><span><span class="keyword">module</span> <a href="Infix/index.html">Infix</a></span><span> : <span class="keyword">sig</span> ... <span class="keyword">end</span></span></code></div></div><div class="odoc-include"><details open="open"><summary class="spec include"><code><span><span class="keyword">include</span> <span class="keyword">module</span> <span class="keyword">type</span> <span class="keyword">of</span> <a href="Infix/index.html">Infix</a></span></code></summary><div class="odoc-spec"><div class="spec value anchored" id="val-(>|=)"><a href="#val-(>|=)" class="anchor"></a><code><span><span class="keyword">val</span> (>|=) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Alias to <a href="#val-map"><code>map</code></a>. <code>p >|= f</code> parses an item <code>x</code> using <code>p</code>, and returns <code>f x</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-(>>=)"><a href="#val-(>>=)" class="anchor"></a><code><span><span class="keyword">val</span> (>>=) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Alias to <a href="#val-bind"><code>bind</code></a>. <code>p >>= f</code> results in a new parser which behaves as <code>p</code> then, in case of success, applies <code>f</code> to the result.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-(<*>)"><a href="#val-(<*>)" class="anchor"></a><code><span><span class="keyword">val</span> (<*>) : <span><span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Applicative.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-(<*)"><a href="#val-(<*)" class="anchor"></a><code><span><span class="keyword">val</span> (<*) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>a <* b</code> parses <code>a</code> into <code>x</code>, parses <code>b</code> and ignores its result, and returns <code>x</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-(*>)"><a href="#val-(*>)" class="anchor"></a><code><span><span class="keyword">val</span> (*>) : <span><span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>a *> b</code> parses <code>a</code>, then parses <code>b</code> into <code>x</code>, and returns <code>x</code>. The result of <code>a</code> is ignored.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-(<|>)"><a href="#val-(<|>)" class="anchor"></a><code><span><span class="keyword">val</span> (<|>) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Alias to <a href="#val-or_"><code>or_</code></a>.</p><p><code>a <|> b</code> tries to parse <code>a</code>, and if <code>a</code> fails without consuming any input, backtracks and tries to parse <code>b</code>, otherwise it fails as <code>a</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-(<?>)"><a href="#val-(<?>)" class="anchor"></a><code><span><span class="keyword">val</span> (<?>) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>string <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p><code>a <?> msg</code> behaves like <code>a</code>, but if <code>a</code> fails, <code>a <?> msg</code> fails with <code>msg</code> instead. Useful as the last choice in a series of <code><|></code>. For example: <code>a <|> b <|> c <?> "expected one of a, b, c"</code>.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-(|||)"><a href="#val-(|||)" class="anchor"></a><code><span><span class="keyword">val</span> (|||) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span></span></code></div><div class="spec-doc"><p>Alias to <a href="#val-both"><code>both</code></a>. <code>a ||| b</code> parses <code>a</code>, then <code>b</code>, then returns the pair of their results.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-let+"><a href="#val-let+" class="anchor"></a><code><span><span class="keyword">val</span> let+ : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span class="type-var">'b</span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-and+"><a href="#val-and+" class="anchor"></a><code><span><span class="keyword">val</span> and+ : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-let*"><a href="#val-let*" class="anchor"></a><code><span><span class="keyword">val</span> let* : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span><span class="type-var">'a</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span>)</span> <span class="arrow">-></span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span></span></code></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-and*"><a href="#val-and*" class="anchor"></a><code><span><span class="keyword">val</span> and* : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span> * <span class="type-var">'b</span>)</span> <a href="#type-t">t</a></span></span></code></div></div></details></div><h3 id="parse-input"><a href="#parse-input" class="anchor"></a>Parse input</h3><div class="odoc-spec"><div class="spec value anchored" id="val-stringify_result"><a href="#val-stringify_result" class="anchor"></a><code><span><span class="keyword">val</span> stringify_result : <span><span><span class="type-var">'a</span> <a href="#type-or_error">or_error</a></span> <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span>, string)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p>Turn a <a href="Error/index.html#type-t"><code>Error.t</code></a>-oriented result into a more basic string result.</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 3.6</li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse_string"><a href="#val-parse_string" class="anchor"></a><code><span><span class="keyword">val</span> parse_string : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>string <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span>, string)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p>Parse a string using the parser.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse_string_e"><a href="#val-parse_string_e" class="anchor"></a><code><span><span class="keyword">val</span> parse_string_e : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>string <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-or_error">or_error</a></span></span></code></div><div class="spec-doc"><p>Version of <a href="#val-parse_string"><code>parse_string</code></a> that returns a more detailed error.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse_string_exn"><a href="#val-parse_string_exn" class="anchor"></a><code><span><span class="keyword">val</span> parse_string_exn : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>string <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <a href="#exception-ParseError"><code>ParseError</code></a> <p>if it fails.</p></li></ul></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse_file"><a href="#val-parse_file" class="anchor"></a><code><span><span class="keyword">val</span> parse_file : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>string <span class="arrow">-></span></span> <span><span>(<span class="type-var">'a</span>, string)</span> <a href="../../ocaml/Stdlib/index.html#type-result">result</a></span></span></code></div><div class="spec-doc"><p><code>parse_file p filename</code> parses file named <code>filename</code> with <code>p</code> by opening the file and reading it whole.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse_file_e"><a href="#val-parse_file_e" class="anchor"></a><code><span><span class="keyword">val</span> parse_file_e : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>string <span class="arrow">-></span></span> <span><span class="type-var">'a</span> <a href="#type-or_error">or_error</a></span></span></code></div><div class="spec-doc"><p>Version of <a href="#val-parse_file"><code>parse_file</code></a> that returns a more detailed error.</p></div></div><div class="odoc-spec"><div class="spec value anchored" id="val-parse_file_exn"><a href="#val-parse_file_exn" class="anchor"></a><code><span><span class="keyword">val</span> parse_file_exn : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">-></span></span> <span>string <span class="arrow">-></span></span> <span class="type-var">'a</span></span></code></div><div class="spec-doc"><p>Same as <a href="#val-parse_file"><code>parse_file</code></a>, but</p><ul class="at-tags"><li class="raises"><span class="at-tag">raises</span> <a href="#exception-ParseError"><code>ParseError</code></a> <p>if it fails.</p></li></ul></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-U"><a href="#module-U" class="anchor"></a><code><span><span class="keyword">module</span> <a href="U/index.html">U</a></span><span> : <span class="keyword">sig</span> ... <span class="keyword">end</span></span></code></div></div><div class="odoc-spec"><div class="spec module anchored" id="module-Debug_"><a href="#module-Debug_" class="anchor"></a><code><span><span class="keyword">module</span> <a href="Debug_/index.html">Debug_</a></span><span> : <span class="keyword">sig</span> ... <span class="keyword">end</span></span></code></div><div class="spec-doc"><p>Debugging utils. <b>EXPERIMENTAL</b></p></div></div></div></body></html>
|