ocaml-containers/3.11/containers/CCParse/index.html
2023-02-07 13:11:03 -05:00

48 lines
No EOL
72 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>CCParse (containers.CCParse)</title><link rel="stylesheet" href="../../odoc.css"/><meta charset="utf-8"/><meta name="generator" content="odoc 2.1.0"/><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> &#x00BB; 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><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 -&gt;
skip_space *&gt;
( (char '(' *&gt; (pure mk_node &lt;*&gt; self &lt;*&gt; self) &lt;* char ')')
&lt;|&gt;
(U.int &gt;|= mk_leaf) )
;;
parse_string_exn ptree &quot;(1 (2 3))&quot; ;;
parse_string_exn ptree &quot;((1 2) (3 (4 5)))&quot; ;;</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><code>open Containers.Parse;;
let p = U.list ~sep:&quot;,&quot; U.word;;
parse_string_exn p &quot;[abc , de, hello ,world ]&quot;;;</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><code>let p = CCParse.(U.list ~sep:&quot;,&quot; U.int);;
let l = CCList.(1 -- 100_000);;
let l_printed =
CCFormat.(to_string (within &quot;[&quot; &quot;]&quot; (list ~sep:(return &quot;,@,&quot;) 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 &quot;experimental&quot; and are still subject to change.</p><div class="odoc-spec"><div class="spec type" id="type-position" class="anchored"><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" id="module-Position" class="anchored"><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" id="module-Error" class="anchored"><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" id="type-or_error" class="anchored"><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> <span class="xref-unresolved">Stdlib</span>.result</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" id="exception-ParseError" class="anchored"><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" id="type-t" class="anchored"><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> <span class="value">ParseError</span> <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" id="val-return" class="anchored"><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">&#45;&gt;</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" id="val-pure" class="anchored"><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">&#45;&gt;</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" id="val-map" class="anchored"><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">&#45;&gt;</span></span> <span class="type-var">'b</span> )</span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-map2" class="anchored"><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">&#45;&gt;</span></span> <span><span class="type-var">'b</span> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'c</span> )</span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-map3" class="anchored"><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">&#45;&gt;</span></span> <span><span class="type-var">'b</span> <span class="arrow">&#45;&gt;</span></span> <span><span class="type-var">'c</span> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'d</span> )</span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'c</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-bind" class="anchored"><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">&#45;&gt;</span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span> )</span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-ap" class="anchored"><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">&#45;&gt;</span></span> <span class="type-var">'b</span> )</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-eoi" class="anchored"><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" id="val-empty" class="anchored"><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" id="val-fail" class="anchored"><a href="#val-fail" class="anchor"></a><code><span><span class="keyword">val</span> fail : <span>string <span class="arrow">&#45;&gt;</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" id="val-failf" class="anchored"><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> <span class="xref-unresolved">Stdlib</span>.format4</span> <span class="arrow">&#45;&gt;</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" id="val-fail_lazy" class="anchored"><a href="#val-fail_lazy" class="anchor"></a><code><span><span class="keyword">val</span> fail_lazy : <span><span>( <span>unit <span class="arrow">&#45;&gt;</span></span> string )</span> <span class="arrow">&#45;&gt;</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" id="val-parsing" class="anchored"><a href="#val-parsing" class="anchor"></a><code><span><span class="keyword">val</span> parsing : <span>string <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-set_error_message" class="anchored"><a href="#val-set_error_message" class="anchor"></a><code><span><span class="keyword">val</span> set_error_message : <span>string <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-pos" class="anchored"><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" id="val-with_pos" class="anchored"><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">&#45;&gt;</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" id="val-any_char" class="anchored"><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" id="val-any_char_n" class="anchored"><a href="#val-any_char_n" class="anchor"></a><code><span><span class="keyword">val</span> any_char_n : <span>int <span class="arrow">&#45;&gt;</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" id="val-char" class="anchored"><a href="#val-char" class="anchor"></a><code><span><span class="keyword">val</span> char : <span>char <span class="arrow">&#45;&gt;</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" id="type-slice" class="anchored"><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" id="module-Slice" class="anchored"><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" id="val-recurse" class="anchored"><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">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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 <code>split_n</code>), 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" id="val-set_current_slice" class="anchored"><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">&#45;&gt;</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" id="val-chars_fold" class="anchored"><a href="#val-chars_fold" class="anchor"></a><code><span><span class="keyword">val</span> chars_fold :
<span>f:
<span>( <span><span class="type-var">'acc</span> <span class="arrow">&#45;&gt;</span></span>
<span>char <span class="arrow">&#45;&gt;</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">&#45;&gt;</span></span>
<span><span class="type-var">'acc</span> <span class="arrow">&#45;&gt;</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" id="val-chars_fold_transduce" class="anchored"><a href="#val-chars_fold_transduce" class="anchor"></a><code><span><span class="keyword">val</span> chars_fold_transduce :
<span>f:
<span>( <span><span class="type-var">'acc</span> <span class="arrow">&#45;&gt;</span></span>
<span>char <span class="arrow">&#45;&gt;</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">&#45;&gt;</span></span>
<span><span class="type-var">'acc</span> <span class="arrow">&#45;&gt;</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 <code>char_fold</code> 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" id="val-take" class="anchored"><a href="#val-take" class="anchor"></a><code><span><span class="keyword">val</span> take : <span>int <span class="arrow">&#45;&gt;</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" id="val-take_if" class="anchored"><a href="#val-take_if" class="anchor"></a><code><span><span class="keyword">val</span> take_if : <span><span>( <span>char <span class="arrow">&#45;&gt;</span></span> bool )</span> <span class="arrow">&#45;&gt;</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" id="val-take1_if" class="anchored"><a href="#val-take1_if" class="anchor"></a><code><span><span class="keyword">val</span> take1_if : <span>?descr:string <span class="arrow">&#45;&gt;</span></span> <span><span>( <span>char <span class="arrow">&#45;&gt;</span></span> bool )</span> <span class="arrow">&#45;&gt;</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" id="val-char_if" class="anchored"><a href="#val-char_if" class="anchor"></a><code><span><span class="keyword">val</span> char_if : <span>?descr:string <span class="arrow">&#45;&gt;</span></span> <span><span>( <span>char <span class="arrow">&#45;&gt;</span></span> bool )</span> <span class="arrow">&#45;&gt;</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" id="val-chars_if" class="anchored"><a href="#val-chars_if" class="anchor"></a><code><span><span class="keyword">val</span> chars_if : <span><span>( <span>char <span class="arrow">&#45;&gt;</span></span> bool )</span> <span class="arrow">&#45;&gt;</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" id="val-chars1_if" class="anchored"><a href="#val-chars1_if" class="anchor"></a><code><span><span class="keyword">val</span> chars1_if : <span>?descr:string <span class="arrow">&#45;&gt;</span></span> <span><span>( <span>char <span class="arrow">&#45;&gt;</span></span> bool )</span> <span class="arrow">&#45;&gt;</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 &gt;|= 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" id="val-endline" class="anchored"><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" id="val-space" class="anchored"><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" id="val-white" class="anchored"><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" id="val-skip_chars" class="anchored"><a href="#val-skip_chars" class="anchor"></a><code><span><span class="keyword">val</span> skip_chars : <span><span>( <span>char <span class="arrow">&#45;&gt;</span></span> bool )</span> <span class="arrow">&#45;&gt;</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" id="val-skip_space" class="anchored"><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" id="val-skip_white" class="anchored"><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" id="val-is_alpha" class="anchored"><a href="#val-is_alpha" class="anchor"></a><code><span><span class="keyword">val</span> is_alpha : <span>char <span class="arrow">&#45;&gt;</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" id="val-is_num" class="anchored"><a href="#val-is_num" class="anchor"></a><code><span><span class="keyword">val</span> is_num : <span>char <span class="arrow">&#45;&gt;</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" id="val-is_alpha_num" class="anchored"><a href="#val-is_alpha_num" class="anchor"></a><code><span><span class="keyword">val</span> is_alpha_num : <span>char <span class="arrow">&#45;&gt;</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" id="val-is_space" class="anchored"><a href="#val-is_space" class="anchor"></a><code><span><span class="keyword">val</span> is_space : <span>char <span class="arrow">&#45;&gt;</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" id="val-is_white" class="anchored"><a href="#val-is_white" class="anchor"></a><code><span><span class="keyword">val</span> is_white : <span>char <span class="arrow">&#45;&gt;</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" id="val-suspend" class="anchored"><a href="#val-suspend" class="anchor"></a><code><span><span class="keyword">val</span> suspend : <span><span>( <span>unit <span class="arrow">&#45;&gt;</span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span> )</span> <span class="arrow">&#45;&gt;</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" id="val-string" class="anchored"><a href="#val-string" class="anchor"></a><code><span><span class="keyword">val</span> string : <span>string <span class="arrow">&#45;&gt;</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" id="val-exact" class="anchored"><a href="#val-exact" class="anchor"></a><code><span><span class="keyword">val</span> exact : <span>string <span class="arrow">&#45;&gt;</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" id="val-many" class="anchored"><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">&#45;&gt;</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" id="val-optional" class="anchored"><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">&#45;&gt;</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" id="val-try_" class="anchored"><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">&#45;&gt;</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 <code>try_opt</code> if you want to detect failure.</p></li></ul></div></div><div class="odoc-spec"><div class="spec value" id="val-try_opt" class="anchored"><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">&#45;&gt;</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" id="val-many_until" class="anchored"><a href="#val-many_until" class="anchor"></a><code><span><span class="keyword">val</span> many_until : <span>until:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-try_or" class="anchored"><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">&#45;&gt;</span></span> <span>f:<span>( <span><span class="type-var">'a</span> <span class="arrow">&#45;&gt;</span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span> )</span> <span class="arrow">&#45;&gt;</span></span> <span>else_:<span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-try_or_l" class="anchored"><a href="#val-try_or_l" class="anchor"></a><code><span><span class="keyword">val</span> try_or_l : <span>?msg:string <span class="arrow">&#45;&gt;</span></span> <span>?else_:<span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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">&#45;&gt;</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-(&lt;|&gt;)"><code>(&lt;|&gt;)</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" id="val-or_" class="anchored"><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">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-both" class="anchored"><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">&#45;&gt;</span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-many1" class="anchored"><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">&#45;&gt;</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" id="val-skip" class="anchored"><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">&#45;&gt;</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" id="val-sep" class="anchored"><a href="#val-sep" class="anchor"></a><code><span><span class="keyword">val</span> sep : <span>by:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-sep_until" class="anchored"><a href="#val-sep_until" class="anchor"></a><code><span><span class="keyword">val</span> sep_until : <span>until:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span>by:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-sep1" class="anchored"><a href="#val-sep1" class="anchor"></a><code><span><span class="keyword">val</span> sep1 : <span>by:<span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-lookahead" class="anchored"><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">&#45;&gt;</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" id="val-lookahead_ignore" class="anchored"><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">&#45;&gt;</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" id="val-fix" class="anchored"><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">&#45;&gt;</span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span> )</span> <span class="arrow">&#45;&gt;</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 -&gt; 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 -&gt; q)</code> is:</p><pre><code>let rec p () =
let self = suspend p in
q</code></pre></div></div><div class="odoc-spec"><div class="spec value" id="val-line" class="anchored"><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" id="val-line_str" class="anchored"><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 &gt;|= 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" id="val-each_line" class="anchored"><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">&#45;&gt;</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" id="val-split_1" class="anchored"><a href="#val-split_1" class="anchor"></a><code><span><span class="keyword">val</span> split_1 : <span>on_char:char <span class="arrow">&#45;&gt;</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" id="val-split_list" class="anchored"><a href="#val-split_list" class="anchor"></a><code><span><span class="keyword">val</span> split_list : <span>on_char:char <span class="arrow">&#45;&gt;</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" id="val-split_list_at_most" class="anchored"><a href="#val-split_list_at_most" class="anchor"></a><code><span><span class="keyword">val</span> split_list_at_most : <span>on_char:char <span class="arrow">&#45;&gt;</span></span> <span>int <span class="arrow">&#45;&gt;</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" id="val-split_2" class="anchored"><a href="#val-split_2" class="anchor"></a><code><span><span class="keyword">val</span> split_2 : <span>on_char:char <span class="arrow">&#45;&gt;</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" id="val-split_3" class="anchored"><a href="#val-split_3" class="anchor"></a><code><span><span class="keyword">val</span> split_3 : <span>on_char:char <span class="arrow">&#45;&gt;</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" id="val-split_4" class="anchored"><a href="#val-split_4" class="anchor"></a><code><span><span class="keyword">val</span> split_4 : <span>on_char:char <span class="arrow">&#45;&gt;</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" id="val-each_split" class="anchored"><a href="#val-each_split" class="anchor"></a><code><span><span class="keyword">val</span> each_split : <span>on_char:char <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-all" class="anchored"><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" id="val-all_str" class="anchored"><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" id="val-memo" class="anchored"><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">&#45;&gt;</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-(&gt;&gt;=)"><code>(&gt;&gt;=)</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><code>let my_expensive_parser = memo (foo *&gt; bar &gt;&gt;= fun i -&gt; …)</code></pre><p>This function is not thread-safe.</p></div></div><div class="odoc-spec"><div class="spec value" id="val-fix_memo" class="anchored"><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">&#45;&gt;</span></span> <span><span class="type-var">'a</span> <a href="#type-t">t</a></span> )</span> <span class="arrow">&#45;&gt;</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" id="module-Infix" class="anchored"><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" id="val-(&gt;|=)" class="anchored"><a href="#val-(&gt;|=)" class="anchor"></a><code><span><span class="keyword">val</span> (&gt;|=) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span>( <span><span class="type-var">'a</span> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'b</span> )</span> <span class="arrow">&#45;&gt;</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 &gt;|= 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" id="val-(&gt;&gt;=)" class="anchored"><a href="#val-(&gt;&gt;=)" class="anchor"></a><code><span><span class="keyword">val</span> (&gt;&gt;=) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span>( <span><span class="type-var">'a</span> <span class="arrow">&#45;&gt;</span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span> )</span> <span class="arrow">&#45;&gt;</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 &gt;&gt;= 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" id="val-(&lt;*&gt;)" class="anchored"><a href="#val-(&lt;*&gt;)" class="anchor"></a><code><span><span class="keyword">val</span> (&lt;*&gt;) : <span><span><span>( <span><span class="type-var">'a</span> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'b</span> )</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-(&lt;*)" class="anchored"><a href="#val-(&lt;*)" class="anchor"></a><code><span><span class="keyword">val</span> (&lt;*) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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 &lt;* 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" id="val-(*&gt;)" class="anchored"><a href="#val-(*&gt;)" class="anchor"></a><code><span><span class="keyword">val</span> (*&gt;) : <span><span><span class="type-var">_</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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 *&gt; 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" id="val-(&lt;|&gt;)" class="anchored"><a href="#val-(&lt;|&gt;)" class="anchor"></a><code><span><span class="keyword">val</span> (&lt;|&gt;) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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 &lt;|&gt; 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" id="val-(&lt;?&gt;)" class="anchored"><a href="#val-(&lt;?&gt;)" class="anchor"></a><code><span><span class="keyword">val</span> (&lt;?&gt;) : <span><span><span class="type-var">'a</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</span></span> <span>string <span class="arrow">&#45;&gt;</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 &lt;?&gt; msg</code> behaves like <code>a</code>, but if <code>a</code> fails, <code>a &lt;?&gt; msg</code> fails with <code>msg</code> instead. Useful as the last choice in a series of <code>&lt;|&gt;</code>. For example: <code>a &lt;|&gt; b &lt;|&gt; c &lt;?&gt; &quot;expected one of a, b, c&quot;</code>.</p></div></div><div class="odoc-spec"><div class="spec value" id="val-(|||)" class="anchored"><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">&#45;&gt;</span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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-include"><div class="spec-doc"><p>Let operators on OCaml &gt;= 4.08.0, nothing otherwise</p><ul class="at-tags"><li class="since"><span class="at-tag">since</span> 2.8</li></ul></div><div class="odoc-spec"><div class="spec value" id="val-let+" class="anchored"><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">&#45;&gt;</span></span> <span><span>( <span><span class="type-var">'a</span> <span class="arrow">&#45;&gt;</span></span> <span class="type-var">'b</span> )</span> <span class="arrow">&#45;&gt;</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" id="val-and+" class="anchored"><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">&#45;&gt;</span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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" id="val-let*" class="anchored"><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">&#45;&gt;</span></span> <span><span>( <span><span class="type-var">'a</span> <span class="arrow">&#45;&gt;</span></span> <span><span class="type-var">'b</span> <a href="#type-t">t</a></span> )</span> <span class="arrow">&#45;&gt;</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" id="val-and*" class="anchored"><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">&#45;&gt;</span></span> <span><span><span class="type-var">'b</span> <a href="#type-t">t</a></span> <span class="arrow">&#45;&gt;</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></details></div><h3 id="parse-input"><a href="#parse-input" class="anchor"></a>Parse input</h3><div class="odoc-spec"><div class="spec value" id="val-stringify_result" class="anchored"><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">&#45;&gt;</span></span> <span><span>( <span class="type-var">'a</span>, string )</span> <span class="xref-unresolved">Stdlib</span>.result</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" id="val-parse_string" class="anchored"><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">&#45;&gt;</span></span> <span>string <span class="arrow">&#45;&gt;</span></span> <span><span>( <span class="type-var">'a</span>, string )</span> <span class="xref-unresolved">Stdlib</span>.result</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" id="val-parse_string_e" class="anchored"><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">&#45;&gt;</span></span> <span>string <span class="arrow">&#45;&gt;</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" id="val-parse_string_exn" class="anchored"><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">&#45;&gt;</span></span> <span>string <span class="arrow">&#45;&gt;</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> <span class="value">ParseError</span> <p>if it fails.</p></li></ul></div></div><div class="odoc-spec"><div class="spec value" id="val-parse_file" class="anchored"><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">&#45;&gt;</span></span> <span>string <span class="arrow">&#45;&gt;</span></span> <span><span>( <span class="type-var">'a</span>, string )</span> <span class="xref-unresolved">Stdlib</span>.result</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" id="val-parse_file_e" class="anchored"><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">&#45;&gt;</span></span> <span>string <span class="arrow">&#45;&gt;</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" id="val-parse_file_exn" class="anchored"><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">&#45;&gt;</span></span> <span>string <span class="arrow">&#45;&gt;</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> <span class="value">ParseError</span> <p>if it fails.</p></li></ul></div></div><div class="odoc-spec"><div class="spec module" id="module-U" class="anchored"><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" id="module-Debug_" class="anchored"><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>