polyparse-1.1: docs/haddock/src/Text/ParserCombinators/PolyLazy.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>PolyLazy
<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 -> [t] -> (a, [t])</font>
<a name="(line6)"></a> <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser t a</font>
<a name="(line7)"></a> <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser t a -> Parser t a</font>
<a name="(line8)"></a> <font color=Blue>-- * Combinators:</font>
<a name="(line9)"></a> <font color=Blue>-- ** Primitives</font>
<a name="(line10)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser t t</font>
<a name="(line11)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser t t</font>
<a name="(line12)"></a> <font color=Cyan>,</font> apply <font color=Blue>-- :: Parser t (a->b) -> Parser t a -> Parser t b</font>
<a name="(line13)"></a> <font color=Cyan>,</font> discard <font color=Blue>-- :: Parser t a -> Parser t b -> Parser t a</font>
<a name="(line14)"></a> <font color=Blue>-- ** Error-handling</font>
<a name="(line15)"></a> <font color=Cyan>,</font> adjustErr <font color=Blue>-- :: Parser t a -> (String->String) -> Parser t a</font>
<a name="(line16)"></a> <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: Parser t a -> (String->String) -> Parser t a</font>
<a name="(line17)"></a> <font color=Cyan>,</font> indent <font color=Blue>-- :: Int -> String -> String</font>
<a name="(line18)"></a> <font color=Blue>-- ** Choices</font>
<a name="(line19)"></a> <font color=Cyan>,</font> onFail <font color=Blue>-- :: Parser t a -> Parser t a -> Parser t a</font>
<a name="(line20)"></a> <font color=Cyan>,</font> oneOf <font color=Blue>-- :: Show t => [Parser t a] -> Parser t a</font>
<a name="(line21)"></a> <font color=Cyan>,</font> oneOf' <font color=Blue>-- :: [(String,Parser t a)] -> Parser t a</font>
<a name="(line22)"></a> <font color=Cyan>,</font> optional <font color=Blue>-- :: Parser t a -> Parser t (Maybe a)</font>
<a name="(line23)"></a> <font color=Blue>-- ** Sequences</font>
<a name="(line24)"></a> <font color=Cyan>,</font> exactly <font color=Blue>-- :: Int -> Parser t a -> Parser t [a]</font>
<a name="(line25)"></a> <font color=Cyan>,</font> many <font color=Blue>-- :: Parser t a -> Parser t [a]</font>
<a name="(line26)"></a> <font color=Cyan>,</font> many1 <font color=Blue>-- :: Parser t a -> Parser t [a]</font>
<a name="(line27)"></a> <font color=Cyan>,</font> sepBy <font color=Blue>-- :: Parser t a -> Parser t sep -> Parser t [a]</font>
<a name="(line28)"></a> <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: Parser t a -> Parser t sep -> Parser t [a]</font>
<a name="(line29)"></a> <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: Parser t bra -> Parser t sep -> Parser t ket</font>
<a name="(line30)"></a> <font color=Blue>-- -> Parser t a -> Parser t [a]</font>
<a name="(line31)"></a> <font color=Cyan>,</font> bracket <font color=Blue>-- :: Parser t bra -> Parser t ket -> Parser t a</font>
<a name="(line32)"></a> <font color=Blue>-- -> Parser t a</font>
<a name="(line33)"></a> <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser t a -> Parser t z -> Parser t [a]</font>
<a name="(line34)"></a> <font color=Blue>-- ** Re-parsing</font>
<a name="(line35)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser t ()</font>
<a name="(line36)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>
<a name="(line37)"></a>
<a name="(line38)"></a><font color=Magenta><em>#if __GLASGOW_HASKELL__</em></font>
<a name="(line39)"></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="(line40)"></a><a name="throwE"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a
<a name="(line41)"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>
<a name="(line42)"></a><font color=Magenta><em>#else</em></font>
<a name="(line43)"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a
<a name="(line44)"></a>throwE msg <font color=Red>=</font> error msg
<a name="(line45)"></a><font color=Magenta><em>#endif</em></font>
<a name="(line46)"></a>
<a name="(line47)"></a><font color=Blue>-- $parser</font>
<a name="(line48)"></a><font color=Blue>-- When applied, these parsers do not return explicit failure.</font>
<a name="(line49)"></a><font color=Blue>-- An exception is</font>
<a name="(line50)"></a><font color=Blue>-- raised instead. This allows partial results to be returned</font>
<a name="(line51)"></a><font color=Blue>-- before a full parse is complete.</font>
<a name="(line52)"></a><font color=Blue>-- One of the key ways to ensure that your parser is properly lazy,</font>
<a name="(line53)"></a><font color=Blue>-- is to parse the initial portion of text returning a function, then</font>
<a name="(line54)"></a><font color=Blue>-- use the @apply@ combinator to build the final value.</font>
<a name="(line55)"></a>
<a name="(line56)"></a><a name="Parser"></a><font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>
<a name="(line57)"></a><a name="Parser"></a><font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>
<a name="(line58)"></a><a name="Parser"></a><font color=Blue>-- String input. (If you require a running state, use module PolyStateLazy</font>
<a name="(line59)"></a><a name="Parser"></a><font color=Blue>-- instead.)</font>
<a name="(line60)"></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>-></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="(line61)"></a>
<a name="(line62)"></a><a name="EitherE"></a><font color=Blue>-- A return type like Either, that distinguishes not only between</font>
<a name="(line63)"></a><a name="EitherE"></a><font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>
<a name="(line64)"></a><a name="EitherE"></a><font color=Blue>-- Not used in this library. !!!!!!!!!!!!!!!!!!!!!!!!!!!</font>
<a name="(line65)"></a><a name="EitherE"></a><font color=Green><u>type</u></font> EitherE a b <font color=Red>=</font> Either <font color=Cyan>(</font>Bool<font color=Cyan>,</font>a<font color=Cyan>)</font> b
<a name="(line66)"></a>
<a name="(line67)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence. The parser cannot return</font>
<a name="(line68)"></a><font color=Blue>-- an error value explicitly, so errors raise an exception. Thus, results</font>
<a name="(line69)"></a><font color=Blue>-- can be partial (lazily constructed, but containing undefined).</font>
<a name="(line70)"></a>runParser <font color=Red>::</font> Parser t a <font color=Red>-></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></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="(line71)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font>
<a name="(line72)"></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>-></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>-></font>throwE m<font color=Cyan>;</font> Right x<font color=Red>-></font>x<font color=Cyan>}</font><font color=Cyan>,</font> ts<font color=Cyan>)</font> <font color=Cyan>)</font>
<a name="(line73)"></a> <font color=Cyan>.</font> p
<a name="(line74)"></a>
<a name="(line75)"></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="(line76)"></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>-></font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line77)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line78)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></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="(line79)"></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="(line80)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line81)"></a> <font color=Cyan>(</font>P f<font color=Cyan>)</font> <font color=Cyan>>>=</font> g <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> <font color=Green><u>case</u></font> f ts <font color=Green><u>of</u></font>
<a name="(line82)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line83)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></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="(line84)"></a> fail e <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line85)"></a>
<a name="(line86)"></a><font color=Blue>-- | Simple failure can be corrected, but when a simple fail is not strong</font>
<a name="(line87)"></a><font color=Blue>-- enough, use failBad for emphasis. It guarantees parsing will</font>
<a name="(line88)"></a><font color=Blue>-- terminate with an exception.</font>
<a name="(line89)"></a>
<a name="(line90)"></a><a name="failBad"></a>failBad <font color=Red>::</font> String <font color=Red>-></font> Parser t a
<a name="(line91)"></a>failBad msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> <font color=Cyan>(</font>throwE msg<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line92)"></a>
<a name="(line93)"></a><a name="commit"></a><font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>
<a name="(line94)"></a><font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>
<a name="(line95)"></a><font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>
<a name="(line96)"></a><font color=Blue>-- they fail hard.</font>
<a name="(line97)"></a>commit <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t a
<a name="(line98)"></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>-></font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line99)"></a> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>throwE e<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line100)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>
<a name="(line101)"></a>
<a name="(line102)"></a>
<a name="(line103)"></a><font color=Blue>-- Combinators</font>
<a name="(line104)"></a>
<a name="(line105)"></a><a name="next"></a><font color=Blue>-- | One token</font>
<a name="(line106)"></a>next <font color=Red>::</font> Parser t t
<a name="(line107)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>
<a name="(line108)"></a> [] <font color=Red>-></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="(line109)"></a> <font color=Cyan>(</font>t<font color=Red><b>:</b></font>ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right t<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>
<a name="(line110)"></a>
<a name="(line111)"></a><a name="satisfy"></a><font color=Blue>-- | One token satifying a predicate</font>
<a name="(line112)"></a>satisfy <font color=Red>::</font> <font color=Cyan>(</font>t<font color=Red>-></font>Bool<font color=Cyan>)</font> <font color=Red>-></font> Parser t t
<a name="(line113)"></a>satisfy p <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> x <font color=Red><-</font> next
<a name="(line114)"></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="(line115)"></a> <font color=Cyan>}</font>
<a name="(line116)"></a>
<a name="(line117)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>
<a name="(line118)"></a><a name="apply"></a><font color=Blue>-- | Apply a parsed function to a parsed value</font>
<a name="(line119)"></a>apply <font color=Red>::</font> Parser t <font color=Cyan>(</font>a<font color=Red>-></font>b<font color=Cyan>)</font> <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t b
<a name="(line120)"></a><a name="apply"></a><font color=Blue>--pf `apply` px = do { f <- pf; x <- px; return (f x) }</font>
<a name="(line121)"></a><a name="apply"></a><font color=Blue>-- Needs to be lazier! Must not force the argument value too early. </font>
<a name="(line122)"></a><a name="apply"></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>-></font>
<a name="(line123)"></a> <font color=Green><u>case</u></font> pf ts <font color=Green><u>of</u></font>
<a name="(line124)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line125)"></a> <font color=Cyan>(</font>Right f<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></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="(line126)"></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>-></font> x<font color=Cyan>;</font> Left e <font color=Red>-></font> throwE e <font color=Cyan>}</font>
<a name="(line127)"></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="(line128)"></a>
<a name="(line129)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>
<a name="(line130)"></a><a name="discard"></a><font color=Blue>-- | @x `discard` y@ parses both x and y, but discards the result of y</font>
<a name="(line131)"></a>discard <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t b <font color=Red>-></font> Parser t a
<a name="(line132)"></a><a name="discard"></a><font color=Blue>--px `discard` py = do { x <- px; _ <- py; return x }</font>
<a name="(line133)"></a><a name="discard"></a><font color=Blue>-- Needs to be lazier! Do not force the discarded portion too early.</font>
<a name="(line134)"></a><a name="discard"></a>px <font color=Cyan>`discard`</font> py <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> px<font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Red>\</font><font color=Green><u>_</u></font><font color=Red>-></font> x<font color=Cyan>)</font> <font color=Cyan>`apply`</font> py <font color=Cyan>}</font>
<a name="(line135)"></a>
<a name="(line136)"></a><a name="adjustErr"></a><font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>
<a name="(line137)"></a><font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>
<a name="(line138)"></a>adjustErr <font color=Red>::</font> Parser t a <font color=Red>-></font> <font color=Cyan>(</font>String<font color=Red>-></font>String<font color=Cyan>)</font> <font color=Red>-></font> Parser t a
<a name="(line139)"></a><a name="adjustErr"></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>-></font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line140)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></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="(line141)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>
<a name="(line142)"></a>
<a name="(line143)"></a><a name="adjustErrBad"></a><font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>
<a name="(line144)"></a><font color=Blue>-- severity of the error.</font>
<a name="(line145)"></a>adjustErrBad <font color=Red>::</font> Parser t a <font color=Red>-></font> <font color=Cyan>(</font>String<font color=Red>-></font>String<font color=Cyan>)</font> <font color=Red>-></font> Parser t a
<a name="(line146)"></a><a name="adjustErrBad"></a>p <font color=Cyan>`adjustErrBad`</font> f <font color=Red>=</font> commit <font color=Cyan>(</font>p <font color=Cyan>`adjustErr`</font> f<font color=Cyan>)</font>
<a name="(line147)"></a>
<a name="(line148)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>6</font> <font color=Cyan>`onFail`</font> <font color=Blue>-- not sure about precedence 6?</font>
<a name="(line149)"></a><a name="onFail"></a><font color=Blue>-- | @p `onFail` q@ means parse p unless p fails in which case parse q instead.</font>
<a name="(line150)"></a><font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>
<a name="(line151)"></a><font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>
<a name="(line152)"></a><font color=Blue>-- message from that defined in p to something different.)</font>
<a name="(line153)"></a><font color=Blue>-- However, a *severe* failure in p cannot be ignored.</font>
<a name="(line154)"></a>onFail <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t a
<a name="(line155)"></a><a name="onFail"></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>-></font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line156)"></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>-></font> q ts
<a name="(line157)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>
<a name="(line158)"></a>
<a name="(line159)"></a><a name="oneOf"></a><font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>
<a name="(line160)"></a>oneOf <font color=Red>::</font> <font color=Red>[</font>Parser t a<font color=Red>]</font> <font color=Red>-></font> Parser t a
<a name="(line161)"></a>oneOf [] <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> n <font color=Red><-</font> next
<a name="(line162)"></a> <font color=Cyan>;</font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices"</font><font color=Cyan>)</font>
<a name="(line163)"></a> <font color=Cyan>}</font>
<a name="(line164)"></a><font color=Blue>--oneOf :: Show t => [Parser t a] -> Parser t a</font>
<a name="(line165)"></a><font color=Blue>--oneOf [] = do { n <- next</font>
<a name="(line166)"></a><font color=Blue>-- ; fail ("failed to parse any of the possible choices"</font>
<a name="(line167)"></a><font color=Blue>-- ++"\n next token is "++show n)</font>
<a name="(line168)"></a><font color=Blue>-- }</font>
<a name="(line169)"></a>oneOf <font color=Cyan>(</font>p<font color=Red><b>:</b></font>ps<font color=Cyan>)</font> <font color=Red>=</font> p <font color=Cyan>`onFail`</font> oneOf ps
<a name="(line170)"></a>
<a name="(line171)"></a><a name="oneOf'"></a><font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>
<a name="(line172)"></a><font color=Blue>-- report only the severe errors, and if none of those, then report</font>
<a name="(line173)"></a><font color=Blue>-- all the soft errors.</font>
<a name="(line174)"></a>oneOf' <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font> Parser t a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser t a
<a name="(line175)"></a>oneOf' ps <font color=Red>=</font> accum [] ps
<a name="(line176)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>
<a name="(line177)"></a> <font color=Green><u>case</u></font> errs <font color=Green><u>of</u></font>
<a name="(line178)"></a> [] <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"internal failure in parser (oneOf'):\n"</font>
<a name="(line179)"></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="(line180)"></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>-></font> fail e
<a name="(line181)"></a> es <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>
<a name="(line182)"></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="(line183)"></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="(line184)"></a> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line185)"></a> <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></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="(line186)"></a> <font color=Green><u>in</u></font> p ts
<a name="(line187)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>
<a name="(line188)"></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="(line189)"></a>
<a name="(line190)"></a><a name="indent"></a><font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>
<a name="(line191)"></a>indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String
<a name="(line192)"></a>indent n <font color=Red>=</font> unlines <font color=Cyan>.</font> map <font color=Cyan>(</font>replicate n <font color=Magenta>' '</font> <font color=Cyan>++</font><font color=Cyan>)</font> <font color=Cyan>.</font> lines
<a name="(line193)"></a>
<a name="(line194)"></a><a name="optional"></a><font color=Blue>-- | 'optional' indicates whether the parser succeeded through the Maybe type.</font>
<a name="(line195)"></a>optional <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t <font color=Cyan>(</font>Maybe a<font color=Cyan>)</font>
<a name="(line196)"></a>optional p <font color=Red>=</font> fmap Just p <font color=Cyan>`onFail`</font> return Nothing
<a name="(line197)"></a>
<a name="(line198)"></a><a name="exactly"></a><font color=Blue>-- | 'exactly n p' parses a precise number of items, n, using the parser</font>
<a name="(line199)"></a><font color=Blue>-- p, in sequence.</font>
<a name="(line200)"></a>exactly <font color=Red>::</font> Int <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line201)"></a>exactly <font color=Magenta>0</font> p <font color=Red>=</font> return []
<a name="(line202)"></a>exactly n p <font color=Red>=</font> return <font color=Cyan>(</font><font color=Red><b>:</b></font><font color=Cyan>)</font> <font color=Cyan>`apply`</font> p <font color=Cyan>`apply`</font> exactly <font color=Cyan>(</font>n<font color=Blue>-</font><font color=Magenta>1</font><font color=Cyan>)</font> p
<a name="(line203)"></a>
<a name="(line204)"></a><a name="many"></a><font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>
<a name="(line205)"></a><font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>
<a name="(line206)"></a>many <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line207)"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return []
<a name="(line208)"></a> <font color=Green><u>where</u></font> many1 p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> p
<a name="(line209)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font><font color=Cyan>)</font> <font color=Cyan>`apply`</font> many p
<a name="(line210)"></a> <font color=Cyan>}</font>
<a name="(line211)"></a>
<a name="(line212)"></a><a name="many1"></a><font color=Blue>-- | Parse a non-empty list of items.</font>
<a name="(line213)"></a>many1 <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line214)"></a>many1 p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> p <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"In a sequence:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font><font color=Cyan>.</font> indent <font color=Magenta>2</font><font color=Cyan>)</font>
<a name="(line215)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font><font color=Cyan>)</font> <font color=Cyan>`apply`</font> many p
<a name="(line216)"></a> <font color=Cyan>}</font>
<a name="(line217)"></a><font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n\t"++)</font>
<a name="(line218)"></a>
<a name="(line219)"></a><a name="sepBy"></a><font color=Blue>-- | Parse a list of items separated by discarded junk.</font>
<a name="(line220)"></a>sepBy <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t sep <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line221)"></a>sepBy p sep <font color=Red>=</font> <font color=Green><u>do</u></font> sepBy1 p sep <font color=Cyan>`onFail`</font> return []
<a name="(line222)"></a>
<a name="(line223)"></a><a name="sepBy1"></a><font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>
<a name="(line224)"></a>sepBy1 <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t sep <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line225)"></a>sepBy1 p sep <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> p
<a name="(line226)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font><font color=Cyan>)</font> <font color=Cyan>`apply`</font> many <font color=Cyan>(</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>sep<font color=Cyan>;</font> p<font color=Cyan>}</font><font color=Cyan>)</font>
<a name="(line227)"></a> <font color=Cyan>}</font>
<a name="(line228)"></a> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for a non-empty sequence with separators:\n\t"</font><font color=Cyan>++</font><font color=Cyan>)</font>
<a name="(line229)"></a>
<a name="(line230)"></a><a name="bracketSep"></a><font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>
<a name="(line231)"></a><font color=Blue>-- items.</font>
<a name="(line232)"></a>bracketSep <font color=Red>::</font> Parser t bra <font color=Red>-></font> Parser t sep <font color=Red>-></font> Parser t ket
<a name="(line233)"></a> <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line234)"></a>bracketSep open sep close p <font color=Red>=</font>
<a name="(line235)"></a> <font color=Green><u>do</u></font> <font color=Cyan>{</font> open<font color=Cyan>;</font> close<font color=Cyan>;</font> return [] <font color=Cyan>}</font>
<a name="(line236)"></a> <font color=Cyan>`onFail`</font>
<a name="(line237)"></a> <font color=Green><u>do</u></font> <font color=Cyan>{</font> open <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Missing opening bracket:\n\t"</font><font color=Cyan>++</font><font color=Cyan>)</font>
<a name="(line238)"></a> <font color=Cyan>;</font> x <font color=Red><-</font> p <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"After first bracket in a group:\n\t"</font><font color=Cyan>++</font><font color=Cyan>)</font>
<a name="(line239)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font><font color=Cyan>)</font> <font color=Cyan>`apply`</font>
<a name="(line240)"></a> manyFinally <font color=Cyan>(</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>sep<font color=Cyan>;</font> p<font color=Cyan>}</font><font color=Cyan>)</font>
<a name="(line241)"></a> <font color=Cyan>(</font>close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for closing bracket:\n\t"</font><font color=Cyan>++</font><font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line242)"></a> <font color=Cyan>}</font>
<a name="(line243)"></a>
<a name="(line244)"></a><a name="bracket"></a><font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>
<a name="(line245)"></a>bracket <font color=Red>::</font> Parser t bra <font color=Red>-></font> Parser t ket <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t a
<a name="(line246)"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>
<a name="(line247)"></a> <font color=Green><u>do</u></font> <font color=Cyan>{</font> open <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Missing opening bracket:\n\t"</font><font color=Cyan>++</font><font color=Cyan>)</font>
<a name="(line248)"></a> <font color=Cyan>;</font> p <font color=Cyan>`discard`</font> <font color=Cyan>(</font>close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"Missing closing bracket:\n\t"</font><font color=Cyan>++</font><font color=Cyan>)</font><font color=Cyan>)</font>
<a name="(line249)"></a> <font color=Cyan>}</font>
<a name="(line250)"></a>
<a name="(line251)"></a><a name="manyFinally"></a><font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>
<a name="(line252)"></a><font color=Blue>-- terminated by a t. Any parse failures could be due either to</font>
<a name="(line253)"></a><font color=Blue>-- a badly-formed terminator or a badly-formed element, so raise</font>
<a name="(line254)"></a><font color=Blue>-- both possible errors.</font>
<a name="(line255)"></a>manyFinally <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t z <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>
<a name="(line256)"></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>-></font>
<a name="(line257)"></a> <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>
<a name="(line258)"></a> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font>
<a name="(line259)"></a> <font color=Green><u>case</u></font> t ts <font color=Green><u>of</u></font>
<a name="(line260)"></a> <font color=Cyan>(</font>Right <font color=Green><u>_</u></font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right []<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line261)"></a> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> ts'<font color=Cyan>)</font>
<a name="(line262)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font>
<a name="(line263)"></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="(line264)"></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="(line265)"></a>
<a name="(line266)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>
<a name="(line267)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>
<a name="(line268)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>
<a name="(line269)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>
<a name="(line270)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>
<a name="(line271)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>
<a name="(line272)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser t ()
<a name="(line273)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp<font color=Red>-></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="(line274)"></a>
<a name="(line275)"></a><font color=Blue>------------------------------------------------------------------------</font>
</pre>
</html>