packages feed

polyparse-1.1: docs/haddock/src/Text/ParserCombinators/Poly/Lazy.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<pre><a name="(line1)"></a><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Lazy
<a name="(line2)"></a>  <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype.</font>
<a name="(line3)"></a>    <font color=Blue>-- $parser</font>
<a name="(line4)"></a>    Parser<font color=Cyan>(</font>P<font color=Cyan>)</font>	<font color=Blue>-- datatype, instance of: Functor, Monad</font>
<a name="(line5)"></a>  <font color=Cyan>,</font> runParser	<font color=Blue>-- :: Parser t a -&gt; [t] -&gt; (a, [t])</font>
<a name="(line6)"></a>    <font color=Blue>-- ** basic parsers</font>
<a name="(line7)"></a>  <font color=Cyan>,</font> next	<font color=Blue>-- :: Parser t t</font>
<a name="(line8)"></a>  <font color=Cyan>,</font> satisfy	<font color=Blue>-- :: (t-&gt;Bool) -&gt; Parser t t</font>
<a name="(line9)"></a>    <font color=Blue>-- one defn from 'Base' is overridden here, because it depends</font>
<a name="(line10)"></a>    <font color=Blue>-- on the representation of the Lazy parser monad</font>
<a name="(line11)"></a>  <font color=Cyan>,</font> manyFinally	<font color=Blue>-- :: Parser t a -&gt; Parser t z -&gt; Parser t [a]</font>
<a name="(line12)"></a>    <font color=Blue>-- ** Re-parsing</font>
<a name="(line13)"></a>  <font color=Cyan>,</font> reparse	<font color=Blue>-- :: [t] -&gt; Parser t ()</font>
<a name="(line14)"></a>    <font color=Blue>-- * Re-export all more general combinators</font>
<a name="(line15)"></a>  <font color=Cyan>,</font> <font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Base
<a name="(line16)"></a>  <font color=Cyan>)</font> <font color=Green><u>where</u></font>
<a name="(line17)"></a>
<a name="(line18)"></a><font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Base hiding <font color=Cyan>(</font> manyFinally <font color=Cyan>)</font>
<a name="(line19)"></a>
<a name="(line20)"></a><font color=Magenta><em>#if __GLASGOW_HASKELL__</em></font>
<a name="(line21)"></a><font color=Green><u>import</u></font> Control<font color=Cyan>.</font>Exception hiding <font color=Cyan>(</font>bracket<font color=Cyan>)</font>
<a name="(line22)"></a><a name="throwE"></a>throwE <font color=Red>::</font> String <font color=Red>-&gt;</font> a
<a name="(line23)"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>
<a name="(line24)"></a><font color=Magenta><em>#else</em></font>
<a name="(line25)"></a>throwE <font color=Red>::</font> String <font color=Red>-&gt;</font> a
<a name="(line26)"></a>throwE msg <font color=Red>=</font> error msg
<a name="(line27)"></a><font color=Magenta><em>#endif</em></font>
<a name="(line28)"></a>
<a name="(line29)"></a><font color=Blue>-- $parser</font>
<a name="(line30)"></a><font color=Blue>-- When applied, these parsers do not return explicit failure.</font>
<a name="(line31)"></a><font color=Blue>-- An exception is</font>
<a name="(line32)"></a><font color=Blue>-- raised instead.  This allows partial results to be returned</font>
<a name="(line33)"></a><font color=Blue>-- before a full parse is complete.</font>
<a name="(line34)"></a><font color=Blue>-- One of the key ways to ensure that your parser is properly lazy,</font>
<a name="(line35)"></a><font color=Blue>-- is to parse the initial portion of text returning a function, then</font>
<a name="(line36)"></a><font color=Blue>-- use the @apply@ combinator to build the final value.</font>
<a name="(line37)"></a>
<a name="(line38)"></a><a name="Parser"></a><font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>
<a name="(line39)"></a><a name="Parser"></a><font color=Blue>--   reporting.  It can be used for arbitrary token types, not just</font>
<a name="(line40)"></a><a name="Parser"></a><font color=Blue>--   String input.  (If you require a running state, use module PolyStateLazy</font>
<a name="(line41)"></a><a name="Parser"></a><font color=Blue>--   instead.)</font>
<a name="(line42)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser t a <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Either String a<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line43)"></a>
<a name="(line44)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence.  The parser cannot return</font>
<a name="(line45)"></a><font color=Blue>--   an error value explicitly, so errors raise an exception.  Thus, results</font>
<a name="(line46)"></a><font color=Blue>--   can be partial (lazily constructed, but containing undefined).</font>
<a name="(line47)"></a>runParser <font color=Red>::</font> Parser t a <font color=Red>-&gt;</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>a<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>
<a name="(line48)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font>
<a name="(line49)"></a>    <font color=Cyan>(</font><font color=Red>\</font> <font color=Cyan>(</font>e<font color=Cyan>,</font>ts<font color=Cyan>)</font><font color=Red>-&gt;</font> <font color=Cyan>(</font><font color=Green><u>case</u></font> e <font color=Green><u>of</u></font> <font color=Cyan>{</font>Left m<font color=Red>-&gt;</font>throwE m<font color=Cyan>;</font> Right x<font color=Red>-&gt;</font>x<font color=Cyan>}</font><font color=Cyan>,</font> ts<font color=Cyan>)</font> <font color=Cyan>)</font>
<a name="(line50)"></a>    <font color=Cyan>.</font> p
<a name="(line51)"></a>
<a name="(line52)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser t<font color=Cyan>)</font> <font color=Green><u>where</u></font>
<a name="(line53)"></a>    fmap f <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line54)"></a>                                <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font>    ts'<font color=Cyan>)</font>
<a name="(line55)"></a>                                <font color=Cyan>(</font>Right x<font color=Cyan>,</font>  ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f x<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line56)"></a><font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser t<font color=Cyan>)</font> <font color=Green><u>where</u></font>
<a name="(line57)"></a>    return x     <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line58)"></a>    <font color=Cyan>(</font>P f<font color=Cyan>)</font> <font color=Cyan>&gt;&gt;=</font> g  <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> f ts <font color=Green><u>of</u></font>
<a name="(line59)"></a>                                <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line60)"></a>                                <font color=Cyan>(</font>Right x<font color=Cyan>,</font>  ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Green><u>let</u></font> <font color=Cyan>(</font>P g'<font color=Cyan>)</font> <font color=Red>=</font> g x <font color=Green><u>in</u></font> g' ts'<font color=Cyan>)</font>
<a name="(line61)"></a>    fail e       <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line62)"></a>
<a name="(line63)"></a>
<a name="(line64)"></a><font color=Green><u>instance</u></font> PolyParse <font color=Cyan>(</font>Parser t<font color=Cyan>)</font> <font color=Green><u>where</u></font>
<a name="(line65)"></a>    commit <font color=Cyan>(</font>P p<font color=Cyan>)</font>         <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line66)"></a>                                      <font color=Cyan>(</font>Left e<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>throwE e<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line67)"></a>                                      right         <font color=Red>-&gt;</font> right <font color=Cyan>)</font>
<a name="(line68)"></a>    <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`onFail`</font> <font color=Cyan>(</font>P q<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line69)"></a>                                      <font color=Cyan>(</font>Left <font color=Green><u>_</u></font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-&gt;</font> q ts
<a name="(line70)"></a>                                      right       <font color=Red>-&gt;</font> right <font color=Cyan>)</font>
<a name="(line71)"></a>    <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`adjustErr`</font> f  <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line72)"></a>                                      <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line73)"></a>                                      right           <font color=Red>-&gt;</font> right <font color=Cyan>)</font>
<a name="(line74)"></a>    oneOf' ps <font color=Red>=</font> accum [] ps
<a name="(line75)"></a>      <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>
<a name="(line76)"></a>              <font color=Green><u>case</u></font> errs <font color=Green><u>of</u></font>
<a name="(line77)"></a>                [] <font color=Red>-&gt;</font>  failBad <font color=Cyan>(</font><font color=Magenta>"internal failure in parser (oneOf'):\n"</font>
<a name="(line78)"></a>                               <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>show <font color=Cyan>(</font>map fst ps<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line79)"></a>                <font color=Red>[</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-&gt;</font> fail e
<a name="(line80)"></a>                es <font color=Red>-&gt;</font> fail <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>
<a name="(line81)"></a>                           <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse es<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line82)"></a>            accum errs <font color=Cyan>(</font><font color=Cyan>(</font>e<font color=Cyan>,</font>P p<font color=Cyan>)</font><font color=Red><b>:</b></font>ps<font color=Cyan>)</font> <font color=Red>=</font>
<a name="(line83)"></a>                P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line84)"></a>                           <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Green><u>let</u></font> <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> accum <font color=Cyan>(</font><font color=Cyan>(</font>e<font color=Cyan>,</font>err<font color=Cyan>)</font><font color=Red><b>:</b></font>errs<font color=Cyan>)</font> ps
<a name="(line85)"></a>                                           <font color=Green><u>in</u></font> p ts
<a name="(line86)"></a>                           right        <font color=Red>-&gt;</font> right <font color=Cyan>)</font>
<a name="(line87)"></a>            showErr <font color=Cyan>(</font>name<font color=Cyan>,</font>err<font color=Cyan>)</font> <font color=Red>=</font> name<font color=Cyan>++</font><font color=Magenta>":\n"</font><font color=Cyan>++</font>indent <font color=Magenta>2</font> err
<a name="(line88)"></a>    <font color=Blue>--   This version of "apply"</font>
<a name="(line89)"></a>    <font color=Blue>--   is strict in the result of the function parser, but</font>
<a name="(line90)"></a>    <font color=Blue>--   lazy in the result of the argument parser.  (Argument laziness is</font>
<a name="(line91)"></a>    <font color=Blue>--   the distinctive feature over other implementations.)</font>
<a name="(line92)"></a>    <font color=Cyan>(</font>P pf<font color=Cyan>)</font> <font color=Cyan>`apply`</font> <font color=Cyan>(</font>P px<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font>
<a name="(line93)"></a>        <font color=Green><u>case</u></font> pf ts <font color=Green><u>of</u></font>
<a name="(line94)"></a>          <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line95)"></a>          <font color=Cyan>(</font>Right f<font color=Cyan>,</font>  ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Green><u>let</u></font> <font color=Cyan>(</font>x'<font color=Cyan>,</font>ts''<font color=Cyan>)</font> <font color=Red>=</font> px ts'
<a name="(line96)"></a>                                 x <font color=Red>=</font> <font color=Green><u>case</u></font> x' <font color=Green><u>of</u></font> <font color=Cyan>{</font> Right x <font color=Red>-&gt;</font> x
<a name="(line97)"></a>                                                <font color=Cyan>;</font> Left e <font color=Red>-&gt;</font> throwE e <font color=Cyan>}</font>
<a name="(line98)"></a>                             <font color=Green><u>in</u></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f x<font color=Cyan>)</font><font color=Cyan>,</font> ts''<font color=Cyan>)</font> <font color=Cyan>)</font>
<a name="(line99)"></a>
<a name="(line100)"></a><a name="next"></a><font color=Blue>-- | Next token</font>
<a name="(line101)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-&gt;</font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>
<a name="(line102)"></a>                  []  <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left <font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>,</font> []<font color=Cyan>)</font>
<a name="(line103)"></a>                  <font color=Cyan>(</font>t<font color=Red><b>:</b></font>ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Right t<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>
<a name="(line104)"></a>
<a name="(line105)"></a><a name="satisfy"></a><font color=Blue>-- | One token satifying a predicate</font>
<a name="(line106)"></a>satisfy <font color=Red>::</font> <font color=Cyan>(</font>t<font color=Red>-&gt;</font>Bool<font color=Cyan>)</font> <font color=Red>-&gt;</font> Parser t t
<a name="(line107)"></a>satisfy p <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> x <font color=Red>&lt;-</font> next
<a name="(line108)"></a>              <font color=Cyan>;</font> <font color=Green><u>if</u></font> p x <font color=Green><u>then</u></font> return x <font color=Green><u>else</u></font> fail <font color=Magenta>"Parse.satisfy: failed"</font>
<a name="(line109)"></a>              <font color=Cyan>}</font>
<a name="(line110)"></a>
<a name="(line111)"></a><a name="manyFinally"></a><font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>
<a name="(line112)"></a><font color=Blue>--   terminated by a t.  Any parse failures could be due either to</font>
<a name="(line113)"></a><font color=Blue>--   a badly-formed terminator or a badly-formed element, so raise</font>
<a name="(line114)"></a><font color=Blue>--   both possible errors.</font>
<a name="(line115)"></a>manyFinally <font color=Red>::</font> Parser t a <font color=Red>-&gt;</font> Parser t z <font color=Red>-&gt;</font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line116)"></a>manyFinally pp<font color=Red>@</font><font color=Cyan>(</font>P p<font color=Cyan>)</font> pt<font color=Red>@</font><font color=Cyan>(</font>P t<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts <font color=Red>-&gt;</font>
<a name="(line117)"></a>    <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line118)"></a>        <font color=Cyan>(</font>Left e<font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-&gt;</font>
<a name="(line119)"></a>            <font color=Green><u>case</u></font> t ts <font color=Green><u>of</u></font>
<a name="(line120)"></a>                <font color=Cyan>(</font>Right <font color=Green><u>_</u></font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Right []<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line121)"></a>                <font color=Cyan>(</font>Left e<font color=Cyan>,</font>  ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font>   ts'<font color=Cyan>)</font>
<a name="(line122)"></a>        <font color=Cyan>(</font>Right x<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-&gt;</font>
<a name="(line123)"></a>            <font color=Green><u>let</u></font> <font color=Cyan>(</font>tail<font color=Cyan>,</font>ts''<font color=Cyan>)</font> <font color=Red>=</font> runParser <font color=Cyan>(</font>manyFinally pp pt<font color=Cyan>)</font> ts'
<a name="(line124)"></a>            <font color=Green><u>in</u></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>x<font color=Red><b>:</b></font>tail<font color=Cyan>)</font><font color=Cyan>,</font> ts''<font color=Cyan>)</font> <font color=Cyan>)</font>
<a name="(line125)"></a>
<a name="(line126)"></a>
<a name="(line127)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>
<a name="(line128)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>
<a name="(line129)"></a><font color=Blue>--   This is useful e.g. for recursively expanding macros.  When the</font>
<a name="(line130)"></a><font color=Blue>--   user-parser recognises a macro use, it can lookup the macro</font>
<a name="(line131)"></a><font color=Blue>--   expansion from the parse state, lex it, and then stuff the</font>
<a name="(line132)"></a><font color=Blue>--   lexed expansion back down into the parser.</font>
<a name="(line133)"></a>reparse    <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-&gt;</font> Parser t ()
<a name="(line134)"></a>reparse ts  <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp<font color=Red>-&gt;</font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line135)"></a>
<a name="(line136)"></a><font color=Blue>------------------------------------------------------------------------</font>
</pre>
</html>