polyparse 1.0 → 1.1
raw patch · 65 files changed
+10936/−1825 lines, 65 files
Files
- Build.bat +5/−5
- Makefile +13/−3
- README +13/−0
- docs/changelog.html +10/−0
- docs/haddock/Text-ParserCombinators-HuttonMeijerWallace.html +1/−1
- docs/haddock/Text-ParserCombinators-Poly-Base.html +1166/−0
- docs/haddock/Text-ParserCombinators-Poly-Lazy.html +501/−0
- docs/haddock/Text-ParserCombinators-Poly-NoLeak-Lazy.html +461/−0
- docs/haddock/Text-ParserCombinators-Poly-NoLeak-Plain.html +461/−0
- docs/haddock/Text-ParserCombinators-Poly-NoLeak-State.html +600/−0
- docs/haddock/Text-ParserCombinators-Poly-NoLeak-StateLazy.html +644/−0
- docs/haddock/Text-ParserCombinators-Poly-Plain.html +461/−0
- docs/haddock/Text-ParserCombinators-Poly-State.html +563/−0
- docs/haddock/Text-ParserCombinators-Poly-StateLazy.html +639/−0
- docs/haddock/Text-ParserCombinators-Poly.html +46/−0
- docs/haddock/Text-ParserCombinators-PolyLazy.html +46/−0
- docs/haddock/Text-ParserCombinators-PolyState.html +46/−0
- docs/haddock/Text-ParserCombinators-PolyStateLazy.html +46/−0
- docs/haddock/doc-index-A.html +30/−6
- docs/haddock/doc-index-B.html +20/−4
- docs/haddock/doc-index-C.html +10/−2
- docs/haddock/doc-index-D.html +10/−2
- docs/haddock/doc-index-E.html +44/−0
- docs/haddock/doc-index-F.html +10/−2
- docs/haddock/doc-index-I.html +10/−2
- docs/haddock/doc-index-M.html +46/−6
- docs/haddock/doc-index-N.html +60/−2
- docs/haddock/doc-index-O.html +39/−7
- docs/haddock/doc-index-P.html +140/−4
- docs/haddock/doc-index-R.html +132/−4
- docs/haddock/doc-index-S.html +185/−9
- docs/haddock/index.html +113/−1
- docs/haddock/src/Text/Parse.html +181/−178
- docs/haddock/src/Text/ParserCombinators/HuttonMeijer.html +221/−218
- docs/haddock/src/Text/ParserCombinators/HuttonMeijerWallace.html +300/−297
- docs/haddock/src/Text/ParserCombinators/Poly.html +250/−238
- docs/haddock/src/Text/ParserCombinators/Poly/Base.html +194/−0
- docs/haddock/src/Text/ParserCombinators/Poly/Lazy.html +140/−0
- docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/Lazy.html +130/−0
- docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/Plain.html +109/−0
- docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/State.html +126/−0
- docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html +176/−0
- docs/haddock/src/Text/ParserCombinators/Poly/Plain.html +96/−0
- docs/haddock/src/Text/ParserCombinators/Poly/State.html +113/−0
- docs/haddock/src/Text/ParserCombinators/Poly/StateLazy.html +144/−0
- docs/haddock/src/Text/ParserCombinators/PolyLazy.html +278/−267
- docs/haddock/src/Text/ParserCombinators/PolyState.html +260/−248
- docs/haddock/src/Text/ParserCombinators/PolyStateLazy.html +293/−281
- docs/index.html +89/−19
- polyparse.cabal +14/−4
- src/Makefile +10/−1
- src/Text/ParserCombinators/HuttonMeijerWallace.hs +1/−1
- src/Text/ParserCombinators/Poly.hs +10/−1
- src/Text/ParserCombinators/Poly/Base.hs +190/−0
- src/Text/ParserCombinators/Poly/Lazy.hs +136/−0
- src/Text/ParserCombinators/Poly/NoLeak/Lazy.hs +126/−0
- src/Text/ParserCombinators/Poly/NoLeak/Plain.hs +105/−0
- src/Text/ParserCombinators/Poly/NoLeak/State.hs +122/−0
- src/Text/ParserCombinators/Poly/NoLeak/StateLazy.hs +172/−0
- src/Text/ParserCombinators/Poly/Plain.hs +92/−0
- src/Text/ParserCombinators/Poly/State.hs +109/−0
- src/Text/ParserCombinators/Poly/StateLazy.hs +140/−0
- src/Text/ParserCombinators/PolyLazy.hs +20/−12
- src/Text/ParserCombinators/PolyState.hs +9/−0
- src/Text/ParserCombinators/PolyStateLazy.hs +9/−0
Build.bat view
@@ -24,12 +24,12 @@ set LD=C:\DEV\ghc\ghc-%GHCVER%\gcc-lib\ld.exe rem Source directory for polyparse: -set SRC=C:\DEV\Haskell\lib\polyparse-1.10\src +set SRC=C:\DEV\Haskell\lib\polyparse-1.1\src rem Two very long lines (500-600 chars) follow here. rem They should not need changing. -set SRCS=Text/ParserCombinators/Poly.hs Text/ParserCombinators/PolyState.hs Text/ParserCombinators/TextParser.hs Text/ParserCombinators/PolyLazy.hs Text/ParserCombinators/PolyStateLazy.hs -set OBJS=Text/ParserCombinators/Poly.o Text/ParserCombinators/PolyState.o Text/ParserCombinators/TextParser.o Text/ParserCombinators/PolyLazy.o Text/ParserCombinators/PolyStateLazy.o +set SRCS=Text/ParserCombinators/Poly.hs Text/ParserCombinators/PolyState.hs Text/ParserCombinators/TextParser.hs Text/ParserCombinators/PolyLazy.hs Text/ParserCombinators/PolyStateLazy.hs Text/ParserCombinators/Poly/Base.hs Text/ParserCombinators/Poly/Plain.hs Text/ParserCombinators/Poly/State.hs Text/ParserCombinators/Poly/Lazy.hs Text/ParserCombinators/Poly/StateLazy.hs Text/ParserCombinators/Poly/NoLeak/Plain.hs Text/ParserCombinators/Poly/NoLeak/State.hs Text/ParserCombinators/Poly/NoLeak/Lazy.hs Text/ParserCombinators/Poly/NoLeak/StateLazy.hs +set OBJS=Text/ParserCombinators/Poly.o Text/ParserCombinators/PolyState.o Text/ParserCombinators/TextParser.o Text/ParserCombinators/PolyLazy.o Text/ParserCombinators/PolyStateLazy.o Text/ParserCombinators/Poly/Base.o Text/ParserCombinators/Poly/Plain.o Text/ParserCombinators/Poly/State.o Text/ParserCombinators/Poly/Lazy.o Text/ParserCombinators/Poly/StateLazy.o Text/ParserCombinators/Poly/NoLeak/Plain.o Text/ParserCombinators/Poly/NoLeak/State.o Text/ParserCombinators/Poly/NoLeak/Lazy.o Text/ParserCombinators/Poly/NoLeak/StateLazy.o rem -- Get on with the real work -- @@ -44,7 +44,7 @@ if "%GHCVER%"=="6.6.1" COPY polyparse.cabal %SRC%\pkg.conf if "%GHCVER%"=="6.6.2" COPY polyparse.cabal %SRC%\pkg.conf cd %SRC% -%GHC% --make -cpp -i. -package-name polyparse-1.00 %SRCS% +%GHC% --make -cpp -i. -package-name polyparse-1.1 %SRCS% %AR% r libHSpolyparse.a %OBJS% rem -- Create library file for GHCi @@ -89,7 +89,7 @@ rem -- Remove GHC package for polyparse -- :Remove -%GHCPKG% --remove-package polyparse-1.00 +%GHCPKG% --remove-package polyparse-1.1 goto Exit
Makefile view
@@ -1,10 +1,11 @@ SOFTWARE = polyparse-VERSION = 1.0+VERSION = 1.1 CPP = cpp -traditional #CPP = cpphs --text # useful e.g. on MacOS X -DIRS = Text Text/ParserCombinators+DIRS = Text Text/ParserCombinators Text/ParserCombinators/Poly \+ Text/ParserCombinators/Poly/NoLeak SRCS = \ src/Text/ParserCombinators/HuttonMeijer.hs \@@ -13,6 +14,15 @@ src/Text/ParserCombinators/PolyState.hs \ src/Text/ParserCombinators/PolyLazy.hs \ src/Text/ParserCombinators/PolyStateLazy.hs \+ src/Text/ParserCombinators/Poly/Base.hs \+ src/Text/ParserCombinators/Poly/Plain.hs \+ src/Text/ParserCombinators/Poly/Lazy.hs \+ src/Text/ParserCombinators/Poly/State.hs \+ src/Text/ParserCombinators/Poly/StateLazy.hs \+ src/Text/ParserCombinators/Poly/NoLeak/Plain.hs \+ src/Text/ParserCombinators/Poly/NoLeak/Lazy.hs \+ src/Text/ParserCombinators/Poly/NoLeak/State.hs \+ src/Text/ParserCombinators/Poly/NoLeak/StateLazy.hs \ src/Text/Parse.hs TOOLSRCS = \@@ -69,7 +79,7 @@ done for file in $(SRCS); \ do $(CPP) -D__NHC__ $$file >$$file.uncpp; \- HsColour -anchorHTML $$file >docs/haddock/`dirname $$file`/`basename $$file .hs`.html; \+ HsColour -anchor -html $$file >docs/haddock/`dirname $$file`/`basename $$file .hs`.html; \ done haddock --html --title=$(SOFTWARE) --odir=docs/haddock \ --package=$(SOFTWARE) \
README view
@@ -44,5 +44,18 @@ PolyState arbitrary token type + running state. PolyLazy arbitrary token type + lazy return of results. PolyStateLazy arbitrary token type + running state + lazy results.+ src/Text/ParserCombinators/Poly+ Base A class-based interface to more specific parser types.+ Plain The instance for simple polymorphic parsers.+ Lazy The instance for lazy polymorphic parsers.+ State The instance for strict polymorphic parsers with state.+ StateLazy The instance for lazy polymorphic parsers with state.+ Stream An experimental instance for stream-based parsers.+ src/Text/ParserCombinators/Poly/NoLeak+ An experimental attempt to plug more space leaks.+ Plain The instance for simple non-leaking parsers.+ Lazy The instance for lazy non-leaking parsers.+ State The instance for strict non-leaking parsers with state.+ StateLazy The instance for lazy non-leaking parsers with state. ----
docs/changelog.html view
@@ -13,6 +13,16 @@ </center> <hr> +<h3>Changes in polyparse-1.1</h3>+<p>+<ul>+<li>Much improved the laziness of the PolyLazy combinators.+<li>Addition of a class-based interface to the Poly libraries, to+ reduce code duplication amongst the variations, and to allow for+ more experimentation with different implementations.+<li>Several new experimental implementations of the interface.+</ul>+ <h3>Changes in polyparse-1.0</h3> <p> <ul>
docs/haddock/Text-ParserCombinators-HuttonMeijerWallace.html view
@@ -113,7 +113,7 @@ >This library of monadic parser combinators is based on the ones defined by Graham Hutton and Erik Meijer. It has been extended by Malcolm Wallace to use an abstract token type (no longer just a- string) as input, and to incorporate a State Transformer monad, useful+ string) as input, and to incorporate state in the monad, useful for symbol tables, macros, and so on. Basic facilities for error reporting have also been added, and later extended by Graham Klyne to return the errors through an <TT
+ docs/haddock/Text-ParserCombinators-Poly-Base.html view
@@ -0,0 +1,1166 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.Base</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.Base</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The PolyParse class+</A+></DT+><DT+><A HREF="#2"+>Combinators general to all parser types.+</A+></DT+><DD+><DL+><DT+><A HREF="#3"+>Simple combinators+</A+></DT+><DT+><A HREF="#4"+>Error-handling+</A+></DT+><DT+><A HREF="#5"+>Choices+</A+></DT+><DT+><A HREF="#6"+>Sequences+</A+></DT+></DL+></DD+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>class</SPAN+> (Functor p, Monad p) => <A HREF="#t%3APolyParse"+>PolyParse</A+> p <SPAN CLASS="keyword"+>where</SPAN+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><A HREF="#v%3Acommit"+>commit</A+> :: p a -> p a</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AadjustErr"+>adjustErr</A+> :: p a -> (String -> String) -> p a</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AonFail"+>onFail</A+> :: p a -> p a -> p a</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AoneOf%27"+>oneOf'</A+> :: [(String, p a)] -> p a</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Aapply"+>apply</A+> :: p (a -> b) -> p a -> p b</TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Adiscard"+>discard</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p b -> p a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AfailBad"+>failBad</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => String -> p a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AadjustErrBad"+>adjustErrBad</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> (String -> String) -> p a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Aindent"+>indent</A+> :: Int -> String -> String</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AoneOf"+>oneOf</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => [p a] -> p a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Aoptional"+>optional</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p (Maybe a)</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Aexactly"+>exactly</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => Int -> p a -> p [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Amany"+>many</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Amany1"+>many1</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AsepBy"+>sepBy</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p sep -> p [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AsepBy1"+>sepBy1</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p sep -> p [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AbracketSep"+>bracketSep</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p bra -> p sep -> p ket -> p a -> p [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Abracket"+>bracket</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p bra -> p ket -> p a -> p a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AmanyFinally"+>manyFinally</A+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p z -> p [a]</TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The PolyParse class+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>class</SPAN+> (Functor p, Monad p) => <A NAME="t%3APolyParse"+></A+><B+>PolyParse</B+> p <SPAN CLASS="keyword"+>where</SPAN+></TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#PolyParse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+><P+>The <TT+>PolyParse</TT+> class is an abstraction over all the current+ concrete representations of monadic parser combinators in this+ package. The common feature is two-level error-handling.+ Some primitives must be implemented specific to each parser type+ (e.g. depending on whether the parser has a running state, or+ whether it is lazy). But given those primitives, large numbers of+ combinators do not depend any further on the internal structure of+ the particular parser.+</P+><P+>There are two additional basic combinators that we expect to be implemented+ afresh for every concrete type, but which (for technical reasons)+ cannot be class methods. They are <TT+>next</TT+> and <TT+>satisfy</TT+>.+</P+></TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="section4"+>Methods</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Acommit"+></A+><B+>commit</B+> :: p a -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#commit"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Commit is a way of raising the severity of any errors found within+ its argument. Used in the middle of a parser definition, it means that+ any operations prior to commitment fail softly, but after commitment,+ they fail hard.+</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AadjustErr"+></A+><B+>adjustErr</B+> :: p a -> (String -> String) -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#adjustErr"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+><TT+>p <TT+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AadjustErr"+>adjustErr</A+></TT+> f</TT+> applies the transformation <TT+>f</TT+> to any error message+ generated in <TT+>p</TT+>, having no effect if <TT+>p</TT+> succeeds.+</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AonFail"+></A+><B+>onFail</B+> :: p a -> p a -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#onFail"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+><TT+>p <TT+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AonFail"+>onFail</A+></TT+> q</TT+> means parse p, unless p fails, in which case+ parse q instead.+ Can be chained together to give multiple attempts to parse something.+ (Note that q could itself be a failing parser, e.g. to change the error+ message from that defined in p to something different.)+ However, a severe failure in p cannot be ignored.+</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AoneOf%27"+></A+><B+>oneOf'</B+> :: [(String, p a)] -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#oneOf%27"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Parse the first alternative that succeeds, but if none succeed,+ report only the severe errors, and if none of those, then report+ all the soft errors.+</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aapply"+></A+><B+>apply</B+> :: p (a -> b) -> p a -> p b</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#apply"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parsed function to a parsed value.+ Rather like ordinary function application lifted into parsers.+</TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:PolyParse')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:PolyParse" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="2"+>Combinators general to all parser types.+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>Simple combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Adiscard"+></A+><B+>discard</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p b -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#discard"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+><TT+>x <TT+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Adiscard"+>discard</A+></TT+> y</TT+> parses both x and y, but discards the result of y.+ Rather like <TT+>const</TT+> lifted into parsers.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="4"+>Error-handling+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AfailBad"+></A+><B+>failBad</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => String -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#failBad"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>When a simple fail is not strong enough, use failBad for emphasis.+ An emphasised (severe) error cannot be overridden by choice+ operators.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AadjustErrBad"+></A+><B+>adjustErrBad</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> (String -> String) -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#adjustErrBad"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+><TT+>adjustErrBad</TT+> is just like <TT+>adjustErr</TT+> except it also raises the+ severity of the error.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aindent"+></A+><B+>indent</B+> :: Int -> String -> String</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#indent"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Helper for formatting error messages: indents all lines by a fixed amount.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="5"+>Choices+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AoneOf"+></A+><B+>oneOf</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => [p a] -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#oneOf"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Parse the first alternative in the list that succeeds.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aoptional"+></A+><B+>optional</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p (Maybe a)</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#optional"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+><TT+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Aoptional"+>optional</A+></TT+> indicates whether the parser succeeded through the Maybe type.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="6"+>Sequences+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aexactly"+></A+><B+>exactly</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => Int -> p a -> p [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#exactly"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'exactly n p' parses precisely n items, using the parser p, in sequence.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Amany"+></A+><B+>many</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#many"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'many p' parses a list of elements with individual parser p.+ Cannot fail, since an empty list is a valid return value.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Amany1"+></A+><B+>many1</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#many1"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Parse a non-empty list of items.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AsepBy"+></A+><B+>sepBy</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p sep -> p [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#sepBy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Parse a list of items separated by discarded junk.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AsepBy1"+></A+><B+>sepBy1</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p sep -> p [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#sepBy1"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Parse a non-empty list of items separated by discarded junk.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AbracketSep"+></A+><B+>bracketSep</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p bra -> p sep -> p ket -> p a -> p [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#bracketSep"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Parse a list of items, discarding the start, end, and separator+ items.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Abracket"+></A+><B+>bracket</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p bra -> p ket -> p a -> p a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#bracket"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Parse a bracketed item, discarding the brackets.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AmanyFinally"+></A+><B+>manyFinally</B+> :: <A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> p => p a -> p z -> p [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Base.html#manyFinally"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'manyFinally e t' parses a possibly-empty sequence of e's,+ terminated by a t. The final t is discarded. Any parse failures+ could be due either to a badly-formed terminator or a badly-formed+ element, so it raises both possible errors.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-Lazy.html view
@@ -0,0 +1,501 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.Lazy</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/Lazy.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.Lazy</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype.+</A+></DT+><DD+><DL+><DT+><A HREF="#2"+>basic parsers+</A+></DT+><DT+><A HREF="#3"+>Re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#4"+>Re-export all more general combinators+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> t a = <A HREF="#v%3AP"+>P</A+> ([t] -> (Either String a, [t]))</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t a -> [t] -> (a, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AmanyFinally"+>manyFinally</A+> :: <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t a -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t z -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype.+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="doc"+>When applied, these parsers do not return explicit failure.+ An exception is+ raised instead. This allows partial results to be returned+ before a full parse is complete.+ One of the key ways to ensure that your parser is properly lazy,+ is to parse the initial portion of text returning a function, then+ use the <TT+>apply</TT+> combinator to build the final value.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Lazy.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>The <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting. It can be used for arbitrary token types, not just+ String input. (If you require a running state, use module PolyStateLazy+ instead.)+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> ([t] -> (Either String a, [t]))</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t a -> [t] -> (a, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Lazy.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an input token sequence. The parser cannot return+ an error value explicitly, so errors raise an exception. Thus, results+ can be partial (lazily constructed, but containing undefined).+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="2"+>basic parsers+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Lazy.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>One token satifying a predicate+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AmanyFinally"+></A+><B+>manyFinally</B+> :: <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t a -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t z -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Lazy.html#manyFinally"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'manyFinally e t' parses a possibly-empty sequence of e's,+ terminated by a t. Any parse failures could be due either to+ a badly-formed terminator or a badly-formed element, so raise+ both possible errors.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>Re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Parser</A+> t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Lazy.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="4"+>Re-export all more general combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-NoLeak-Lazy.html view
@@ -0,0 +1,461 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.NoLeak.Lazy</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Lazy.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.NoLeak.Lazy</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype+</A+></DT+><DD+><DL+><DT+><A HREF="#2"+>basic parsers+</A+></DT+><DT+><A HREF="#3"+>re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#4"+>Re-export all more general combinators+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> t a = <A HREF="#v%3AP"+>P</A+> ([t] -> Result [t] a)</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t a -> [t] -> (a, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Anext"+>next</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Lazy.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>This <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting. It can be used for arbitrary token types, not just+ String input. (If you require a running state, use module PolyState+ instead)+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> ([t] -> Result [t] a)</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t a -> [t] -> (a, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Lazy.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an input token sequence.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="2"+>basic parsers+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Anext"+></A+><B+>next</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Lazy.html#next"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Lazy.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Parser</A+> t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Lazy.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="4"+>Re-export all more general combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-NoLeak-Plain.html view
@@ -0,0 +1,461 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.NoLeak.Plain</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Plain.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.NoLeak.Plain</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype+</A+></DT+><DD+><DL+><DT+><A HREF="#2"+>basic parsers+</A+></DT+><DT+><A HREF="#3"+>re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#4"+>Re-export all more general combinators+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> t a = <A HREF="#v%3AP"+>P</A+> ([t] -> Result [t] a)</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t a -> [t] -> (Either String a, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Anext"+>next</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Plain.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>This <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting. It can be used for arbitrary token types, not just+ String input. (If you require a running state, use module PolyState+ instead)+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> ([t] -> Result [t] a)</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t a -> [t] -> (Either String a, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Plain.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an input token sequence.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="2"+>basic parsers+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Anext"+></A+><B+>next</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Plain.html#next"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Plain.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Parser</A+> t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/Plain.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="4"+>Re-export all more general combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-NoLeak-State.html view
@@ -0,0 +1,600 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.NoLeak.State</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.NoLeak.State</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype+</A+></DT+><DD+><DL+><DT+><A HREF="#2"+>basic parsers+</A+></DT+><DT+><A HREF="#3"+>State-handling+</A+></DT+><DT+><A HREF="#4"+>re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#5"+>Re-export all more general combinators+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> s t a = <A HREF="#v%3AP"+>P</A+> (s -> [t] -> Result [t] s a)</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (Either String a, s, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Anext"+>next</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstUpdate"+>stUpdate</A+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstQuery"+>stQuery</A+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstGet"+>stGet</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t s</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>This <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting. It can be used for arbitrary token types, not just+ String input. (If you require a running state, use module PolyState+ instead)+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> (s -> [t] -> Result [t] s a)</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (Either String a, s, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an input token sequence.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="2"+>basic parsers+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Anext"+></A+><B+>next</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#next"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>State-handling+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstUpdate"+></A+><B+>stUpdate</B+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#stUpdate"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Update the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstQuery"+></A+><B+>stQuery</B+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#stQuery"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Query the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstGet"+></A+><B+>stGet</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t s</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#stGet"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Deliver the entire internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="4"+>re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/State.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="5"+>Re-export all more general combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-NoLeak-StateLazy.html view
@@ -0,0 +1,644 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.NoLeak.StateLazy</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype+</A+></DT+><DD+><DL+><DT+><A HREF="#2"+>basic parsers+</A+></DT+><DT+><A HREF="#3"+>State-handling+</A+></DT+><DT+><A HREF="#4"+>re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#5"+>Re-export all more general combinators+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> s t a = <A HREF="#v%3AP"+>P</A+> (s -> [t] -> Result [t] s a)</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (a, s, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Anext"+>next</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AmanyFinally"+>manyFinally</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t a -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t z -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstUpdate"+>stUpdate</A+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstQuery"+>stQuery</A+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstGet"+>stGet</A+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t s</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>This <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting. It can be used for arbitrary token types, not just+ String input. (If you require a running state, use module PolyState+ instead)+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> (s -> [t] -> Result [t] s a)</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (a, s, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an input token sequence.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="2"+>basic parsers+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Anext"+></A+><B+>next</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#next"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AmanyFinally"+></A+><B+>manyFinally</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t a -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t z -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#manyFinally"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>State-handling+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstUpdate"+></A+><B+>stUpdate</B+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#stUpdate"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Update the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstQuery"+></A+><B+>stQuery</B+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#stQuery"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Query the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstGet"+></A+><B+>stGet</B+> :: <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t s</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#stGet"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Deliver the entire internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="4"+>re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="5"+>Re-export all more general combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-Plain.html view
@@ -0,0 +1,461 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.Plain</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/Plain.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.Plain</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype+</A+></DT+><DD+><DL+><DT+><A HREF="#2"+>basic parsers+</A+></DT+><DT+><A HREF="#3"+>re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#4"+>Re-export all more general combinators+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> t a = <A HREF="#v%3AP"+>P</A+> ([t] -> (EitherE String a, [t]))</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t a -> [t] -> (Either String a, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Anext"+>next</A+> :: <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Plain.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>This <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting. It can be used for arbitrary token types, not just+ String input. (If you require a running state, use module PolyState+ instead)+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> ([t] -> (EitherE String a, [t]))</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t a -> [t] -> (Either String a, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Plain.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an input token sequence.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="2"+>basic parsers+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Anext"+></A+><B+>next</B+> :: <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Plain.html#next"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Plain.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Parser</A+> t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/Plain.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="4"+>Re-export all more general combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-State.html view
@@ -0,0 +1,563 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.State</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.State</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype+</A+></DT+><DD+><DL+><DT+><A HREF="#2"+>basic parsers+</A+></DT+><DT+><A HREF="#3"+>State-handling+</A+></DT+><DT+><A HREF="#4"+>Re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#5"+>Re-export all more general combinators.+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> s t a = <A HREF="#v%3AP"+>P</A+> (s -> [t] -> (EitherE String a, s, [t]))</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (Either String a, s, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstUpdate"+>stUpdate</A+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstQuery"+>stQuery</A+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstGet"+>stGet</A+> :: <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t s</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>The <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting and a running state. It can be used for arbitrary token+ types, not just String input.+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> (s -> [t] -> (EitherE String a, s, [t]))</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (Either String a, s, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an initial state and input token sequence.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="2"+>basic parsers+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>State-handling+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstUpdate"+></A+><B+>stUpdate</B+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html#stUpdate"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Update the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstQuery"+></A+><B+>stQuery</B+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html#stQuery"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Query the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstGet"+></A+><B+>stGet</B+> :: <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t s</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html#stGet"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Deliver the entire internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="4"+>Re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/State.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="5"+>Re-export all more general combinators.+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
+ docs/haddock/Text-ParserCombinators-Poly-StateLazy.html view
@@ -0,0 +1,639 @@+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">+<!--Rendered using the Haskell Html Library v0.2-->+<HTML+><HEAD+><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8"+><TITLE+>Text.ParserCombinators.Poly.StateLazy</TITLE+><LINK HREF="haddock.css" REL="stylesheet" TYPE="text/css"+><SCRIPT SRC="haddock.js" TYPE="text/javascript"+></SCRIPT+></HEAD+><BODY+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="topbar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><IMG SRC="haskell_icon.gif" WIDTH="16" HEIGHT="16" ALT=" "+></TD+><TD CLASS="title"+>polyparse</TD+><TD CLASS="topbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html"+>Source code</A+></TD+><TD CLASS="topbut"+><A HREF="index.html"+>Contents</A+></TD+><TD CLASS="topbut"+><A HREF="doc-index.html"+>Index</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="modulebar"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD+><FONT SIZE="6"+>Text.ParserCombinators.Poly.StateLazy</FONT+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="section4"+><B+>Contents</B+></TD+></TR+><TR+><TD+><DL+><DT+><A HREF="#1"+>The Parser datatype.+</A+></DT+><DT+><A HREF="#2"+>Combinators:+</A+></DT+><DD+><DL+><DT+><A HREF="#3"+>Primitives+</A+></DT+><DT+><A HREF="#4"+>State-handling+</A+></DT+><DT+><A HREF="#5"+>Re-parsing+</A+></DT+></DL+></DD+><DT+><A HREF="#6"+>Re-export all more general combinators+</A+></DT+></DL+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+>Synopsis</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="decl"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A HREF="#t%3AParser"+>Parser</A+> s t a = <A HREF="#v%3AP"+>P</A+> (s -> [t] -> (Either String a, s, [t]))</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3ArunParser"+>runParser</A+> :: <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (a, s, [t])</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Anext"+>next</A+> :: <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Asatisfy"+>satisfy</A+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstUpdate"+>stUpdate</A+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstQuery"+>stQuery</A+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t a</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3AstGet"+>stGet</A+> :: <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t s</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+><A HREF="#v%3Areparse"+>reparse</A+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="1"+>The Parser datatype.+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="doc"+>Parsers do not return explicit failure. An exception is raised+ instead. This allows partial results to be returned before a+ full parse is complete.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><SPAN CLASS="keyword"+>newtype</SPAN+> <A NAME="t%3AParser"+></A+><B+>Parser</B+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#Parser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="0" CELLPADDING="0"+><TR+><TD CLASS="ndoc"+>The <TT+>Parser</TT+> datatype is a fairly generic parsing monad with error+ reporting and a running state. It can be used for arbitrary token+ types, not just String input.+</TD+></TR+><TR+><TD CLASS="section4"+>Constructors</TD+></TR+><TR+><TD CLASS="body"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="arg"+><A NAME="v%3AP"+></A+><B+>P</B+> (s -> [t] -> (Either String a, s, [t]))</TD+><TD CLASS="rdoc"+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="section4"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'i:Parser')" ALT="show/hide"+> Instances</TD+></TR+><TR+><TD CLASS="body"+><DIV ID="i:Parser" STYLE="display:block;"+><TABLE CLASS="vanilla" CELLSPACING="1" CELLPADDING="0"+><TR+><TD CLASS="decl"+>Functor (<A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+>Monad (<A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+><TR+><TD CLASS="decl"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>PolyParse</A+> (<A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t)</TD+></TR+></TABLE+></DIV+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3ArunParser"+></A+><B+>runParser</B+> :: <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t a -> s -> [t] -> (a, s, [t])</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#runParser"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Apply a parser to an initial state and input token sequence.+ The parser cannot return an error value explicitly, so errors+ raise an exception. Thus, results can be partial (lazily constructed,+ but containing undefined).+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="2"+>Combinators:+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="3"+>Primitives+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Anext"+></A+><B+>next</B+> :: <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#next"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Yield one token.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Asatisfy"+></A+><B+>satisfy</B+> :: (t -> Bool) -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t t</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#satisfy"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Yield one token if it satisfies a predicate.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="4"+>State-handling+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstUpdate"+></A+><B+>stUpdate</B+> :: (s -> s) -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#stUpdate"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Update the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstQuery"+></A+><B+>stQuery</B+> :: (s -> a) -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t a</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#stQuery"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Query the internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3AstGet"+></A+><B+>stGet</B+> :: <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t s</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#stGet"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Deliver the entire internal state.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section2"+><A NAME="5"+>Re-parsing+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Areparse"+></A+><B+>reparse</B+> :: [t] -> <A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Parser</A+> s t ()</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly/StateLazy.html#reparse"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>Push some tokens back onto the front of the input stream and reparse.+ This is useful e.g. for recursively expanding macros. When the+ user-parser recognises a macro use, it can lookup the macro+ expansion from the parse state, lex it, and then stuff the+ lexed expansion back down into the parser.+</TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="section1"+><A NAME="6"+>Re-export all more general combinators+</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="decl"+>module <A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="botbar"+>Produced by <A HREF="http://www.haskell.org/haddock/"+>Haddock</A+> version 0.8</TD+></TR+></TABLE+></BODY+></HTML+>
docs/haddock/Text-ParserCombinators-Poly.html view
@@ -334,6 +334,20 @@ ></TR ><TR ><TD CLASS="decl"+><A HREF="#v%3Aexactly"+>exactly</A+> :: Int -> <A HREF="Text-ParserCombinators-Poly.html#t%3AParser"+>Parser</A+> t a -> <A HREF="Text-ParserCombinators-Poly.html#t%3AParser"+>Parser</A+> t [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl" ><A HREF="#v%3Amany" >many</A > :: <A HREF="Text-ParserCombinators-Poly.html#t%3AParser"@@ -1083,6 +1097,38 @@ >Sequences </A ></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aexactly"+></A+><B+>exactly</B+> :: Int -> <A HREF="Text-ParserCombinators-Poly.html#t%3AParser"+>Parser</A+> t a -> <A HREF="Text-ParserCombinators-Poly.html#t%3AParser"+>Parser</A+> t [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/Poly.html#exactly"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'exactly n p' parses a precise number of items, n, using the parser+ p, in sequence.+</TD ></TR ><TR ><TD CLASS="s15"
docs/haddock/Text-ParserCombinators-PolyLazy.html view
@@ -334,6 +334,20 @@ ></TR ><TR ><TD CLASS="decl"+><A HREF="#v%3Aexactly"+>exactly</A+> :: Int -> <A HREF="Text-ParserCombinators-PolyLazy.html#t%3AParser"+>Parser</A+> t a -> <A HREF="Text-ParserCombinators-PolyLazy.html#t%3AParser"+>Parser</A+> t [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl" ><A HREF="#v%3Amany" >many</A > :: <A HREF="Text-ParserCombinators-PolyLazy.html#t%3AParser"@@ -1103,6 +1117,38 @@ >Sequences </A ></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aexactly"+></A+><B+>exactly</B+> :: Int -> <A HREF="Text-ParserCombinators-PolyLazy.html#t%3AParser"+>Parser</A+> t a -> <A HREF="Text-ParserCombinators-PolyLazy.html#t%3AParser"+>Parser</A+> t [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/PolyLazy.html#exactly"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'exactly n p' parses a precise number of items, n, using the parser+ p, in sequence.+</TD ></TR ><TR ><TD CLASS="s15"
docs/haddock/Text-ParserCombinators-PolyState.html view
@@ -325,6 +325,20 @@ ></TR ><TR ><TD CLASS="decl"+><A HREF="#v%3Aexactly"+>exactly</A+> :: Int -> <A HREF="Text-ParserCombinators-PolyState.html#t%3AParser"+>Parser</A+> s t a -> <A HREF="Text-ParserCombinators-PolyState.html#t%3AParser"+>Parser</A+> s t [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl" ><A HREF="#v%3Amany" >many</A > :: <A HREF="Text-ParserCombinators-PolyState.html#t%3AParser"@@ -1074,6 +1088,38 @@ >Sequences </A ></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aexactly"+></A+><B+>exactly</B+> :: Int -> <A HREF="Text-ParserCombinators-PolyState.html#t%3AParser"+>Parser</A+> s t a -> <A HREF="Text-ParserCombinators-PolyState.html#t%3AParser"+>Parser</A+> s t [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/PolyState.html#exactly"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'exactly n p' parses a precise number of items, n, using the parser+ p, in sequence.+</TD ></TR ><TR ><TD CLASS="s15"
docs/haddock/Text-ParserCombinators-PolyStateLazy.html view
@@ -339,6 +339,20 @@ ></TR ><TR ><TD CLASS="decl"+><A HREF="#v%3Aexactly"+>exactly</A+> :: Int -> <A HREF="Text-ParserCombinators-PolyStateLazy.html#t%3AParser"+>Parser</A+> s t a -> <A HREF="Text-ParserCombinators-PolyStateLazy.html#t%3AParser"+>Parser</A+> s t [a]</TD+></TR+><TR+><TD CLASS="s8"+></TD+></TR+><TR+><TD CLASS="decl" ><A HREF="#v%3Amany" >many</A > :: <A HREF="Text-ParserCombinators-PolyStateLazy.html#t%3AParser"@@ -1138,6 +1152,38 @@ >Sequences </A ></TD+></TR+><TR+><TD CLASS="s15"+></TD+></TR+><TR+><TD CLASS="topdecl"+><TABLE CLASS="declbar"+><TR+><TD CLASS="declname"+><A NAME="v%3Aexactly"+></A+><B+>exactly</B+> :: Int -> <A HREF="Text-ParserCombinators-PolyStateLazy.html#t%3AParser"+>Parser</A+> s t a -> <A HREF="Text-ParserCombinators-PolyStateLazy.html#t%3AParser"+>Parser</A+> s t [a]</TD+><TD CLASS="declbut"+><A HREF="src/Text/ParserCombinators/PolyStateLazy.html#exactly"+>Source</A+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD CLASS="doc"+>'exactly n p' parses a precise number of items, n, using the parser+ p, in sequence.+</TD ></TR ><TR ><TD CLASS="s15"
docs/haddock/doc-index-A.html view
@@ -137,13 +137,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AadjustErr"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AadjustErr" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AadjustErr" >Text.ParserCombinators.PolyState</A@@ -151,7 +159,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AadjustErr" >Text.ParserCombinators.PolyStateLazy</A@@ -173,13 +181,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AadjustErrBad"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AadjustErrBad" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AadjustErrBad" >Text.ParserCombinators.PolyState</A@@ -187,7 +203,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AadjustErrBad" >Text.ParserCombinators.PolyStateLazy</A@@ -217,13 +233,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Aapply"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Aapply" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Aapply" >Text.ParserCombinators.PolyState</A@@ -231,7 +255,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Aapply" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-B.html view
@@ -153,13 +153,21 @@ ><TD CLASS="indexannot" >4 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Abracket"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Abracket" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->5 (Function)</TD+>6 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Abracket" >Text.ParserCombinators.PolyState</A@@ -167,7 +175,7 @@ ></TR ><TR ><TD CLASS="indexannot"->6 (Function)</TD+>7 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Abracket" >Text.ParserCombinators.PolyStateLazy</A@@ -189,13 +197,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AbracketSep"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AbracketSep" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AbracketSep" >Text.ParserCombinators.PolyState</A@@ -203,7 +219,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AbracketSep" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-C.html view
@@ -233,13 +233,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Acommit"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Acommit" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Acommit" >Text.ParserCombinators.PolyState</A@@ -247,7 +255,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Acommit" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-D.html view
@@ -145,13 +145,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Adiscard"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Adiscard" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Adiscard" >Text.ParserCombinators.PolyState</A@@ -159,7 +167,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Adiscard" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-E.html view
@@ -145,6 +145,50 @@ >Text.ParserCombinators.HuttonMeijerWallace</A ></TD ></TR+><TR+><TD CLASS="indexentry" COLSPAN="2"+>exactly</TD+></TR+><TR+><TD CLASS="indexannot"+>1 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly.html#v%3Aexactly"+>Text.ParserCombinators.Poly</A+>, Text.Parse</TD+></TR+><TR+><TD CLASS="indexannot"+>2 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Aexactly"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Aexactly"+>Text.ParserCombinators.PolyLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-PolyState.html#v%3Aexactly"+>Text.ParserCombinators.PolyState</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Aexactly"+>Text.ParserCombinators.PolyStateLazy</A+></TD+></TR ></TABLE ></TD ></TR
docs/haddock/doc-index-F.html view
@@ -137,13 +137,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AfailBad"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AfailBad" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AfailBad" >Text.ParserCombinators.PolyState</A@@ -151,7 +159,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AfailBad" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-I.html view
@@ -153,13 +153,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Aindent"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Aindent" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Aindent" >Text.ParserCombinators.PolyState</A@@ -167,7 +175,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Aindent" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-M.html view
@@ -153,13 +153,21 @@ ><TD CLASS="indexannot" >4 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Amany"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Amany" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->5 (Function)</TD+>6 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Amany" >Text.ParserCombinators.PolyState</A@@ -167,7 +175,7 @@ ></TR ><TR ><TD CLASS="indexannot"->6 (Function)</TD+>7 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Amany" >Text.ParserCombinators.PolyStateLazy</A@@ -205,13 +213,21 @@ ><TD CLASS="indexannot" >4 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Amany1"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Amany1" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->5 (Function)</TD+>6 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Amany1" >Text.ParserCombinators.PolyState</A@@ -219,7 +235,7 @@ ></TR ><TR ><TD CLASS="indexannot"->6 (Function)</TD+>7 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Amany1" >Text.ParserCombinators.PolyStateLazy</A@@ -241,13 +257,37 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AmanyFinally"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Lazy.html#v%3AmanyFinally"+>Text.ParserCombinators.Poly.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3AmanyFinally"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AmanyFinally" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>6 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AmanyFinally" >Text.ParserCombinators.PolyState</A@@ -255,7 +295,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>7 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AmanyFinally" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-N.html view
@@ -153,13 +153,61 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#v%3Anext"+>Text.ParserCombinators.Poly.NoLeak.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#v%3Anext"+>Text.ParserCombinators.Poly.NoLeak.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3Anext"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3Anext"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>6 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Plain.html#v%3Anext"+>Text.ParserCombinators.Poly.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>7 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3Anext"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>8 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Anext" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>9 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Anext" >Text.ParserCombinators.PolyState</A@@ -167,10 +215,20 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>10 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Anext" >Text.ParserCombinators.PolyStateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>11 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Lazy.html#v%3Anext"+>Text.ParserCombinators.Poly.Lazy</A+>, <A HREF="Text-ParserCombinators-Poly-State.html#v%3Anext"+>Text.ParserCombinators.Poly.State</A ></TD ></TR ><TR
docs/haddock/doc-index-O.html view
@@ -137,13 +137,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AonFail"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AonFail" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AonFail" >Text.ParserCombinators.PolyState</A@@ -151,7 +159,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AonFail" >Text.ParserCombinators.PolyStateLazy</A@@ -173,13 +181,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AoneOf"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AoneOf" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AoneOf" >Text.ParserCombinators.PolyState</A@@ -187,7 +203,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AoneOf" >Text.ParserCombinators.PolyStateLazy</A@@ -209,13 +225,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AoneOf%27"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AoneOf%27" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AoneOf%27" >Text.ParserCombinators.PolyState</A@@ -223,7 +247,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AoneOf%27" >Text.ParserCombinators.PolyStateLazy</A@@ -265,13 +289,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3Aoptional"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Aoptional" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Aoptional" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-P.html view
@@ -153,13 +153,77 @@ ><TD CLASS="indexannot" >4 (Data Constructor)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Lazy.html#v%3AP"+>Text.ParserCombinators.Poly.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Data Constructor)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#v%3AP"+>Text.ParserCombinators.Poly.NoLeak.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>6 (Data Constructor)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#v%3AP"+>Text.ParserCombinators.Poly.NoLeak.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>7 (Data Constructor)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3AP"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>8 (Data Constructor)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3AP"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>9 (Data Constructor)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Plain.html#v%3AP"+>Text.ParserCombinators.Poly.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>10 (Data Constructor)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#v%3AP"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>11 (Data Constructor)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3AP"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>12 (Data Constructor)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AP" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->5 (Data Constructor)</TD+>13 (Data Constructor)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AP" >Text.ParserCombinators.PolyState</A@@ -167,7 +231,7 @@ ></TR ><TR ><TD CLASS="indexannot"->6 (Data Constructor)</TD+>14 (Data Constructor)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AP" >Text.ParserCombinators.PolyStateLazy</A@@ -213,13 +277,77 @@ ><TD CLASS="indexannot" >4 (Type/Class)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Lazy.html#t%3AParser"+>Text.ParserCombinators.Poly.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Type/Class)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#t%3AParser"+>Text.ParserCombinators.Poly.NoLeak.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>6 (Type/Class)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#t%3AParser"+>Text.ParserCombinators.Poly.NoLeak.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>7 (Type/Class)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#t%3AParser"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>8 (Type/Class)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#t%3AParser"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>9 (Type/Class)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Plain.html#t%3AParser"+>Text.ParserCombinators.Poly.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>10 (Type/Class)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#t%3AParser"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>11 (Type/Class)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#t%3AParser"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>12 (Type/Class)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#t%3AParser" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->5 (Type/Class)</TD+>13 (Type/Class)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#t%3AParser" >Text.ParserCombinators.PolyState</A@@ -227,11 +355,19 @@ ></TR ><TR ><TD CLASS="indexannot"->6 (Type/Class)</TD+>14 (Type/Class)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#t%3AParser" >Text.ParserCombinators.PolyStateLazy</A ></TD+></TR+><TR+><TD CLASS="indexentry"+>PolyParse</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#t%3APolyParse"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD ></TR ><TR ><TD CLASS="indexentry" COLSPAN="2"
docs/haddock/doc-index-R.html view
@@ -145,13 +145,77 @@ ><TD CLASS="indexannot" >3 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Lazy.html#v%3Areparse"+>Text.ParserCombinators.Poly.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#v%3Areparse"+>Text.ParserCombinators.Poly.NoLeak.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#v%3Areparse"+>Text.ParserCombinators.Poly.NoLeak.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>6 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3Areparse"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>7 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3Areparse"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>8 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Plain.html#v%3Areparse"+>Text.ParserCombinators.Poly.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>9 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#v%3Areparse"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>10 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3Areparse"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>11 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Areparse" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>12 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Areparse" >Text.ParserCombinators.PolyState</A@@ -159,7 +223,7 @@ ></TR ><TR ><TD CLASS="indexannot"->5 (Function)</TD+>13 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Areparse" >Text.ParserCombinators.PolyStateLazy</A@@ -181,13 +245,77 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Lazy.html#v%3ArunParser"+>Text.ParserCombinators.Poly.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#v%3ArunParser"+>Text.ParserCombinators.Poly.NoLeak.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#v%3ArunParser"+>Text.ParserCombinators.Poly.NoLeak.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3ArunParser"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>6 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3ArunParser"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>7 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Plain.html#v%3ArunParser"+>Text.ParserCombinators.Poly.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>8 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#v%3ArunParser"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>9 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3ArunParser"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>10 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3ArunParser" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>11 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3ArunParser" >Text.ParserCombinators.PolyState</A@@ -195,7 +323,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>12 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3ArunParser" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/doc-index-S.html view
@@ -145,13 +145,77 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Lazy.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.NoLeak.Lazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.NoLeak.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>6 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>7 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Plain.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.Plain</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>8 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>9 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3Asatisfy"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>10 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3Asatisfy" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>11 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3Asatisfy" >Text.ParserCombinators.PolyState</A@@ -159,7 +223,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>12 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3Asatisfy" >Text.ParserCombinators.PolyStateLazy</A@@ -181,13 +245,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AsepBy"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AsepBy" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AsepBy" >Text.ParserCombinators.PolyState</A@@ -195,7 +267,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AsepBy" >Text.ParserCombinators.PolyStateLazy</A@@ -217,13 +289,21 @@ ><TD CLASS="indexannot" >2 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-Base.html#v%3AsepBy1"+>Text.ParserCombinators.Poly.Base</A+>, Text.ParserCombinators.Poly.Lazy, Text.ParserCombinators.Poly.NoLeak.Lazy, Text.ParserCombinators.Poly.NoLeak.Plain, Text.ParserCombinators.Poly.NoLeak.State, Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.ParserCombinators.Poly.Plain, Text.ParserCombinators.Poly.State, Text.ParserCombinators.Poly.StateLazy</TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyLazy.html#v%3AsepBy1" >Text.ParserCombinators.PolyLazy</A ></TD ></TR ><TR ><TD CLASS="indexannot"->3 (Function)</TD+>4 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AsepBy1" >Text.ParserCombinators.PolyState</A@@ -231,7 +311,7 @@ ></TR ><TR ><TD CLASS="indexannot"->4 (Function)</TD+>5 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AsepBy1" >Text.ParserCombinators.PolyStateLazy</A@@ -301,13 +381,45 @@ ><TD CLASS="indexannot" >1 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3AstGet"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>2 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3AstGet"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#v%3AstGet"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3AstGet"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AstGet" >Text.ParserCombinators.PolyState</A ></TD ></TR ><TR ><TD CLASS="indexannot"->2 (Function)</TD+>6 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AstGet" >Text.ParserCombinators.PolyStateLazy</A@@ -321,13 +433,45 @@ ><TD CLASS="indexannot" >1 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3AstQuery"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>2 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3AstQuery"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#v%3AstQuery"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3AstQuery"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AstQuery" >Text.ParserCombinators.PolyState</A ></TD ></TR ><TR ><TD CLASS="indexannot"->2 (Function)</TD+>6 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AstQuery" >Text.ParserCombinators.PolyStateLazy</A@@ -341,13 +485,45 @@ ><TD CLASS="indexannot" >1 (Function)</TD ><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html#v%3AstUpdate"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>2 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html#v%3AstUpdate"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>3 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-State.html#v%3AstUpdate"+>Text.ParserCombinators.Poly.State</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>4 (Function)</TD+><TD CLASS="indexlinks"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html#v%3AstUpdate"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+></TR+><TR+><TD CLASS="indexannot"+>5 (Function)</TD+><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyState.html#v%3AstUpdate" >Text.ParserCombinators.PolyState</A ></TD ></TR ><TR ><TD CLASS="indexannot"->2 (Function)</TD+>6 (Function)</TD ><TD CLASS="indexlinks" ><A HREF="Text-ParserCombinators-PolyStateLazy.html#v%3AstUpdate" >Text.ParserCombinators.PolyStateLazy</A
docs/haddock/index.html view
@@ -94,13 +94,125 @@ ></TD ></TR ><TR-><TD STYLE="padding-left: 1.25em;width: 46em"+><TD STYLE="width: 46em"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'n:2')" ALT="show/hide" ><A HREF="Text-ParserCombinators-Poly.html" >Text.ParserCombinators.Poly</A ></TD ><TD ></TD ><TD+></TD+></TR+><TR+><TD STYLE="padding: 0; padding-left: 2em" COLSPAN="3"+><TABLE CLASS="vanilla2" CELLSPACING="0" CELLPADDING="0" ID="n:2" STYLE="display:block;"+><TR+><TD STYLE="padding-left: 1.25em;width: 44em"+><A HREF="Text-ParserCombinators-Poly-Base.html"+>Text.ParserCombinators.Poly.Base</A+></TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="padding-left: 1.25em;width: 44em"+><A HREF="Text-ParserCombinators-Poly-Lazy.html"+>Text.ParserCombinators.Poly.Lazy</A+></TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="width: 44em"+><IMG SRC="minus.gif" CLASS="coll" ONCLICK="toggle(this,'n:3')" ALT="show/hide"+>NoLeak</TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="padding: 0; padding-left: 2em" COLSPAN="3"+><TABLE CLASS="vanilla2" CELLSPACING="0" CELLPADDING="0" ID="n:3" STYLE="display:block;"+><TR+><TD STYLE="padding-left: 1.25em;width: 42em"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Lazy.html"+>Text.ParserCombinators.Poly.NoLeak.Lazy</A+></TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="padding-left: 1.25em;width: 42em"+><A HREF="Text-ParserCombinators-Poly-NoLeak-Plain.html"+>Text.ParserCombinators.Poly.NoLeak.Plain</A+></TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="padding-left: 1.25em;width: 42em"+><A HREF="Text-ParserCombinators-Poly-NoLeak-State.html"+>Text.ParserCombinators.Poly.NoLeak.State</A+></TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="padding-left: 1.25em;width: 42em"+><A HREF="Text-ParserCombinators-Poly-NoLeak-StateLazy.html"+>Text.ParserCombinators.Poly.NoLeak.StateLazy</A+></TD+><TD+></TD+><TD+></TD+></TR+></TABLE+></TD+></TR+><TR+><TD STYLE="padding-left: 1.25em;width: 44em"+><A HREF="Text-ParserCombinators-Poly-Plain.html"+>Text.ParserCombinators.Poly.Plain</A+></TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="padding-left: 1.25em;width: 44em"+><A HREF="Text-ParserCombinators-Poly-State.html"+>Text.ParserCombinators.Poly.State</A+></TD+><TD+></TD+><TD+></TD+></TR+><TR+><TD STYLE="padding-left: 1.25em;width: 44em"+><A HREF="Text-ParserCombinators-Poly-StateLazy.html"+>Text.ParserCombinators.Poly.StateLazy</A+></TD+><TD+></TD+><TD+></TD+></TR+></TABLE ></TD ></TR ><TR
docs/haddock/src/Text/Parse.html view
@@ -1,179 +1,182 @@-<pre><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>Parse- <font color=Cyan>(</font> <font color=Blue>-- * The Parse class is a replacement for the standard Read class. </font>- <font color=Blue>-- $parser</font>- TextParser <font color=Blue>-- synonym for Parser Char, i.e. string input, no state</font>- <font color=Cyan>,</font> Parse<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font> <font color=Blue>-- instances: (), (a,b), (a,b,c), Maybe a, Either a, [a],</font>- <font color=Blue>-- Int, Integer, Float, Double, Char, Bool</font>- <font color=Cyan>,</font> parseByRead <font color=Blue>-- :: Read a => String -> TextParser a</font>- <font color=Blue>-- ** Combinators specific to string input, lexed haskell-style</font>- <font color=Cyan>,</font> word <font color=Blue>-- :: TextParser String</font>- <font color=Cyan>,</font> isWord <font color=Blue>-- :: String -> TextParser ()</font>- <font color=Cyan>,</font> optionalParens <font color=Blue>-- :: TextParser a -> TextParser a</font>- <font color=Cyan>,</font> field <font color=Blue>-- :: Parse a => String -> TextParser a</font>- <font color=Cyan>,</font> constructors<font color=Blue>-- :: [(String,TextParser a)] -> TextParser a</font>- <font color=Cyan>,</font> enumeration <font color=Blue>-- :: Show a => String -> [a] -> TextParser a</font>- <font color=Blue>-- ** Re-export all the more general combinators from Poly too</font>- <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> <font color=Green><u>where</u></font>--<font color=Green><u>import</u></font> Char <font color=Cyan>(</font>isSpace<font color=Cyan>)</font>-<font color=Green><u>import</u></font> List <font color=Cyan>(</font>intersperse<font color=Cyan>)</font>-<font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- $parser</font>-<font color=Blue>-- The Parse class is a replacement for the standard Read class. It is a</font>-<font color=Blue>-- specialisation of the (poly) Parser monad for String input.</font>-<font color=Blue>-- There are instances defined for all Prelude types.</font>-<font color=Blue>-- For user-defined types, you can write your own instance, or use</font>-<font color=Blue>-- DrIFT to generate them automatically, e.g. {-! derive : Parse !-}</font>--<font color=Blue>-- | A synonym for Parser Char, i.e. string input (no state)</font>-<a name="TextParser"></a><font color=Green><u>type</u></font> TextParser a <font color=Red>=</font> Parser Char a--<font color=Blue>-- | The class @Parse@ is a replacement for @Read@, operating over String input.</font>-<font color=Blue>-- Essentially, it permits better error messages for why something failed to</font>-<font color=Blue>-- parse. It is rather important that @parse@ can read back exactly what</font>-<font color=Blue>-- is generated by the corresponding instance of @show@. To apply a parser</font>-<font color=Blue>-- to some text, use @runParser@.</font>-<a name="Parse"></a><font color=Green><u>class</u></font> Parse a <font color=Green><u>where</u></font>- parse <font color=Red>::</font> TextParser a- parseList <font color=Red>::</font> TextParser <font color=Red>[</font>a<font color=Red>]</font> <font color=Blue>-- only to distinguish [] and ""</font>- parseList <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"[]"</font><font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>- <font color=Cyan>`onFail`</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"["</font><font color=Cyan>;</font> isWord <font color=Magenta>"]"</font><font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>- <font color=Cyan>`onFail`</font>- bracketSep <font color=Cyan>(</font>isWord <font color=Magenta>"["</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>","</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>"]"</font><font color=Cyan>)</font> parse- <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Expected a list, but\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>--<font color=Blue>-- | If there already exists a Read instance for a type, then we can make</font>-<font color=Blue>-- a Parser for it, but with only poor error-reporting.</font>-parseByRead <font color=Red>::</font> Read a <font color=Red>=></font> String <font color=Red>-></font> TextParser a-<a name="parseByRead"></a>parseByRead name <font color=Red>=</font>- P <font color=Cyan>(</font><font color=Red>\</font>s<font color=Red>-></font> <font color=Green><u>case</u></font> reads s <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no parse, expected a "</font><font color=Cyan>++</font>name<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>- <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Right a<font color=Cyan>,</font> s'<font color=Cyan>)</font>- <font color=Green><u>_</u></font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"ambiguous parse, expected a "</font><font color=Cyan>++</font>name<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>- <font color=Cyan>)</font>--<font color=Blue>-- | One lexical chunk (Haskell-style lexing).</font>-word <font color=Red>::</font> TextParser String-<a name="word"></a>word <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s<font color=Red>-></font> <font color=Green><u>case</u></font> lex s <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input? (impossible)"</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>- <font color=Red>[</font><font color=Cyan>(</font><font color=Magenta>""</font><font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input?"</font><font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>)</font>- <font color=Cyan>(</font><font color=Cyan>(</font>x<font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<font color=Cyan>)</font> <font color=Cyan>)</font>--<font color=Blue>-- | Ensure that the next input word is the given string. (Note the input</font>-<font color=Blue>-- is lexed as haskell, so wordbreaks at spaces, symbols, etc.)</font>-isWord <font color=Red>::</font> String <font color=Red>-></font> TextParser String-<a name="isWord"></a>isWord w <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> w' <font color=Red><-</font> word- <font color=Cyan>;</font> <font color=Green><u>if</u></font> w'<font color=Cyan>==</font>w <font color=Green><u>then</u></font> return w <font color=Green><u>else</u></font> fail <font color=Cyan>(</font><font color=Magenta>"expected "</font><font color=Cyan>++</font>w<font color=Cyan>++</font><font color=Magenta>" got "</font><font color=Cyan>++</font>w'<font color=Cyan>)</font>- <font color=Cyan>}</font>--<font color=Blue>-- | Allow true string parens around an item.</font>-optionalParens <font color=Red>::</font> TextParser a <font color=Red>-></font> TextParser a-<a name="optionalParens"></a>optionalParens p <font color=Red>=</font> bracket <font color=Cyan>(</font>isWord <font color=Magenta>"("</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>")"</font><font color=Cyan>)</font> p <font color=Cyan>`onFail`</font> p--<font color=Blue>-- | Deal with named field syntax. The string argument is the field name,</font>-<font color=Blue>-- and the parser returns the value of the field.</font>-field <font color=Red>::</font> Parse a <font color=Red>=></font> String <font color=Red>-></font> TextParser a-<a name="field"></a>field name <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord name<font color=Cyan>;</font> commit <font color=Cyan>$</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"="</font><font color=Cyan>;</font> parse <font color=Cyan>}</font> <font color=Cyan>}</font>--<font color=Blue>-- | Parse one of a bunch of alternative constructors. In the list argument,</font>-<font color=Blue>-- the first element of the pair is the constructor name, and</font>-<font color=Blue>-- the second is the parser for the rest of the value. The first matching</font>-<font color=Blue>-- parse is returned.</font>-constructors <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font>TextParser a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> TextParser a-<a name="constructors"></a>constructors cs <font color=Red>=</font> oneOf' <font color=Cyan>(</font>map cons cs<font color=Cyan>)</font>- <font color=Green><u>where</u></font> cons <font color=Cyan>(</font>name<font color=Cyan>,</font>p<font color=Cyan>)</font> <font color=Red>=</font>- <font color=Cyan>(</font> name- <font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord name- <font color=Cyan>;</font> p <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"got constructor, but within "</font>- <font color=Cyan>++</font>name<font color=Cyan>++</font><font color=Magenta>",\n"</font><font color=Cyan>)</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>}</font>- <font color=Cyan>)</font>--<font color=Blue>-- | Parse one of the given nullary constructors (an enumeration).</font>-<font color=Blue>-- The string argument is the name of the type, and the list argument</font>-<font color=Blue>-- should contain all of the possible enumeration values.</font>-enumeration <font color=Red>::</font> <font color=Cyan>(</font>Show a<font color=Cyan>)</font> <font color=Red>=></font> String <font color=Red>-></font> <font color=Red>[</font>a<font color=Red>]</font> <font color=Red>-></font> TextParser a-<a name="enumeration"></a>enumeration typ cs <font color=Red>=</font> oneOf <font color=Cyan>(</font>map <font color=Cyan>(</font><font color=Red>\</font>c<font color=Red>-></font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Cyan>(</font>show c<font color=Cyan>)</font><font color=Cyan>;</font> return c <font color=Cyan>}</font><font color=Cyan>)</font> cs<font color=Cyan>)</font>- <font color=Cyan>`adjustErr`</font>- <font color=Cyan>(</font><font color=Cyan>++</font><font color=Cyan>(</font><font color=Magenta>"\n expected "</font><font color=Cyan>++</font>typ<font color=Cyan>++</font><font color=Magenta>" value ("</font><font color=Cyan>++</font>e<font color=Cyan>++</font><font color=Magenta>")"</font><font color=Cyan>)</font><font color=Cyan>)</font>- <font color=Green><u>where</u></font> e <font color=Red>=</font> concat <font color=Cyan>(</font>intersperse <font color=Magenta>", "</font> <font color=Cyan>(</font>map show <font color=Cyan>(</font>init cs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>- <font color=Cyan>++</font> <font color=Magenta>", or "</font> <font color=Cyan>++</font> show <font color=Cyan>(</font>last cs<font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- Instances for all the Standard Prelude types.</font>--<font color=Blue>-- Basic types</font>-<font color=Green><u>instance</u></font> Parse Int <font color=Green><u>where</u></font>- parse <font color=Red>=</font> parseByRead <font color=Magenta>"Int"</font>-<font color=Green><u>instance</u></font> Parse Integer <font color=Green><u>where</u></font>- parse <font color=Red>=</font> parseByRead <font color=Magenta>"Integer"</font>-<font color=Green><u>instance</u></font> Parse Float <font color=Green><u>where</u></font>- parse <font color=Red>=</font> parseByRead <font color=Magenta>"Float"</font>-<font color=Green><u>instance</u></font> Parse Double <font color=Green><u>where</u></font>- parse <font color=Red>=</font> parseByRead <font color=Magenta>"Double"</font>-<font color=Green><u>instance</u></font> Parse Char <font color=Green><u>where</u></font>- parse <font color=Red>=</font> parseByRead <font color=Magenta>"Char"</font>- <font color=Blue>-- parseList = bracket (isWord "\"") (satisfy (=='"'))</font>- <font color=Blue>-- (many (satisfy (/='"')))</font>- <font color=Blue>-- not totally correct for strings...</font>- parseList <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> w <font color=Red><-</font> word<font color=Cyan>;</font> <font color=Green><u>if</u></font> head w <font color=Cyan>==</font> <font color=Magenta>'"'</font> <font color=Green><u>then</u></font> return <font color=Cyan>(</font>init <font color=Cyan>(</font>tail w<font color=Cyan>)</font><font color=Cyan>)</font>- <font color=Green><u>else</u></font> fail <font color=Magenta>"not a string"</font> <font color=Cyan>}</font>--<font color=Green><u>instance</u></font> Parse Bool <font color=Green><u>where</u></font>- parse <font color=Red>=</font> enumeration <font color=Magenta>"Bool"</font> <font color=Red>[</font>False<font color=Cyan>,</font>True<font color=Red>]</font>--<font color=Green><u>instance</u></font> Parse Ordering <font color=Green><u>where</u></font>- parse <font color=Red>=</font> enumeration <font color=Magenta>"Ordering"</font> <font color=Red>[</font>LT<font color=Cyan>,</font>EQ<font color=Cyan>,</font>GT<font color=Red>]</font>--<font color=Blue>-- Structural types</font>-<font color=Green><u>instance</u></font> Parse <font color=Cyan>(</font><font color=Cyan>)</font> <font color=Green><u>where</u></font>- parse <font color=Red>=</font> P p- <font color=Green><u>where</u></font> p <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input: expected a ()"</font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- p <font color=Cyan>(</font><font color=Magenta>'('</font><font color=Red><b>:</b></font>cs<font color=Cyan>)</font> <font color=Red>=</font> <font color=Green><u>case</u></font> dropWhile isSpace cs <font color=Green><u>of</u></font>- <font color=Cyan>(</font><font color=Magenta>')'</font><font color=Red><b>:</b></font>s<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>- <font color=Green><u>_</u></font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Expected ) after ("</font><font color=Cyan>)</font><font color=Cyan>,</font> cs<font color=Cyan>)</font>- p <font color=Cyan>(</font>c<font color=Red><b>:</b></font>cs<font color=Cyan>)</font> <font color=Red>|</font> isSpace c <font color=Red>=</font> p cs- <font color=Red>|</font> otherwise <font color=Red>=</font> <font color=Cyan>(</font> Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Expected a (), got "</font><font color=Cyan>++</font>show c<font color=Cyan>)</font>- <font color=Cyan>,</font> <font color=Cyan>(</font>c<font color=Red><b>:</b></font>cs<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>)</font> <font color=Red>=></font> Parse <font color=Cyan>(</font>a<font color=Cyan>,</font>b<font color=Cyan>)</font> <font color=Green><u>where</u></font>- parse <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> isWord <font color=Magenta>"("</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Opening a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> x <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 1st item of a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> y <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 2nd item of a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> isWord <font color=Magenta>")"</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Closing a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Cyan>,</font>y<font color=Cyan>)</font> <font color=Cyan>}</font>--<font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>,</font> Parse c<font color=Cyan>)</font> <font color=Red>=></font> Parse <font color=Cyan>(</font>a<font color=Cyan>,</font>b<font color=Cyan>,</font>c<font color=Cyan>)</font> <font color=Green><u>where</u></font>- parse <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> isWord <font color=Magenta>"("</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Opening a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> x <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 1st item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating(1) a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> y <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 2nd item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating(2) a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> z <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 3rd item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> isWord <font color=Magenta>")"</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Closing a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Cyan>,</font>y<font color=Cyan>,</font>z<font color=Cyan>)</font> <font color=Cyan>}</font>--<font color=Green><u>instance</u></font> Parse a <font color=Red>=></font> Parse <font color=Cyan>(</font>Maybe a<font color=Cyan>)</font> <font color=Green><u>where</u></font>- parse <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"Nothing"</font><font color=Cyan>;</font> return Nothing <font color=Cyan>}</font>- <font color=Cyan>`onFail`</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"Just"</font>- <font color=Cyan>;</font> fmap Just <font color=Cyan>$</font> optionalParens parse- <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"but within Just, "</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>}</font>- <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"expected a Maybe (Just or Nothing)\n"</font><font color=Cyan>++</font><font color=Cyan>)</font><font color=Cyan>.</font>indent <font color=Magenta>2</font><font color=Cyan>)</font>--<font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>)</font> <font color=Red>=></font> Parse <font color=Cyan>(</font>Either a b<font color=Cyan>)</font> <font color=Green><u>where</u></font>- parse <font color=Red>=</font> constructors <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"Left"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> fmap Left <font color=Cyan>$</font> optionalParens parse <font color=Cyan>}</font> <font color=Cyan>)</font>- <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"Right"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> fmap Right <font color=Cyan>$</font> optionalParens parse <font color=Cyan>}</font> <font color=Cyan>)</font>- <font color=Red>]</font>--<font color=Green><u>instance</u></font> Parse a <font color=Red>=></font> Parse <font color=Red>[</font>a<font color=Red>]</font> <font color=Green><u>where</u></font>- parse <font color=Red>=</font> parseList--<font color=Blue>------------------------------------------------------------------------</font>+<!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>Parse+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parse class is a replacement for the standard Read class. </font>+<a name="(line3)"></a> <font color=Blue>-- $parser</font>+<a name="(line4)"></a> TextParser <font color=Blue>-- synonym for Parser Char, i.e. string input, no state</font>+<a name="(line5)"></a> <font color=Cyan>,</font> Parse<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font> <font color=Blue>-- instances: (), (a,b), (a,b,c), Maybe a, Either a, [a],</font>+<a name="(line6)"></a> <font color=Blue>-- Int, Integer, Float, Double, Char, Bool</font>+<a name="(line7)"></a> <font color=Cyan>,</font> parseByRead <font color=Blue>-- :: Read a => String -> TextParser a</font>+<a name="(line8)"></a> <font color=Blue>-- ** Combinators specific to string input, lexed haskell-style</font>+<a name="(line9)"></a> <font color=Cyan>,</font> word <font color=Blue>-- :: TextParser String</font>+<a name="(line10)"></a> <font color=Cyan>,</font> isWord <font color=Blue>-- :: String -> TextParser ()</font>+<a name="(line11)"></a> <font color=Cyan>,</font> optionalParens <font color=Blue>-- :: TextParser a -> TextParser a</font>+<a name="(line12)"></a> <font color=Cyan>,</font> field <font color=Blue>-- :: Parse a => String -> TextParser a</font>+<a name="(line13)"></a> <font color=Cyan>,</font> constructors<font color=Blue>-- :: [(String,TextParser a)] -> TextParser a</font>+<a name="(line14)"></a> <font color=Cyan>,</font> enumeration <font color=Blue>-- :: Show a => String -> [a] -> TextParser a</font>+<a name="(line15)"></a> <font color=Blue>-- ** Re-export all the more general combinators from Poly too</font>+<a name="(line16)"></a> <font color=Cyan>,</font> <font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly+<a name="(line17)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line18)"></a>+<a name="(line19)"></a><font color=Green><u>import</u></font> Char <font color=Cyan>(</font>isSpace<font color=Cyan>)</font>+<a name="(line20)"></a><font color=Green><u>import</u></font> List <font color=Cyan>(</font>intersperse<font color=Cyan>)</font>+<a name="(line21)"></a><font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly+<a name="(line22)"></a>+<a name="(line23)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line24)"></a><font color=Blue>-- $parser</font>+<a name="(line25)"></a><font color=Blue>-- The Parse class is a replacement for the standard Read class. It is a</font>+<a name="(line26)"></a><font color=Blue>-- specialisation of the (poly) Parser monad for String input.</font>+<a name="(line27)"></a><font color=Blue>-- There are instances defined for all Prelude types.</font>+<a name="(line28)"></a><font color=Blue>-- For user-defined types, you can write your own instance, or use</font>+<a name="(line29)"></a><font color=Blue>-- DrIFT to generate them automatically, e.g. {-! derive : Parse !-}</font>+<a name="(line30)"></a>+<a name="(line31)"></a><a name="TextParser"></a><font color=Blue>-- | A synonym for Parser Char, i.e. string input (no state)</font>+<a name="(line32)"></a><a name="TextParser"></a><font color=Green><u>type</u></font> TextParser a <font color=Red>=</font> Parser Char a+<a name="(line33)"></a>+<a name="(line34)"></a><a name="Parse"></a><font color=Blue>-- | The class @Parse@ is a replacement for @Read@, operating over String input.</font>+<a name="(line35)"></a><a name="Parse"></a><font color=Blue>-- Essentially, it permits better error messages for why something failed to</font>+<a name="(line36)"></a><a name="Parse"></a><font color=Blue>-- parse. It is rather important that @parse@ can read back exactly what</font>+<a name="(line37)"></a><a name="Parse"></a><font color=Blue>-- is generated by the corresponding instance of @show@. To apply a parser</font>+<a name="(line38)"></a><a name="Parse"></a><font color=Blue>-- to some text, use @runParser@.</font>+<a name="(line39)"></a><a name="Parse"></a><font color=Green><u>class</u></font> Parse a <font color=Green><u>where</u></font>+<a name="(line40)"></a> parse <font color=Red>::</font> TextParser a+<a name="(line41)"></a> parseList <font color=Red>::</font> TextParser <font color=Red>[</font>a<font color=Red>]</font> <font color=Blue>-- only to distinguish [] and ""</font>+<a name="(line42)"></a> parseList <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"[]"</font><font color=Cyan>;</font> return [] <font color=Cyan>}</font>+<a name="(line43)"></a> <font color=Cyan>`onFail`</font>+<a name="(line44)"></a> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"["</font><font color=Cyan>;</font> isWord <font color=Magenta>"]"</font><font color=Cyan>;</font> return [] <font color=Cyan>}</font>+<a name="(line45)"></a> <font color=Cyan>`onFail`</font>+<a name="(line46)"></a> bracketSep <font color=Cyan>(</font>isWord <font color=Magenta>"["</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>","</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>"]"</font><font color=Cyan>)</font> parse+<a name="(line47)"></a> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Expected a list, but\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line48)"></a>+<a name="(line49)"></a><a name="parseByRead"></a><font color=Blue>-- | If there already exists a Read instance for a type, then we can make</font>+<a name="(line50)"></a><font color=Blue>-- a Parser for it, but with only poor error-reporting.</font>+<a name="(line51)"></a>parseByRead <font color=Red>::</font> Read a <font color=Red>=></font> String <font color=Red>-></font> TextParser a+<a name="(line52)"></a>parseByRead name <font color=Red>=</font>+<a name="(line53)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s<font color=Red>-></font> <font color=Green><u>case</u></font> reads s <font color=Green><u>of</u></font>+<a name="(line54)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no parse, expected a "</font><font color=Cyan>++</font>name<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>+<a name="(line55)"></a> <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Right a<font color=Cyan>,</font> s'<font color=Cyan>)</font>+<a name="(line56)"></a> <font color=Green><u>_</u></font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"ambiguous parse, expected a "</font><font color=Cyan>++</font>name<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>+<a name="(line57)"></a> <font color=Cyan>)</font>+<a name="(line58)"></a>+<a name="(line59)"></a><a name="word"></a><font color=Blue>-- | One lexical chunk (Haskell-style lexing).</font>+<a name="(line60)"></a>word <font color=Red>::</font> TextParser String+<a name="(line61)"></a>word <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s<font color=Red>-></font> <font color=Green><u>case</u></font> lex s <font color=Green><u>of</u></font>+<a name="(line62)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input? (impossible)"</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>)</font>+<a name="(line63)"></a> <font color=Red>[</font><font color=Cyan>(</font><font color=Magenta>""</font><font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input?"</font><font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>)</font>+<a name="(line64)"></a> <font color=Cyan>(</font><font color=Cyan>(</font>x<font color=Cyan>,</font>s'<font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line65)"></a>+<a name="(line66)"></a><a name="isWord"></a><font color=Blue>-- | Ensure that the next input word is the given string. (Note the input</font>+<a name="(line67)"></a><font color=Blue>-- is lexed as haskell, so wordbreaks at spaces, symbols, etc.)</font>+<a name="(line68)"></a>isWord <font color=Red>::</font> String <font color=Red>-></font> TextParser String+<a name="(line69)"></a>isWord w <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> w' <font color=Red><-</font> word+<a name="(line70)"></a> <font color=Cyan>;</font> <font color=Green><u>if</u></font> w'<font color=Cyan>==</font>w <font color=Green><u>then</u></font> return w <font color=Green><u>else</u></font> fail <font color=Cyan>(</font><font color=Magenta>"expected "</font><font color=Cyan>++</font>w<font color=Cyan>++</font><font color=Magenta>" got "</font><font color=Cyan>++</font>w'<font color=Cyan>)</font>+<a name="(line71)"></a> <font color=Cyan>}</font>+<a name="(line72)"></a>+<a name="(line73)"></a><a name="optionalParens"></a><font color=Blue>-- | Allow true string parens around an item.</font>+<a name="(line74)"></a>optionalParens <font color=Red>::</font> TextParser a <font color=Red>-></font> TextParser a+<a name="(line75)"></a>optionalParens p <font color=Red>=</font> bracket <font color=Cyan>(</font>isWord <font color=Magenta>"("</font><font color=Cyan>)</font> <font color=Cyan>(</font>isWord <font color=Magenta>")"</font><font color=Cyan>)</font> p <font color=Cyan>`onFail`</font> p+<a name="(line76)"></a>+<a name="(line77)"></a><a name="field"></a><font color=Blue>-- | Deal with named field syntax. The string argument is the field name,</font>+<a name="(line78)"></a><font color=Blue>-- and the parser returns the value of the field.</font>+<a name="(line79)"></a>field <font color=Red>::</font> Parse a <font color=Red>=></font> String <font color=Red>-></font> TextParser a+<a name="(line80)"></a>field name <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord name<font color=Cyan>;</font> commit <font color=Cyan>$</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"="</font><font color=Cyan>;</font> parse <font color=Cyan>}</font> <font color=Cyan>}</font>+<a name="(line81)"></a>+<a name="(line82)"></a><a name="constructors"></a><font color=Blue>-- | Parse one of a bunch of alternative constructors. In the list argument,</font>+<a name="(line83)"></a><font color=Blue>-- the first element of the pair is the constructor name, and</font>+<a name="(line84)"></a><font color=Blue>-- the second is the parser for the rest of the value. The first matching</font>+<a name="(line85)"></a><font color=Blue>-- parse is returned.</font>+<a name="(line86)"></a>constructors <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font>TextParser a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> TextParser a+<a name="(line87)"></a>constructors cs <font color=Red>=</font> oneOf' <font color=Cyan>(</font>map cons cs<font color=Cyan>)</font>+<a name="(line88)"></a> <font color=Green><u>where</u></font> cons <font color=Cyan>(</font>name<font color=Cyan>,</font>p<font color=Cyan>)</font> <font color=Red>=</font>+<a name="(line89)"></a> <font color=Cyan>(</font> name+<a name="(line90)"></a> <font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord name+<a name="(line91)"></a> <font color=Cyan>;</font> p <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"got constructor, but within "</font>+<a name="(line92)"></a> <font color=Cyan>++</font>name<font color=Cyan>++</font><font color=Magenta>",\n"</font><font color=Cyan>)</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line93)"></a> <font color=Cyan>}</font>+<a name="(line94)"></a> <font color=Cyan>)</font>+<a name="(line95)"></a>+<a name="(line96)"></a><a name="enumeration"></a><font color=Blue>-- | Parse one of the given nullary constructors (an enumeration).</font>+<a name="(line97)"></a><font color=Blue>-- The string argument is the name of the type, and the list argument</font>+<a name="(line98)"></a><font color=Blue>-- should contain all of the possible enumeration values.</font>+<a name="(line99)"></a>enumeration <font color=Red>::</font> <font color=Cyan>(</font>Show a<font color=Cyan>)</font> <font color=Red>=></font> String <font color=Red>-></font> <font color=Red>[</font>a<font color=Red>]</font> <font color=Red>-></font> TextParser a+<a name="(line100)"></a>enumeration typ cs <font color=Red>=</font> oneOf <font color=Cyan>(</font>map <font color=Cyan>(</font><font color=Red>\</font>c<font color=Red>-></font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Cyan>(</font>show c<font color=Cyan>)</font><font color=Cyan>;</font> return c <font color=Cyan>}</font><font color=Cyan>)</font> cs<font color=Cyan>)</font>+<a name="(line101)"></a> <font color=Cyan>`adjustErr`</font>+<a name="(line102)"></a> <font color=Cyan>(</font><font color=Cyan>++</font><font color=Cyan>(</font><font color=Magenta>"\n expected "</font><font color=Cyan>++</font>typ<font color=Cyan>++</font><font color=Magenta>" value ("</font><font color=Cyan>++</font>e<font color=Cyan>++</font><font color=Magenta>")"</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line103)"></a> <font color=Green><u>where</u></font> e <font color=Red>=</font> concat <font color=Cyan>(</font>intersperse <font color=Magenta>", "</font> <font color=Cyan>(</font>map show <font color=Cyan>(</font>init cs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line104)"></a> <font color=Cyan>++</font> <font color=Magenta>", or "</font> <font color=Cyan>++</font> show <font color=Cyan>(</font>last cs<font color=Cyan>)</font>+<a name="(line105)"></a>+<a name="(line106)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line107)"></a><font color=Blue>-- Instances for all the Standard Prelude types.</font>+<a name="(line108)"></a>+<a name="(line109)"></a><font color=Blue>-- Basic types</font>+<a name="(line110)"></a><font color=Green><u>instance</u></font> Parse Int <font color=Green><u>where</u></font>+<a name="(line111)"></a> parse <font color=Red>=</font> parseByRead <font color=Magenta>"Int"</font>+<a name="(line112)"></a><font color=Green><u>instance</u></font> Parse Integer <font color=Green><u>where</u></font>+<a name="(line113)"></a> parse <font color=Red>=</font> parseByRead <font color=Magenta>"Integer"</font>+<a name="(line114)"></a><font color=Green><u>instance</u></font> Parse Float <font color=Green><u>where</u></font>+<a name="(line115)"></a> parse <font color=Red>=</font> parseByRead <font color=Magenta>"Float"</font>+<a name="(line116)"></a><font color=Green><u>instance</u></font> Parse Double <font color=Green><u>where</u></font>+<a name="(line117)"></a> parse <font color=Red>=</font> parseByRead <font color=Magenta>"Double"</font>+<a name="(line118)"></a><font color=Green><u>instance</u></font> Parse Char <font color=Green><u>where</u></font>+<a name="(line119)"></a> parse <font color=Red>=</font> parseByRead <font color=Magenta>"Char"</font>+<a name="(line120)"></a> <font color=Blue>-- parseList = bracket (isWord "\"") (satisfy (=='"'))</font>+<a name="(line121)"></a> <font color=Blue>-- (many (satisfy (/='"')))</font>+<a name="(line122)"></a> <font color=Blue>-- not totally correct for strings...</font>+<a name="(line123)"></a> parseList <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> w <font color=Red><-</font> word<font color=Cyan>;</font> <font color=Green><u>if</u></font> head w <font color=Cyan>==</font> <font color=Magenta>'"'</font> <font color=Green><u>then</u></font> return <font color=Cyan>(</font>init <font color=Cyan>(</font>tail w<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line124)"></a> <font color=Green><u>else</u></font> fail <font color=Magenta>"not a string"</font> <font color=Cyan>}</font>+<a name="(line125)"></a>+<a name="(line126)"></a><font color=Green><u>instance</u></font> Parse Bool <font color=Green><u>where</u></font>+<a name="(line127)"></a> parse <font color=Red>=</font> enumeration <font color=Magenta>"Bool"</font> <font color=Red>[</font>False<font color=Cyan>,</font>True<font color=Red>]</font>+<a name="(line128)"></a>+<a name="(line129)"></a><font color=Green><u>instance</u></font> Parse Ordering <font color=Green><u>where</u></font>+<a name="(line130)"></a> parse <font color=Red>=</font> enumeration <font color=Magenta>"Ordering"</font> <font color=Red>[</font>LT<font color=Cyan>,</font>EQ<font color=Cyan>,</font>GT<font color=Red>]</font>+<a name="(line131)"></a>+<a name="(line132)"></a><font color=Blue>-- Structural types</font>+<a name="(line133)"></a><font color=Green><u>instance</u></font> Parse () <font color=Green><u>where</u></font>+<a name="(line134)"></a> parse <font color=Red>=</font> P p+<a name="(line135)"></a> <font color=Green><u>where</u></font> p [] <font color=Red>=</font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"no input: expected a ()"</font><font color=Cyan>)</font><font color=Cyan>,</font> []<font color=Cyan>)</font>+<a name="(line136)"></a> p <font color=Cyan>(</font><font color=Magenta>'('</font><font color=Red><b>:</b></font>cs<font color=Cyan>)</font> <font color=Red>=</font> <font color=Green><u>case</u></font> dropWhile isSpace cs <font color=Green><u>of</u></font>+<a name="(line137)"></a> <font color=Cyan>(</font><font color=Magenta>')'</font><font color=Red><b>:</b></font>s<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> s<font color=Cyan>)</font>+<a name="(line138)"></a> <font color=Green><u>_</u></font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Expected ) after ("</font><font color=Cyan>)</font><font color=Cyan>,</font> cs<font color=Cyan>)</font>+<a name="(line139)"></a> p <font color=Cyan>(</font>c<font color=Red><b>:</b></font>cs<font color=Cyan>)</font> <font color=Red>|</font> isSpace c <font color=Red>=</font> p cs+<a name="(line140)"></a> <font color=Red>|</font> otherwise <font color=Red>=</font> <font color=Cyan>(</font> Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Expected a (), got "</font><font color=Cyan>++</font>show c<font color=Cyan>)</font>+<a name="(line141)"></a> <font color=Cyan>,</font> <font color=Cyan>(</font>c<font color=Red><b>:</b></font>cs<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line142)"></a>+<a name="(line143)"></a><font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>)</font> <font color=Red>=></font> Parse <font color=Cyan>(</font>a<font color=Cyan>,</font>b<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line144)"></a> parse <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> isWord <font color=Magenta>"("</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Opening a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line145)"></a> <font color=Cyan>;</font> x <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 1st item of a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line146)"></a> <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line147)"></a> <font color=Cyan>;</font> y <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 2nd item of a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line148)"></a> <font color=Cyan>;</font> isWord <font color=Magenta>")"</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Closing a 2-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line149)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Cyan>,</font>y<font color=Cyan>)</font> <font color=Cyan>}</font>+<a name="(line150)"></a>+<a name="(line151)"></a><font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>,</font> Parse c<font color=Cyan>)</font> <font color=Red>=></font> Parse <font color=Cyan>(</font>a<font color=Cyan>,</font>b<font color=Cyan>,</font>c<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line152)"></a> parse <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> isWord <font color=Magenta>"("</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Opening a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line153)"></a> <font color=Cyan>;</font> x <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 1st item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line154)"></a> <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating(1) a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line155)"></a> <font color=Cyan>;</font> y <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 2nd item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line156)"></a> <font color=Cyan>;</font> isWord <font color=Magenta>","</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Separating(2) a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line157)"></a> <font color=Cyan>;</font> z <font color=Red><-</font> parse <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"In 3rd item of a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line158)"></a> <font color=Cyan>;</font> isWord <font color=Magenta>")"</font> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"Closing a 3-tuple\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line159)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Cyan>,</font>y<font color=Cyan>,</font>z<font color=Cyan>)</font> <font color=Cyan>}</font>+<a name="(line160)"></a>+<a name="(line161)"></a><font color=Green><u>instance</u></font> Parse a <font color=Red>=></font> Parse <font color=Cyan>(</font>Maybe a<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line162)"></a> parse <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"Nothing"</font><font color=Cyan>;</font> return Nothing <font color=Cyan>}</font>+<a name="(line163)"></a> <font color=Cyan>`onFail`</font>+<a name="(line164)"></a> <font color=Green><u>do</u></font> <font color=Cyan>{</font> isWord <font color=Magenta>"Just"</font>+<a name="(line165)"></a> <font color=Cyan>;</font> fmap Just <font color=Cyan>$</font> optionalParens parse+<a name="(line166)"></a> <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"but within Just, "</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line167)"></a> <font color=Cyan>}</font>+<a name="(line168)"></a> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"expected a Maybe (Just or Nothing)\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="(line169)"></a>+<a name="(line170)"></a><font color=Green><u>instance</u></font> <font color=Cyan>(</font>Parse a<font color=Cyan>,</font> Parse b<font color=Cyan>)</font> <font color=Red>=></font> Parse <font color=Cyan>(</font>Either a b<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line171)"></a> parse <font color=Red>=</font> constructors <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"Left"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> fmap Left <font color=Cyan>$</font> optionalParens parse <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line172)"></a> <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"Right"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> fmap Right <font color=Cyan>$</font> optionalParens parse <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line173)"></a> <font color=Red>]</font>+<a name="(line174)"></a>+<a name="(line175)"></a><font color=Green><u>instance</u></font> Parse a <font color=Red>=></font> Parse <font color=Red>[</font>a<font color=Red>]</font> <font color=Green><u>where</u></font>+<a name="(line176)"></a> parse <font color=Red>=</font> parseList+<a name="(line177)"></a>+<a name="(line178)"></a><font color=Blue>------------------------------------------------------------------------</font> </pre>+</html>
docs/haddock/src/Text/ParserCombinators/HuttonMeijer.html view
@@ -1,219 +1,222 @@-<pre><font color=Blue>-----------------------------------------------------------------------------</font>-<font color=Blue>-- |</font>-<font color=Blue>-- Module : Text.ParserCombinators.HuttonMeijer</font>-<font color=Blue>-- Copyright : Graham Hutton (University of Nottingham), Erik Meijer (University of Utrecht)</font>-<font color=Blue>-- Licence : BSD</font>-<font color=Blue>-- </font>-<font color=Blue>-- Maintainer : Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk></font>-<font color=Blue>-- Stability : Stable</font>-<font color=Blue>-- Portability : All</font>-<font color=Blue>--</font>-<font color=Blue>-- A LIBRARY OF MONADIC PARSER COMBINATORS</font>-<font color=Blue>-- </font>-<font color=Blue>-- 29th July 1996</font>-<font color=Blue>-- </font>-<font color=Blue>-- Graham Hutton Erik Meijer</font>-<font color=Blue>-- University of Nottingham University of Utrecht</font>-<font color=Blue>-- </font>-<font color=Blue>-- This Haskell script defines a library of parser combinators, and is</font>-<font color=Blue>-- taken from sections 1-6 of our article "Monadic Parser Combinators".</font>-<font color=Blue>-- Some changes to the library have been made in the move from Gofer</font>-<font color=Blue>-- to Haskell:</font>-<font color=Blue>-- </font>-<font color=Blue>-- * Do notation is used in place of monad comprehension notation;</font>-<font color=Blue>-- </font>-<font color=Blue>-- * The parser datatype is defined using "newtype", to avoid the overhead</font>-<font color=Blue>-- of tagging and untagging parsers with the P constructor.</font>-<font color=Blue>-----------------------------------------------------------------------------</font>---<font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>HuttonMeijer- <font color=Cyan>(</font>Parser<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font><font color=Cyan>,</font> item<font color=Cyan>,</font> first<font color=Cyan>,</font> papply<font color=Cyan>,</font> <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font><font color=Cyan>,</font> sat<font color=Cyan>,</font> <font color=Blue>{-tok,-}</font> many<font color=Cyan>,</font> many1<font color=Cyan>,</font>- sepby<font color=Cyan>,</font> sepby1<font color=Cyan>,</font> chainl<font color=Cyan>,</font>- chainl1<font color=Cyan>,</font> chainr<font color=Cyan>,</font> chainr1<font color=Cyan>,</font> ops<font color=Cyan>,</font> bracket<font color=Cyan>,</font> char<font color=Cyan>,</font> digit<font color=Cyan>,</font> lower<font color=Cyan>,</font> upper<font color=Cyan>,</font>- letter<font color=Cyan>,</font> alphanum<font color=Cyan>,</font> string<font color=Cyan>,</font> ident<font color=Cyan>,</font> nat<font color=Cyan>,</font> int<font color=Cyan>,</font> spaces<font color=Cyan>,</font> comment<font color=Cyan>,</font> junk<font color=Cyan>,</font>- skip<font color=Cyan>,</font> token<font color=Cyan>,</font> natural<font color=Cyan>,</font> integer<font color=Cyan>,</font> symbol<font color=Cyan>,</font> identifier<font color=Cyan>)</font> <font color=Green><u>where</u></font>--<font color=Green><u>import</u></font> Char-<font color=Green><u>import</u></font> Monad--<font color=Green><u>infixr</u></font> <font color=Magenta>5</font> <font color=Cyan>+++</font>--<a name="Token"></a><font color=Green><u>type</u></font> Token <font color=Red>=</font> Char--<font color=Blue>---------------------------------------------------------</font>-<font color=Blue>-- | The parser monad</font>--<font color=Green><u>newtype</u></font> Parser a <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>[</font>Token<font color=Red>]</font> <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font><font color=Red>[</font>Token<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>--<font color=Green><u>instance</u></font> Functor Parser <font color=Green><u>where</u></font>- <font color=Blue>-- map :: (a -> b) -> (Parser a -> Parser b)</font>- 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>inp <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>f v<font color=Cyan>,</font> out<font color=Cyan>)</font> <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> p inp<font color=Red>]</font><font color=Cyan>)</font>--<font color=Green><u>instance</u></font> Monad Parser <font color=Green><u>where</u></font>- <font color=Blue>-- return :: a -> Parser a</font>- return v <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>v<font color=Cyan>,</font>inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>-- <font color=Blue>-- >>= :: Parser a -> (a -> Parser b) -> Parser b</font>- <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>>>=</font> f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> concat <font color=Red>[</font>papply <font color=Cyan>(</font>f v<font color=Cyan>)</font> out <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> p inp<font color=Red>]</font><font color=Cyan>)</font>-- <font color=Blue>-- fail :: String -> Parser a</font>- fail <font color=Green><u>_</u></font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font><font color=Green><u>_</u></font> <font color=Red>-></font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>--<font color=Green><u>instance</u></font> MonadPlus Parser <font color=Green><u>where</u></font>- <font color=Blue>-- mzero :: Parser a</font>- mzero <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font><font color=Green><u>_</u></font> <font color=Red>-></font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>-- <font color=Blue>-- mplus :: Parser a -> Parser a -> Parser a</font>- <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`mplus`</font> <font color=Cyan>(</font>P q<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Cyan>(</font>p inp <font color=Cyan>++</font> q inp<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- ------------------------------------------------------------</font>-<font color=Blue>-- * Other primitive parser combinators</font>-<font color=Blue>-- ------------------------------------------------------------</font>--item <font color=Red>::</font> Parser Token-<a name="item"></a>item <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Red>[</font><font color=Red>]</font>- <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font> <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>x<font color=Cyan>,</font>xs<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>--first <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a-<a name="first"></a>first <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Green><u>case</u></font> p inp <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Red>[</font><font color=Red>]</font>- <font color=Cyan>(</font>x<font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> <font color=Red>[</font>x<font color=Red>]</font><font color=Cyan>)</font>--papply <font color=Red>::</font> Parser a <font color=Red>-></font> <font color=Red>[</font>Token<font color=Red>]</font> <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font><font color=Red>[</font>Token<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>-<a name="papply"></a>papply <font color=Cyan>(</font>P p<font color=Cyan>)</font> inp <font color=Red>=</font> p inp--<font color=Blue>-- ------------------------------------------------------------</font>-<font color=Blue>-- * Derived combinators</font>-<font color=Blue>-- ------------------------------------------------------------</font>--<a name="+++"></a><font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a <font color=Red>-></font> Parser a-<a name="p"></a>p <font color=Cyan>+++</font> q <font color=Red>=</font> first <font color=Cyan>(</font>p <font color=Cyan>`mplus`</font> q<font color=Cyan>)</font>--sat <font color=Red>::</font> <font color=Cyan>(</font>Token <font color=Red>-></font> Bool<font color=Cyan>)</font> <font color=Red>-></font> Parser Token-<a name="sat"></a>sat p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> item<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> mzero<font color=Cyan>}</font>--<font color=Blue>--tok :: Token -> Parser Token</font>-<font color=Blue>--tok t = do {x <- item; if t==snd x then return t else mzero}</font>--many <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>-<a name="many"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>+++</font> return <font color=Red>[</font><font color=Red>]</font>-<font color=Blue>--many p = force (many1 p +++ return [])</font>--many1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>-<a name="many1"></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>;</font> xs <font color=Red><-</font> many p<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>--sepby <font color=Red>::</font> Parser a <font color=Red>-></font> Parser b <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepby"></a>p <font color=Cyan>`sepby`</font> sep <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`sepby1`</font> sep<font color=Cyan>)</font> <font color=Cyan>+++</font> return <font color=Red>[</font><font color=Red>]</font>--sepby1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser b <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepby1"></a>p <font color=Cyan>`sepby1`</font> sep <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> xs <font color=Red><-</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><font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>--chainl <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> a <font color=Red>-></font> Parser a-<a name="chainl"></a>chainl p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainl1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v--chainl1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> Parser a-<a name="chainl1"></a>p <font color=Cyan>`chainl1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>- <font color=Green><u>where</u></font>- rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>f <font color=Red><-</font> op<font color=Cyan>;</font> y <font color=Red><-</font> p<font color=Cyan>;</font> rest <font color=Cyan>(</font>f x y<font color=Cyan>)</font><font color=Cyan>}</font>- <font color=Cyan>+++</font> return x--chainr <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> a <font color=Red>-></font> Parser a-<a name="chainr"></a>chainr p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainr1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v--chainr1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> Parser a-<a name="chainr1"></a>p <font color=Cyan>`chainr1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>- <font color=Green><u>where</u></font>- rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>f <font color=Red><-</font> op<font color=Cyan>;</font> y <font color=Red><-</font> p <font color=Cyan>`chainr1`</font> op<font color=Cyan>;</font> return <font color=Cyan>(</font>f x y<font color=Cyan>)</font><font color=Cyan>}</font>- <font color=Cyan>+++</font> return x--ops <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>Parser a<font color=Cyan>,</font> b<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser b-<a name="ops"></a>ops xs <font color=Red>=</font> foldr1 <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>[</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>p<font color=Cyan>;</font> return op<font color=Cyan>}</font> <font color=Red>|</font> <font color=Cyan>(</font>p<font color=Cyan>,</font>op<font color=Cyan>)</font> <font color=Red><-</font> xs<font color=Red>]</font>--bracket <font color=Red>::</font> Parser a <font color=Red>-></font> Parser b <font color=Red>-></font> Parser c <font color=Red>-></font> Parser b-<a name="bracket"></a>bracket open p close <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>open<font color=Cyan>;</font> x <font color=Red><-</font> p<font color=Cyan>;</font> close<font color=Cyan>;</font> return x<font color=Cyan>}</font>--<font color=Blue>-- ------------------------------------------------------------</font>-<font color=Blue>-- * Useful parsers</font>-<font color=Blue>-- ------------------------------------------------------------</font>--char <font color=Red>::</font> Char <font color=Red>-></font> Parser Char-<a name="char"></a>char x <font color=Red>=</font> sat <font color=Cyan>(</font><font color=Red>\</font>y <font color=Red>-></font> x <font color=Cyan>==</font> y<font color=Cyan>)</font>--digit <font color=Red>::</font> Parser Char-<a name="digit"></a>digit <font color=Red>=</font> sat isDigit--lower <font color=Red>::</font> Parser Char-<a name="lower"></a>lower <font color=Red>=</font> sat isLower--upper <font color=Red>::</font> Parser Char-<a name="upper"></a>upper <font color=Red>=</font> sat isUpper--letter <font color=Red>::</font> Parser Char-<a name="letter"></a>letter <font color=Red>=</font> sat isAlpha--alphanum <font color=Red>::</font> Parser Char-<a name="alphanum"></a>alphanum <font color=Red>=</font> sat isAlphaNum <font color=Cyan>+++</font> char <font color=Magenta>'_'</font>--string <font color=Red>::</font> String <font color=Red>-></font> Parser String-<a name="string"></a>string <font color=Magenta>""</font> <font color=Red>=</font> return <font color=Magenta>""</font>-string <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font> <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>char x<font color=Cyan>;</font> string xs<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>--ident <font color=Red>::</font> Parser String-<a name="ident"></a>ident <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> lower<font color=Cyan>;</font> xs <font color=Red><-</font> many alphanum<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>--nat <font color=Red>::</font> Parser Int-<a name="nat"></a>nat <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> digit<font color=Cyan>;</font> return <font color=Cyan>(</font>fromEnum x <font color=Blue>-</font> fromEnum <font color=Magenta>'0'</font><font color=Cyan>)</font><font color=Cyan>}</font> <font color=Cyan>`chainl1`</font> return op- <font color=Green><u>where</u></font>- m <font color=Cyan>`op`</font> n <font color=Red>=</font> <font color=Magenta>10</font><font color=Cyan>*</font>m <font color=Cyan>+</font> n--int <font color=Red>::</font> Parser Int-<a name="int"></a>int <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>char <font color=Magenta>'-'</font><font color=Cyan>;</font> n <font color=Red><-</font> nat<font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Blue>-</font>n<font color=Cyan>)</font><font color=Cyan>}</font> <font color=Cyan>+++</font> nat--<font color=Blue>-- ------------------------------------------------------------</font>-<font color=Blue>-- * Lexical combinators</font>-<font color=Blue>-- ------------------------------------------------------------</font>--spaces <font color=Red>::</font> Parser <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="spaces"></a>spaces <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>many1 <font color=Cyan>(</font>sat isSpace<font color=Cyan>)</font><font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>}</font>--comment <font color=Red>::</font> Parser <font color=Cyan>(</font><font color=Cyan>)</font>-<font color=Blue>--comment = do {string "--"; many (sat (\x -> x /= '\n')); return ()}</font>-<font color=Blue>--comment = do </font>-<font color=Blue>-- _ <- string "--"</font>-<font color=Blue>-- _ <- many (sat (\x -> x /= '\n'))</font>-<font color=Blue>-- return ()</font>-<a name="comment"></a>comment <font color=Red>=</font> <font color=Green><u>do</u></font>- bracket <font color=Cyan>(</font>string <font color=Magenta>"/*"</font><font color=Cyan>)</font> <font color=Cyan>(</font>many item<font color=Cyan>)</font> <font color=Cyan>(</font>string <font color=Magenta>"*/"</font><font color=Cyan>)</font>- return <font color=Cyan>(</font><font color=Cyan>)</font>--junk <font color=Red>::</font> Parser <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="junk"></a>junk <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>many <font color=Cyan>(</font>spaces <font color=Cyan>+++</font> comment<font color=Cyan>)</font><font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>}</font>--skip <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a-<a name="skip"></a>skip p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>junk<font color=Cyan>;</font> p<font color=Cyan>}</font>--token <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a-<a name="token"></a>token p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>v <font color=Red><-</font> p<font color=Cyan>;</font> junk<font color=Cyan>;</font> return v<font color=Cyan>}</font>--<font color=Blue>-- ------------------------------------------------------------</font>-<font color=Blue>-- * Token parsers</font>-<font color=Blue>-- ------------------------------------------------------------</font>--natural <font color=Red>::</font> Parser Int-<a name="natural"></a>natural <font color=Red>=</font> token nat--integer <font color=Red>::</font> Parser Int-<a name="integer"></a>integer <font color=Red>=</font> token int--symbol <font color=Red>::</font> String <font color=Red>-></font> Parser String-<a name="symbol"></a>symbol xs <font color=Red>=</font> token <font color=Cyan>(</font>string xs<font color=Cyan>)</font>--identifier <font color=Red>::</font> <font color=Red>[</font>String<font color=Red>]</font> <font color=Red>-></font> Parser String-<a name="identifier"></a>identifier ks <font color=Red>=</font> token <font color=Cyan>(</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> ident<font color=Cyan>;</font>- <font color=Green><u>if</u></font> not <font color=Cyan>(</font>elem x ks<font color=Cyan>)</font> <font color=Green><u>then</u></font> return x- <font color=Green><u>else</u></font> return mzero<font color=Cyan>}</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------------</font>+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">+<html>+<pre><a name="(line1)"></a><font color=Blue>-----------------------------------------------------------------------------</font>+<a name="(line2)"></a><font color=Blue>-- |</font>+<a name="(line3)"></a><font color=Blue>-- Module : Text.ParserCombinators.HuttonMeijer</font>+<a name="(line4)"></a><font color=Blue>-- Copyright : Graham Hutton (University of Nottingham), Erik Meijer (University of Utrecht)</font>+<a name="(line5)"></a><font color=Blue>-- Licence : BSD</font>+<a name="(line6)"></a><font color=Blue>-- </font>+<a name="(line7)"></a><font color=Blue>-- Maintainer : Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk></font>+<a name="(line8)"></a><font color=Blue>-- Stability : Stable</font>+<a name="(line9)"></a><font color=Blue>-- Portability : All</font>+<a name="(line10)"></a><font color=Blue>--</font>+<a name="(line11)"></a><font color=Blue>-- A LIBRARY OF MONADIC PARSER COMBINATORS</font>+<a name="(line12)"></a><font color=Blue>-- </font>+<a name="(line13)"></a><font color=Blue>-- 29th July 1996</font>+<a name="(line14)"></a><font color=Blue>-- </font>+<a name="(line15)"></a><font color=Blue>-- Graham Hutton Erik Meijer</font>+<a name="(line16)"></a><font color=Blue>-- University of Nottingham University of Utrecht</font>+<a name="(line17)"></a><font color=Blue>-- </font>+<a name="(line18)"></a><font color=Blue>-- This Haskell script defines a library of parser combinators, and is</font>+<a name="(line19)"></a><font color=Blue>-- taken from sections 1-6 of our article "Monadic Parser Combinators".</font>+<a name="(line20)"></a><font color=Blue>-- Some changes to the library have been made in the move from Gofer</font>+<a name="(line21)"></a><font color=Blue>-- to Haskell:</font>+<a name="(line22)"></a><font color=Blue>-- </font>+<a name="(line23)"></a><font color=Blue>-- * Do notation is used in place of monad comprehension notation;</font>+<a name="(line24)"></a><font color=Blue>-- </font>+<a name="(line25)"></a><font color=Blue>-- * The parser datatype is defined using "newtype", to avoid the overhead</font>+<a name="(line26)"></a><font color=Blue>-- of tagging and untagging parsers with the P constructor.</font>+<a name="(line27)"></a><font color=Blue>-----------------------------------------------------------------------------</font>+<a name="(line28)"></a>+<a name="(line29)"></a>+<a name="(line30)"></a><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>HuttonMeijer+<a name="(line31)"></a> <font color=Cyan>(</font>Parser<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font><font color=Cyan>,</font> item<font color=Cyan>,</font> first<font color=Cyan>,</font> papply<font color=Cyan>,</font> <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font><font color=Cyan>,</font> sat<font color=Cyan>,</font> <font color=Blue>{-tok,-}</font> many<font color=Cyan>,</font> many1<font color=Cyan>,</font>+<a name="(line32)"></a> sepby<font color=Cyan>,</font> sepby1<font color=Cyan>,</font> chainl<font color=Cyan>,</font>+<a name="(line33)"></a> chainl1<font color=Cyan>,</font> chainr<font color=Cyan>,</font> chainr1<font color=Cyan>,</font> ops<font color=Cyan>,</font> bracket<font color=Cyan>,</font> char<font color=Cyan>,</font> digit<font color=Cyan>,</font> lower<font color=Cyan>,</font> upper<font color=Cyan>,</font>+<a name="(line34)"></a> letter<font color=Cyan>,</font> alphanum<font color=Cyan>,</font> string<font color=Cyan>,</font> ident<font color=Cyan>,</font> nat<font color=Cyan>,</font> int<font color=Cyan>,</font> spaces<font color=Cyan>,</font> comment<font color=Cyan>,</font> junk<font color=Cyan>,</font>+<a name="(line35)"></a> skip<font color=Cyan>,</font> token<font color=Cyan>,</font> natural<font color=Cyan>,</font> integer<font color=Cyan>,</font> symbol<font color=Cyan>,</font> identifier<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line36)"></a>+<a name="(line37)"></a><font color=Green><u>import</u></font> Char+<a name="(line38)"></a><font color=Green><u>import</u></font> Monad+<a name="(line39)"></a>+<a name="(line40)"></a><font color=Green><u>infixr</u></font> <font color=Magenta>5</font> <font color=Cyan>+++</font>+<a name="(line41)"></a>+<a name="(line42)"></a><a name="Token"></a><font color=Green><u>type</u></font> Token <font color=Red>=</font> Char+<a name="(line43)"></a>+<a name="(line44)"></a><font color=Blue>---------------------------------------------------------</font>+<a name="(line45)"></a><font color=Blue>-- | The parser monad</font>+<a name="(line46)"></a>+<a name="(line47)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser a <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>[</font>Token<font color=Red>]</font> <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font><font color=Red>[</font>Token<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line48)"></a>+<a name="(line49)"></a><font color=Green><u>instance</u></font> Functor Parser <font color=Green><u>where</u></font>+<a name="(line50)"></a> <font color=Blue>-- map :: (a -> b) -> (Parser a -> Parser b)</font>+<a name="(line51)"></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>inp <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>f v<font color=Cyan>,</font> out<font color=Cyan>)</font> <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> p inp<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line52)"></a>+<a name="(line53)"></a><font color=Green><u>instance</u></font> Monad Parser <font color=Green><u>where</u></font>+<a name="(line54)"></a> <font color=Blue>-- return :: a -> Parser a</font>+<a name="(line55)"></a> return v <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>v<font color=Cyan>,</font>inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line56)"></a>+<a name="(line57)"></a> <font color=Blue>-- >>= :: Parser a -> (a -> Parser b) -> Parser b</font>+<a name="(line58)"></a> <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>>>=</font> f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> concat <font color=Red>[</font>papply <font color=Cyan>(</font>f v<font color=Cyan>)</font> out <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> p inp<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line59)"></a>+<a name="(line60)"></a> <font color=Blue>-- fail :: String -> Parser a</font>+<a name="(line61)"></a> fail <font color=Green><u>_</u></font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font><font color=Green><u>_</u></font> <font color=Red>-></font> []<font color=Cyan>)</font>+<a name="(line62)"></a>+<a name="(line63)"></a><font color=Green><u>instance</u></font> MonadPlus Parser <font color=Green><u>where</u></font>+<a name="(line64)"></a> <font color=Blue>-- mzero :: Parser a</font>+<a name="(line65)"></a> mzero <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font><font color=Green><u>_</u></font> <font color=Red>-></font> []<font color=Cyan>)</font>+<a name="(line66)"></a>+<a name="(line67)"></a> <font color=Blue>-- mplus :: Parser a -> Parser a -> Parser a</font>+<a name="(line68)"></a> <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`mplus`</font> <font color=Cyan>(</font>P q<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Cyan>(</font>p inp <font color=Cyan>++</font> q inp<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line69)"></a>+<a name="(line70)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line71)"></a><font color=Blue>-- * Other primitive parser combinators</font>+<a name="(line72)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line73)"></a>+<a name="(line74)"></a><a name="item"></a>item <font color=Red>::</font> Parser Token+<a name="(line75)"></a>item <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>+<a name="(line76)"></a> [] <font color=Red>-></font> []+<a name="(line77)"></a> <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font> <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>x<font color=Cyan>,</font>xs<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line78)"></a>+<a name="(line79)"></a><a name="first"></a>first <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a+<a name="(line80)"></a>first <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp <font color=Red>-></font> <font color=Green><u>case</u></font> p inp <font color=Green><u>of</u></font>+<a name="(line81)"></a> [] <font color=Red>-></font> []+<a name="(line82)"></a> <font color=Cyan>(</font>x<font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> <font color=Red>[</font>x<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line83)"></a>+<a name="(line84)"></a><a name="papply"></a>papply <font color=Red>::</font> Parser a <font color=Red>-></font> <font color=Red>[</font>Token<font color=Red>]</font> <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font><font color=Red>[</font>Token<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>+<a name="(line85)"></a>papply <font color=Cyan>(</font>P p<font color=Cyan>)</font> inp <font color=Red>=</font> p inp+<a name="(line86)"></a>+<a name="(line87)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line88)"></a><font color=Blue>-- * Derived combinators</font>+<a name="(line89)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line90)"></a>+<a name="(line91)"></a><a name="+++"></a><font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a <font color=Red>-></font> Parser a+<a name="(line92)"></a><a name="p"></a>p <font color=Cyan>+++</font> q <font color=Red>=</font> first <font color=Cyan>(</font>p <font color=Cyan>`mplus`</font> q<font color=Cyan>)</font>+<a name="(line93)"></a>+<a name="(line94)"></a><a name="sat"></a>sat <font color=Red>::</font> <font color=Cyan>(</font>Token <font color=Red>-></font> Bool<font color=Cyan>)</font> <font color=Red>-></font> Parser Token+<a name="(line95)"></a>sat p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> item<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> mzero<font color=Cyan>}</font>+<a name="(line96)"></a>+<a name="(line97)"></a><font color=Blue>--tok :: Token -> Parser Token</font>+<a name="(line98)"></a><font color=Blue>--tok t = do {x <- item; if t==snd x then return t else mzero}</font>+<a name="(line99)"></a>+<a name="(line100)"></a><a name="many"></a>many <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line101)"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>+++</font> return []+<a name="(line102)"></a><font color=Blue>--many p = force (many1 p +++ return [])</font>+<a name="(line103)"></a>+<a name="(line104)"></a><a name="many1"></a>many1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line105)"></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>;</font> xs <font color=Red><-</font> many p<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line106)"></a>+<a name="(line107)"></a><a name="sepby"></a>sepby <font color=Red>::</font> Parser a <font color=Red>-></font> Parser b <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line108)"></a><a name="sepby"></a>p <font color=Cyan>`sepby`</font> sep <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`sepby1`</font> sep<font color=Cyan>)</font> <font color=Cyan>+++</font> return []+<a name="(line109)"></a>+<a name="(line110)"></a><a name="sepby1"></a>sepby1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser b <font color=Red>-></font> Parser <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line111)"></a><a name="sepby1"></a>p <font color=Cyan>`sepby1`</font> sep <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> xs <font color=Red><-</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><font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line112)"></a>+<a name="(line113)"></a><a name="chainl"></a>chainl <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> a <font color=Red>-></font> Parser a+<a name="(line114)"></a>chainl p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainl1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v+<a name="(line115)"></a>+<a name="(line116)"></a><a name="chainl1"></a>chainl1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> Parser a+<a name="(line117)"></a><a name="chainl1"></a>p <font color=Cyan>`chainl1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>+<a name="(line118)"></a> <font color=Green><u>where</u></font>+<a name="(line119)"></a> rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>f <font color=Red><-</font> op<font color=Cyan>;</font> y <font color=Red><-</font> p<font color=Cyan>;</font> rest <font color=Cyan>(</font>f x y<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line120)"></a> <font color=Cyan>+++</font> return x+<a name="(line121)"></a>+<a name="(line122)"></a><a name="chainr"></a>chainr <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> a <font color=Red>-></font> Parser a+<a name="(line123)"></a>chainr p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainr1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v+<a name="(line124)"></a>+<a name="(line125)"></a><a name="chainr1"></a>chainr1 <font color=Red>::</font> Parser a <font color=Red>-></font> Parser <font color=Cyan>(</font>a <font color=Red>-></font> a <font color=Red>-></font> a<font color=Cyan>)</font> <font color=Red>-></font> Parser a+<a name="(line126)"></a><a name="chainr1"></a>p <font color=Cyan>`chainr1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>+<a name="(line127)"></a> <font color=Green><u>where</u></font>+<a name="(line128)"></a> rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>f <font color=Red><-</font> op<font color=Cyan>;</font> y <font color=Red><-</font> p <font color=Cyan>`chainr1`</font> op<font color=Cyan>;</font> return <font color=Cyan>(</font>f x y<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line129)"></a> <font color=Cyan>+++</font> return x+<a name="(line130)"></a>+<a name="(line131)"></a><a name="ops"></a>ops <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>Parser a<font color=Cyan>,</font> b<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser b+<a name="(line132)"></a>ops xs <font color=Red>=</font> foldr1 <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>[</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>p<font color=Cyan>;</font> return op<font color=Cyan>}</font> <font color=Red>|</font> <font color=Cyan>(</font>p<font color=Cyan>,</font>op<font color=Cyan>)</font> <font color=Red><-</font> xs<font color=Red>]</font>+<a name="(line133)"></a>+<a name="(line134)"></a><a name="bracket"></a>bracket <font color=Red>::</font> Parser a <font color=Red>-></font> Parser b <font color=Red>-></font> Parser c <font color=Red>-></font> Parser b+<a name="(line135)"></a>bracket open p close <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>open<font color=Cyan>;</font> x <font color=Red><-</font> p<font color=Cyan>;</font> close<font color=Cyan>;</font> return x<font color=Cyan>}</font>+<a name="(line136)"></a>+<a name="(line137)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line138)"></a><font color=Blue>-- * Useful parsers</font>+<a name="(line139)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line140)"></a>+<a name="(line141)"></a><a name="char"></a>char <font color=Red>::</font> Char <font color=Red>-></font> Parser Char+<a name="(line142)"></a>char x <font color=Red>=</font> sat <font color=Cyan>(</font><font color=Red>\</font>y <font color=Red>-></font> x <font color=Cyan>==</font> y<font color=Cyan>)</font>+<a name="(line143)"></a>+<a name="(line144)"></a><a name="digit"></a>digit <font color=Red>::</font> Parser Char+<a name="(line145)"></a>digit <font color=Red>=</font> sat isDigit+<a name="(line146)"></a>+<a name="(line147)"></a><a name="lower"></a>lower <font color=Red>::</font> Parser Char+<a name="(line148)"></a>lower <font color=Red>=</font> sat isLower+<a name="(line149)"></a>+<a name="(line150)"></a><a name="upper"></a>upper <font color=Red>::</font> Parser Char+<a name="(line151)"></a>upper <font color=Red>=</font> sat isUpper+<a name="(line152)"></a>+<a name="(line153)"></a><a name="letter"></a>letter <font color=Red>::</font> Parser Char+<a name="(line154)"></a>letter <font color=Red>=</font> sat isAlpha+<a name="(line155)"></a>+<a name="(line156)"></a><a name="alphanum"></a>alphanum <font color=Red>::</font> Parser Char+<a name="(line157)"></a>alphanum <font color=Red>=</font> sat isAlphaNum <font color=Cyan>+++</font> char <font color=Magenta>'_'</font>+<a name="(line158)"></a>+<a name="(line159)"></a><a name="string"></a>string <font color=Red>::</font> String <font color=Red>-></font> Parser String+<a name="(line160)"></a>string <font color=Magenta>""</font> <font color=Red>=</font> return <font color=Magenta>""</font>+<a name="(line161)"></a>string <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font> <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>char x<font color=Cyan>;</font> string xs<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line162)"></a>+<a name="(line163)"></a><a name="ident"></a>ident <font color=Red>::</font> Parser String+<a name="(line164)"></a>ident <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> lower<font color=Cyan>;</font> xs <font color=Red><-</font> many alphanum<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line165)"></a>+<a name="(line166)"></a><a name="nat"></a>nat <font color=Red>::</font> Parser Int+<a name="(line167)"></a>nat <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> digit<font color=Cyan>;</font> return <font color=Cyan>(</font>fromEnum x <font color=Blue>-</font> fromEnum <font color=Magenta>'0'</font><font color=Cyan>)</font><font color=Cyan>}</font> <font color=Cyan>`chainl1`</font> return op+<a name="(line168)"></a> <font color=Green><u>where</u></font>+<a name="(line169)"></a> m <font color=Cyan>`op`</font> n <font color=Red>=</font> <font color=Magenta>10</font><font color=Cyan>*</font>m <font color=Cyan>+</font> n+<a name="(line170)"></a>+<a name="(line171)"></a><a name="int"></a>int <font color=Red>::</font> Parser Int+<a name="(line172)"></a>int <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>char <font color=Magenta>'-'</font><font color=Cyan>;</font> n <font color=Red><-</font> nat<font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Blue>-</font>n<font color=Cyan>)</font><font color=Cyan>}</font> <font color=Cyan>+++</font> nat+<a name="(line173)"></a>+<a name="(line174)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line175)"></a><font color=Blue>-- * Lexical combinators</font>+<a name="(line176)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line177)"></a>+<a name="(line178)"></a><a name="spaces"></a>spaces <font color=Red>::</font> Parser ()+<a name="(line179)"></a>spaces <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>many1 <font color=Cyan>(</font>sat isSpace<font color=Cyan>)</font><font color=Cyan>;</font> return ()<font color=Cyan>}</font>+<a name="(line180)"></a>+<a name="(line181)"></a><a name="comment"></a>comment <font color=Red>::</font> Parser ()+<a name="(line182)"></a><font color=Blue>--comment = do {string "--"; many (sat (\x -> x /= '\n')); return ()}</font>+<a name="(line183)"></a><font color=Blue>--comment = do </font>+<a name="(line184)"></a><font color=Blue>-- _ <- string "--"</font>+<a name="(line185)"></a><font color=Blue>-- _ <- many (sat (\x -> x /= '\n'))</font>+<a name="(line186)"></a><font color=Blue>-- return ()</font>+<a name="(line187)"></a>comment <font color=Red>=</font> <font color=Green><u>do</u></font>+<a name="(line188)"></a> bracket <font color=Cyan>(</font>string <font color=Magenta>"/*"</font><font color=Cyan>)</font> <font color=Cyan>(</font>many item<font color=Cyan>)</font> <font color=Cyan>(</font>string <font color=Magenta>"*/"</font><font color=Cyan>)</font>+<a name="(line189)"></a> return ()+<a name="(line190)"></a>+<a name="(line191)"></a><a name="junk"></a>junk <font color=Red>::</font> Parser ()+<a name="(line192)"></a>junk <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>many <font color=Cyan>(</font>spaces <font color=Cyan>+++</font> comment<font color=Cyan>)</font><font color=Cyan>;</font> return ()<font color=Cyan>}</font>+<a name="(line193)"></a>+<a name="(line194)"></a><a name="skip"></a>skip <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a+<a name="(line195)"></a>skip p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>junk<font color=Cyan>;</font> p<font color=Cyan>}</font>+<a name="(line196)"></a>+<a name="(line197)"></a><a name="token"></a>token <font color=Red>::</font> Parser a <font color=Red>-></font> Parser a+<a name="(line198)"></a>token p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>v <font color=Red><-</font> p<font color=Cyan>;</font> junk<font color=Cyan>;</font> return v<font color=Cyan>}</font>+<a name="(line199)"></a>+<a name="(line200)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line201)"></a><font color=Blue>-- * Token parsers</font>+<a name="(line202)"></a><font color=Blue>-- ------------------------------------------------------------</font>+<a name="(line203)"></a>+<a name="(line204)"></a><a name="natural"></a>natural <font color=Red>::</font> Parser Int+<a name="(line205)"></a>natural <font color=Red>=</font> token nat+<a name="(line206)"></a>+<a name="(line207)"></a><a name="integer"></a>integer <font color=Red>::</font> Parser Int+<a name="(line208)"></a>integer <font color=Red>=</font> token int+<a name="(line209)"></a>+<a name="(line210)"></a><a name="symbol"></a>symbol <font color=Red>::</font> String <font color=Red>-></font> Parser String+<a name="(line211)"></a>symbol xs <font color=Red>=</font> token <font color=Cyan>(</font>string xs<font color=Cyan>)</font>+<a name="(line212)"></a>+<a name="(line213)"></a><a name="identifier"></a>identifier <font color=Red>::</font> <font color=Red>[</font>String<font color=Red>]</font> <font color=Red>-></font> Parser String+<a name="(line214)"></a>identifier ks <font color=Red>=</font> token <font color=Cyan>(</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> ident<font color=Cyan>;</font>+<a name="(line215)"></a> <font color=Green><u>if</u></font> not <font color=Cyan>(</font>elem x ks<font color=Cyan>)</font> <font color=Green><u>then</u></font> return x+<a name="(line216)"></a> <font color=Green><u>else</u></font> return mzero<font color=Cyan>}</font><font color=Cyan>)</font>+<a name="(line217)"></a>+<a name="(line218)"></a><font color=Blue>------------------------------------------------------------------------------</font> </pre>+</html>
docs/haddock/src/Text/ParserCombinators/HuttonMeijerWallace.html view
@@ -1,298 +1,301 @@-<pre><font color=Cyan>{</font><font color=Blue>-----------------------------------------------------------------------------</font>-- A LIBRARY OF MONADIC PARSER COMBINATORS-- <font color=Magenta>29</font>th July <font color=Magenta>1996</font>-- Graham Hutton Erik Meijer- University <font color=Green><u>of</u></font> Nottingham University <font color=Green><u>of</u></font> Utrecht--This Haskell <font color=Magenta>1.3</font> script defines a library <font color=Green><u>of</u></font> parser combinators<font color=Cyan>,</font> and is taken-<a name="from"></a>from sections <font color=Magenta>1</font><font color=Blue>-</font><font color=Magenta>6</font> <font color=Green><u>of</u></font> our article <font color=Magenta>"Monadic Parser Combinators"</font><font color=Cyan>.</font> Some changes-<a name="to"></a>to the library have been made <font color=Green><u>in</u></font> the move from Gofer to Haskell<font color=Red><b>:</b></font>-- <font color=Cyan>*</font> Do notation is used <font color=Green><u>in</u></font> place <font color=Green><u>of</u></font> monad comprehension notation<font color=Cyan>;</font>-- <font color=Cyan>*</font> The parser datatype is defined using <font color=Magenta>"newtype"</font><font color=Cyan>,</font> to avoid the overhead- <font color=Green><u>of</u></font> tagging and untagging parsers with the P constructor<font color=Cyan>.</font>--<font color=Blue>------------------------------------------------------------------------------</font>-<font color=Cyan>**</font> Extended to allow a symbol table<font color=Cyan>/</font>state to be threaded through the monad<font color=Cyan>.</font>-<font color=Cyan>**</font> Extended to allow a parameterised token <font color=Green><u>type</u></font><font color=Cyan>,</font> rather than just strings<font color=Cyan>.</font>-<font color=Cyan>**</font> Extended to allow error<font color=Blue>-</font>reporting<font color=Cyan>.</font>--<font color=Cyan>(</font>Extensions<font color=Red><b>:</b></font> <font color=Magenta>1998</font><font color=Blue>-</font><font color=Magenta>2000</font> Malcolm<font color=Cyan>.</font>Wallace<font color=Red>@</font>cs<font color=Cyan>.</font>york<font color=Cyan>.</font>ac<font color=Cyan>.</font>uk<font color=Cyan>)</font>-<a name="------------------------------------------------------------------------------}"></a><font color=Cyan>(</font>More extensions<font color=Red><b>:</b></font> <font color=Magenta>2004</font> gk<font color=Blue>-</font>haskell<font color=Red>@</font>ninebynine<font color=Cyan>.</font>org<font color=Cyan>)</font>--<font color=Cyan>------------------------------------------------------------------------------}</font>--<font color=Blue>-- | This library of monadic parser combinators is based on the ones</font>-<font color=Blue>-- defined by Graham Hutton and Erik Meijer. It has been extended by</font>-<font color=Blue>-- Malcolm Wallace to use an abstract token type (no longer just a</font>-<font color=Blue>-- string) as input, and to incorporate a State Transformer monad, useful</font>-<font color=Blue>-- for symbol tables, macros, and so on. Basic facilities for error</font>-<font color=Blue>-- reporting have also been added, and later extended by Graham Klyne</font>-<font color=Blue>-- to return the errors through an @Either@ type, rather than just</font>-<font color=Blue>-- calling @error@.</font>--<font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>HuttonMeijerWallace- <font color=Cyan>(</font>- <font color=Blue>-- * The parser monad</font>- Parser<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font>- <font color=Blue>-- * Primitive parser combinators</font>- <font color=Cyan>,</font> item<font color=Cyan>,</font> eof<font color=Cyan>,</font> papply<font color=Cyan>,</font> papply'- <font color=Blue>-- * Derived combinators</font>- <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Blue>{-sat,-}</font> tok<font color=Cyan>,</font> nottok<font color=Cyan>,</font> many<font color=Cyan>,</font> many1- <font color=Cyan>,</font> sepby<font color=Cyan>,</font> sepby1<font color=Cyan>,</font> chainl<font color=Cyan>,</font> chainl1<font color=Cyan>,</font> chainr<font color=Cyan>,</font> chainr1<font color=Cyan>,</font> ops<font color=Cyan>,</font> bracket- <font color=Cyan>,</font> toEOF- <font color=Blue>-- * Error handling</font>- <font color=Cyan>,</font> elserror- <font color=Blue>-- * State handling</font>- <font color=Cyan>,</font> stupd<font color=Cyan>,</font> stquery<font color=Cyan>,</font> stget- <font color=Blue>-- * Re-parsing</font>- <font color=Cyan>,</font> reparse- <font color=Cyan>)</font> <font color=Green><u>where</u></font>--<font color=Green><u>import</u></font> Char-<font color=Green><u>import</u></font> Monad--<font color=Green><u>infixr</u></font> <font color=Magenta>5</font> <font color=Cyan>+++</font>--<font color=Blue>--- The parser monad ---------------------------------------------------------</font>--<a name="ParseResult"></a><font color=Green><u>type</u></font> ParseResult s t e a <font color=Red>=</font> Either e <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s<font color=Cyan>,</font><font color=Red>[</font>Either e t<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>--<font color=Green><u>newtype</u></font> Parser s t e a <font color=Red>=</font> P <font color=Cyan>(</font> s <font color=Red>-></font> <font color=Red>[</font>Either e t<font color=Red>]</font> <font color=Red>-></font> ParseResult s t e a <font color=Cyan>)</font>- <font color=Blue>-- ^ The parser type is parametrised on the types of the state @s@,</font>- <font color=Blue>-- the input tokens @t@, error-type @e@, and the result value @a@.</font>- <font color=Blue>-- The state and remaining input are threaded through the monad.</font>--<font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t e<font color=Cyan>)</font> <font color=Green><u>where</u></font>- <font color=Blue>-- fmap :: (a -> b) -> (Parser s t e a -> Parser s t e b)</font>- 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>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> p st inp <font color=Green><u>of</u></font>- Right res <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>f v<font color=Cyan>,</font> s<font color=Cyan>,</font> out<font color=Cyan>)</font> <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>s<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> res<font color=Red>]</font>- Left err <font color=Red>-></font> Left err- <font color=Cyan>)</font>--<font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t e<font color=Cyan>)</font> <font color=Green><u>where</u></font>- <font color=Blue>-- return :: a -> Parser s t e a</font>- return v <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>v<font color=Cyan>,</font>st<font color=Cyan>,</font>inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>- <font color=Blue>-- >>= :: Parser s t e a -> (a -> Parser s t e b) -> Parser s t e b</font>- <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>>>=</font> f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> p st inp <font color=Green><u>of</u></font>- Right res <font color=Red>-></font> foldr joinresults <font color=Cyan>(</font>Right <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- <font color=Red>[</font> papply' <font color=Cyan>(</font>f v<font color=Cyan>)</font> s out <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>s<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> res <font color=Red>]</font>- Left err <font color=Red>-></font> Left err- <font color=Cyan>)</font>- <font color=Blue>-- fail :: String -> Parser s t e a</font>- fail err <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> Right <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- <font color=Blue>-- I know it's counterintuitive, but we want no-parse, not an error.</font>--<font color=Green><u>instance</u></font> MonadPlus <font color=Cyan>(</font>Parser s t e<font color=Cyan>)</font> <font color=Green><u>where</u></font>- <font color=Blue>-- mzero :: Parser s t e a</font>- mzero <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> Right <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- <font color=Blue>-- mplus :: Parser s t e a -> Parser s t e a -> Parser s t e a</font>- <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`mplus`</font> <font color=Cyan>(</font>P q<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> joinresults <font color=Cyan>(</font>p st inp<font color=Cyan>)</font> <font color=Cyan>(</font>q st inp<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- joinresults ensures that explicitly raised errors are dominant,</font>-<font color=Blue>-- provided no parse has yet been found. The commented out code is</font>-<font color=Blue>-- a slightly stricter specification of the real code.</font>-joinresults <font color=Red>::</font> ParseResult s t e a <font color=Red>-></font> ParseResult s t e a <font color=Red>-></font> ParseResult s t e a-<font color=Blue>{--joinresults (Left p) (Left q) = Left p-joinresults (Left p) (Right _) = Left p-joinresults (Right []) (Left q) = Left q-joinresults (Right p) (Left q) = Right p-joinresults (Right p) (Right q) = Right (p++q)--}</font>-<a name="joinresults"></a>joinresults <font color=Cyan>(</font>Left p<font color=Cyan>)</font> q <font color=Red>=</font> Left p-joinresults <font color=Cyan>(</font>Right <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font> q <font color=Red>=</font> q-joinresults <font color=Cyan>(</font>Right p<font color=Cyan>)</font> q <font color=Red>=</font> Right <font color=Cyan>(</font>p<font color=Cyan>++</font> <font color=Green><u>case</u></font> q <font color=Green><u>of</u></font> Left <font color=Green><u>_</u></font> <font color=Red>-></font> <font color=Red>[</font><font color=Red>]</font>- Right r <font color=Red>-></font> r<font color=Cyan>)</font>---<font color=Blue>--- Primitive parser combinators ---------------------------------------------</font>--<font color=Blue>-- | Deliver the first remaining token.</font>-item <font color=Red>::</font> Parser s t e t-<a name="item"></a>item <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> Right <font color=Red>[</font><font color=Red>]</font>- <font color=Cyan>(</font>Left e<font color=Red><b>:</b></font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left e- <font color=Cyan>(</font>Right x<font color=Red><b>:</b></font> xs<font color=Cyan>)</font> <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>x<font color=Cyan>,</font>st<font color=Cyan>,</font>xs<font color=Cyan>)</font><font color=Red>]</font>- <font color=Cyan>)</font>--<font color=Blue>-- | Fail if end of input is not reached</font>-eof <font color=Red>::</font> Show p <font color=Red>=></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="eof"></a>eof <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font><font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font>st<font color=Cyan>,</font><font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>- <font color=Cyan>(</font>Left e<font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left e- <font color=Cyan>(</font>Right <font color=Cyan>(</font>p<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left <font color=Cyan>(</font><font color=Magenta>"End of input expected at "</font>- <font color=Cyan>++</font>show p<font color=Cyan>++</font><font color=Magenta>"\n but found text"</font><font color=Cyan>)</font>- <font color=Cyan>)</font>--<font color=Blue>{---- | Ensure the value delivered by the parser is evaluated to WHNF.-force :: Parser s t e a -> Parser s t e a-force (P p) = P (\st inp -> let Right xs = p st inp- h = head xs in- h `seq` Right (h: tail xs)- )--- [[[GK]]] ^^^^^^--- WHNF = Weak Head Normal Form, meaning that it has no top-level redex.--- In this case, I think that means that the first element of the list--- is fully evaluated.------ NOTE: the original form of this function fails if there is no parse--- result for p st inp (head xs fails if xs is null), so the modified--- form can assume a Right value only.------ Why is this needed?--- It's not exported, and the only use of this I see is commented out.------------------------------------------}</font>---<font color=Blue>-- | Deliver the first parse result only, eliminating any backtracking.</font>-first <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e a-<a name="first"></a>first <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> p st inp <font color=Green><u>of</u></font>- Right <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font> <font color=Red>-></font> Right <font color=Red>[</font>x<font color=Red>]</font>- otherwise <font color=Red>-></font> otherwise- <font color=Cyan>)</font>--<font color=Blue>-- | Apply the parser to some real input, given an initial state value.</font>-<font color=Blue>-- If the parser fails, raise 'error' to halt the program.</font>-<font color=Blue>-- (This is the original exported behaviour - to allow the caller to</font>-<font color=Blue>-- deal with the error differently, see @papply'@.)</font>-papply <font color=Red>::</font> Parser s t String a <font color=Red>-></font> s <font color=Red>-></font> <font color=Red>[</font>Either String t<font color=Red>]</font>- <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s<font color=Cyan>,</font><font color=Red>[</font>Either String t<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>-<a name="papply"></a>papply <font color=Cyan>(</font>P p<font color=Cyan>)</font> st inp <font color=Red>=</font> either error id <font color=Cyan>(</font>p st inp<font color=Cyan>)</font>--<font color=Blue>-- | Apply the parser to some real input, given an initial state value.</font>-<font color=Blue>-- If the parser fails, return a diagnostic message to the caller.</font>-papply' <font color=Red>::</font> Parser s t e a <font color=Red>-></font> s <font color=Red>-></font> <font color=Red>[</font>Either e t<font color=Red>]</font>- <font color=Red>-></font> Either e <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s<font color=Cyan>,</font><font color=Red>[</font>Either e t<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>-<a name="papply'"></a>papply' <font color=Cyan>(</font>P p<font color=Cyan>)</font> st inp <font color=Red>=</font> p st inp--<font color=Blue>--- Derived combinators ------------------------------------------------------</font>--<font color=Blue>-- | A choice between parsers. Keep only the first success.</font>-<a name="+++"></a><font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e a <font color=Red>-></font> Parser s t e a-<a name="p"></a>p <font color=Cyan>+++</font> q <font color=Red>=</font> first <font color=Cyan>(</font>p <font color=Cyan>`mplus`</font> q<font color=Cyan>)</font>--<font color=Blue>-- | Deliver the first token if it satisfies a predicate.</font>-sat <font color=Red>::</font> <font color=Cyan>(</font>t <font color=Red>-></font> Bool<font color=Cyan>)</font> <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e t-<a name="sat"></a>sat p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>x<font color=Cyan>)</font> <font color=Red><-</font> item<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> mzero<font color=Cyan>}</font>--<font color=Blue>-- | Deliver the first token if it equals the argument.</font>-tok <font color=Red>::</font> Eq t <font color=Red>=></font> t <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e t-<a name="tok"></a>tok t <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>x<font color=Cyan>)</font> <font color=Red><-</font> item<font color=Cyan>;</font> <font color=Green><u>if</u></font> x<font color=Cyan>==</font>t <font color=Green><u>then</u></font> return t <font color=Green><u>else</u></font> mzero<font color=Cyan>}</font>--<font color=Blue>-- | Deliver the first token if it does not equal the argument.</font>-nottok <font color=Red>::</font> Eq t <font color=Red>=></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e t-<a name="nottok"></a>nottok ts <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>x<font color=Cyan>)</font> <font color=Red><-</font> item<font color=Cyan>;</font> <font color=Green><u>if</u></font> x <font color=Cyan>`notElem`</font> ts <font color=Green><u>then</u></font> return x- <font color=Green><u>else</u></font> mzero<font color=Cyan>}</font>--<font color=Blue>-- | Deliver zero or more values of @a@.</font>-many <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>-<a name="many"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>+++</font> return <font color=Red>[</font><font color=Red>]</font>-<font color=Blue>--many p = force (many1 p +++ return [])</font>--<font color=Blue>-- | Deliver one or more values of @a@.</font>-many1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>-<a name="many1"></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>;</font> xs <font color=Red><-</font> many p<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>--<font color=Blue>-- | Deliver zero or more values of @a@ separated by @b@'s.</font>-sepby <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e b <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepby"></a>p <font color=Cyan>`sepby`</font> sep <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`sepby1`</font> sep<font color=Cyan>)</font> <font color=Cyan>+++</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Deliver one or more values of @a@ separated by @b@'s.</font>-sepby1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e b <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepby1"></a>p <font color=Cyan>`sepby1`</font> sep <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> xs <font color=Red><-</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><font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>--chainl <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> a- <font color=Red>-></font> Parser s t e a-<a name="chainl"></a>chainl p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainl1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v--chainl1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e a-<a name="chainl1"></a>p <font color=Cyan>`chainl1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>- <font color=Green><u>where</u></font>- rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>f <font color=Red><-</font> op<font color=Cyan>;</font> y <font color=Red><-</font> p<font color=Cyan>;</font> rest <font color=Cyan>(</font>f x y<font color=Cyan>)</font><font color=Cyan>}</font>- <font color=Cyan>+++</font> return x--chainr <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> a- <font color=Red>-></font> Parser s t e a-<a name="chainr"></a>chainr p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainr1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v--chainr1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e a-<a name="chainr1"></a>p <font color=Cyan>`chainr1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>- <font color=Green><u>where</u></font>- rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> f <font color=Red><-</font> op- <font color=Cyan>;</font> y <font color=Red><-</font> p <font color=Cyan>`chainr1`</font> op- <font color=Cyan>;</font> return <font color=Cyan>(</font>f x y<font color=Cyan>)</font>- <font color=Cyan>}</font>- <font color=Cyan>+++</font> return x--ops <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>Parser s t e a<font color=Cyan>,</font> b<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser s t e b-<a name="ops"></a>ops xs <font color=Red>=</font> foldr1 <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>[</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>p<font color=Cyan>;</font> return op<font color=Cyan>}</font> <font color=Red>|</font> <font color=Cyan>(</font>p<font color=Cyan>,</font>op<font color=Cyan>)</font> <font color=Red><-</font> xs<font color=Red>]</font>--bracket <font color=Red>::</font> <font color=Cyan>(</font>Show p<font color=Cyan>,</font>Show t<font color=Cyan>)</font> <font color=Red>=></font>- Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e a <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e b <font color=Red>-></font>- Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e c <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e b-<a name="bracket"></a>bracket open p close <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> open- <font color=Cyan>;</font> x <font color=Red><-</font> p- <font color=Cyan>;</font> close <font color=Blue>-- `elserror` "improperly matched construct";</font>- <font color=Cyan>;</font> return x- <font color=Cyan>}</font>--<font color=Blue>-- | Accept a complete parse of the input only, no partial parses.</font>-toEOF <font color=Red>::</font> Show p <font color=Red>=></font>- Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a-<a name="toEOF"></a>toEOF 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>;</font> eof<font color=Cyan>;</font> return x <font color=Cyan>}</font>---<font color=Blue>--- Error handling -----------------------------------------------------------</font>--<font color=Blue>-- | Return an error using the supplied diagnostic string, and a token type</font>-<font color=Blue>-- which includes position information.</font>-parseerror <font color=Red>::</font> <font color=Cyan>(</font>Show p<font color=Cyan>,</font>Show t<font color=Cyan>)</font> <font color=Red>=></font> String <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a-<a name="parseerror"></a>parseerror err <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font>- <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> Left <font color=Magenta>"Parse error: unexpected EOF\n"</font>- <font color=Cyan>(</font>Left e<font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left <font color=Cyan>(</font><font color=Magenta>"Lexical error: "</font><font color=Cyan>++</font>e<font color=Cyan>)</font>- <font color=Cyan>(</font>Right <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font>- Left <font color=Cyan>(</font><font color=Magenta>"Parse error: in "</font><font color=Cyan>++</font>show p<font color=Cyan>++</font><font color=Magenta>"\n "</font>- <font color=Cyan>++</font>err<font color=Cyan>++</font><font color=Magenta>"\n "</font><font color=Cyan>++</font><font color=Magenta>"Found "</font><font color=Cyan>++</font>show t<font color=Cyan>)</font>- <font color=Cyan>)</font>---<font color=Blue>-- | If the parser fails, generate an error message.</font>-elserror <font color=Red>::</font> <font color=Cyan>(</font>Show p<font color=Cyan>,</font>Show t<font color=Cyan>)</font> <font color=Red>=></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a <font color=Red>-></font> String- <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a-<a name="elserror"></a>p <font color=Cyan>`elserror`</font> s <font color=Red>=</font> p <font color=Cyan>+++</font> parseerror s--<font color=Blue>--- State handling -----------------------------------------------------------</font>--<font color=Blue>-- | Update the internal state.</font>-stupd <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="stupd"></a>stupd f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> <font color=Blue>{-let newst = f st in newst `seq`-}</font>- Right <font color=Red>[</font><font color=Cyan>(</font><font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> f st<font color=Cyan>,</font> inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>--<font color=Blue>-- | Query the internal state.</font>-stquery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e a-<a name="stquery"></a>stquery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>f st<font color=Cyan>,</font> st<font color=Cyan>,</font> inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>--<font color=Blue>-- | Deliver the entire internal state.</font>-stget <font color=Red>::</font> Parser s t e s-<a name="stget"></a>stget <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>st<font color=Cyan>,</font> st<font color=Cyan>,</font> inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>---<font color=Blue>--- Push some tokens back onto the input stream and reparse ------------------</font>--<font color=Blue>-- | This is useful for recursively expanding macros. When the</font>-<font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>-<font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>-<font color=Blue>-- lexed expansion back down into the parser.</font>-reparse <font color=Red>::</font> <font color=Red>[</font>Either e t<font color=Red>]</font> <font color=Red>-></font> Parser s t e <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="reparse"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font><font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> st<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------------</font>+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">+<html>+<pre><a name="(line1)"></a><font color=Blue>{-----------------------------------------------------------------------------+<a name="(line2)"></a>+<a name="(line3)"></a> A LIBRARY OF MONADIC PARSER COMBINATORS+<a name="(line4)"></a>+<a name="(line5)"></a> 29th July 1996+<a name="(line6)"></a>+<a name="(line7)"></a> Graham Hutton Erik Meijer+<a name="(line8)"></a> University of Nottingham University of Utrecht+<a name="(line9)"></a>+<a name="(line10)"></a>This Haskell 1.3 script defines a library of parser combinators, and is taken+<a name="(line11)"></a>from sections 1-6 of our article "Monadic Parser Combinators". Some changes+<a name="(line12)"></a>to the library have been made in the move from Gofer to Haskell:+<a name="(line13)"></a>+<a name="(line14)"></a> * Do notation is used in place of monad comprehension notation;+<a name="(line15)"></a>+<a name="(line16)"></a> * The parser datatype is defined using "newtype", to avoid the overhead+<a name="(line17)"></a> of tagging and untagging parsers with the P constructor.+<a name="(line18)"></a>+<a name="(line19)"></a>------------------------------------------------------------------------------+<a name="(line20)"></a>** Extended to allow a symbol table/state to be threaded through the monad.+<a name="(line21)"></a>** Extended to allow a parameterised token type, rather than just strings.+<a name="(line22)"></a>** Extended to allow error-reporting.+<a name="(line23)"></a>+<a name="(line24)"></a>(Extensions: 1998-2000 Malcolm.Wallace@cs.york.ac.uk)+<a name="(line25)"></a>(More extensions: 2004 gk-haskell@ninebynine.org)+<a name="(line26)"></a>+<a name="(line27)"></a>------------------------------------------------------------------------------}</font>+<a name="(line28)"></a>+<a name="(line29)"></a><font color=Blue>-- | This library of monadic parser combinators is based on the ones</font>+<a name="(line30)"></a><font color=Blue>-- defined by Graham Hutton and Erik Meijer. It has been extended by</font>+<a name="(line31)"></a><font color=Blue>-- Malcolm Wallace to use an abstract token type (no longer just a</font>+<a name="(line32)"></a><font color=Blue>-- string) as input, and to incorporate state in the monad, useful</font>+<a name="(line33)"></a><font color=Blue>-- for symbol tables, macros, and so on. Basic facilities for error</font>+<a name="(line34)"></a><font color=Blue>-- reporting have also been added, and later extended by Graham Klyne</font>+<a name="(line35)"></a><font color=Blue>-- to return the errors through an @Either@ type, rather than just</font>+<a name="(line36)"></a><font color=Blue>-- calling @error@.</font>+<a name="(line37)"></a>+<a name="(line38)"></a><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>HuttonMeijerWallace+<a name="(line39)"></a> <font color=Cyan>(</font>+<a name="(line40)"></a> <font color=Blue>-- * The parser monad</font>+<a name="(line41)"></a> Parser<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font>+<a name="(line42)"></a> <font color=Blue>-- * Primitive parser combinators</font>+<a name="(line43)"></a> <font color=Cyan>,</font> item<font color=Cyan>,</font> eof<font color=Cyan>,</font> papply<font color=Cyan>,</font> papply'+<a name="(line44)"></a> <font color=Blue>-- * Derived combinators</font>+<a name="(line45)"></a> <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Blue>{-sat,-}</font> tok<font color=Cyan>,</font> nottok<font color=Cyan>,</font> many<font color=Cyan>,</font> many1+<a name="(line46)"></a> <font color=Cyan>,</font> sepby<font color=Cyan>,</font> sepby1<font color=Cyan>,</font> chainl<font color=Cyan>,</font> chainl1<font color=Cyan>,</font> chainr<font color=Cyan>,</font> chainr1<font color=Cyan>,</font> ops<font color=Cyan>,</font> bracket+<a name="(line47)"></a> <font color=Cyan>,</font> toEOF+<a name="(line48)"></a> <font color=Blue>-- * Error handling</font>+<a name="(line49)"></a> <font color=Cyan>,</font> elserror+<a name="(line50)"></a> <font color=Blue>-- * State handling</font>+<a name="(line51)"></a> <font color=Cyan>,</font> stupd<font color=Cyan>,</font> stquery<font color=Cyan>,</font> stget+<a name="(line52)"></a> <font color=Blue>-- * Re-parsing</font>+<a name="(line53)"></a> <font color=Cyan>,</font> reparse+<a name="(line54)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line55)"></a>+<a name="(line56)"></a><font color=Green><u>import</u></font> Char+<a name="(line57)"></a><font color=Green><u>import</u></font> Monad+<a name="(line58)"></a>+<a name="(line59)"></a><font color=Green><u>infixr</u></font> <font color=Magenta>5</font> <font color=Cyan>+++</font>+<a name="(line60)"></a>+<a name="(line61)"></a><font color=Blue>--- The parser monad ---------------------------------------------------------</font>+<a name="(line62)"></a>+<a name="(line63)"></a><a name="ParseResult"></a><font color=Green><u>type</u></font> ParseResult s t e a <font color=Red>=</font> Either e <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s<font color=Cyan>,</font><font color=Red>[</font>Either e t<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>+<a name="(line64)"></a>+<a name="(line65)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser s t e a <font color=Red>=</font> P <font color=Cyan>(</font> s <font color=Red>-></font> <font color=Red>[</font>Either e t<font color=Red>]</font> <font color=Red>-></font> ParseResult s t e a <font color=Cyan>)</font>+<a name="(line66)"></a> <font color=Blue>-- ^ The parser type is parametrised on the types of the state @s@,</font>+<a name="(line67)"></a> <font color=Blue>-- the input tokens @t@, error-type @e@, and the result value @a@.</font>+<a name="(line68)"></a> <font color=Blue>-- The state and remaining input are threaded through the monad.</font>+<a name="(line69)"></a>+<a name="(line70)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t e<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line71)"></a> <font color=Blue>-- fmap :: (a -> b) -> (Parser s t e a -> Parser s t e b)</font>+<a name="(line72)"></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>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> p st inp <font color=Green><u>of</u></font>+<a name="(line73)"></a> Right res <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>f v<font color=Cyan>,</font> s<font color=Cyan>,</font> out<font color=Cyan>)</font> <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>s<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> res<font color=Red>]</font>+<a name="(line74)"></a> Left err <font color=Red>-></font> Left err+<a name="(line75)"></a> <font color=Cyan>)</font>+<a name="(line76)"></a>+<a name="(line77)"></a><font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t e<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line78)"></a> <font color=Blue>-- return :: a -> Parser s t e a</font>+<a name="(line79)"></a> return v <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>v<font color=Cyan>,</font>st<font color=Cyan>,</font>inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line80)"></a> <font color=Blue>-- >>= :: Parser s t e a -> (a -> Parser s t e b) -> Parser s t e b</font>+<a name="(line81)"></a> <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>>>=</font> f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> p st inp <font color=Green><u>of</u></font>+<a name="(line82)"></a> Right res <font color=Red>-></font> foldr joinresults <font color=Cyan>(</font>Right []<font color=Cyan>)</font>+<a name="(line83)"></a> <font color=Red>[</font> papply' <font color=Cyan>(</font>f v<font color=Cyan>)</font> s out <font color=Red>|</font> <font color=Cyan>(</font>v<font color=Cyan>,</font>s<font color=Cyan>,</font>out<font color=Cyan>)</font> <font color=Red><-</font> res <font color=Red>]</font>+<a name="(line84)"></a> Left err <font color=Red>-></font> Left err+<a name="(line85)"></a> <font color=Cyan>)</font>+<a name="(line86)"></a> <font color=Blue>-- fail :: String -> Parser s t e a</font>+<a name="(line87)"></a> fail err <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> Right []<font color=Cyan>)</font>+<a name="(line88)"></a> <font color=Blue>-- I know it's counterintuitive, but we want no-parse, not an error.</font>+<a name="(line89)"></a>+<a name="(line90)"></a><font color=Green><u>instance</u></font> MonadPlus <font color=Cyan>(</font>Parser s t e<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line91)"></a> <font color=Blue>-- mzero :: Parser s t e a</font>+<a name="(line92)"></a> mzero <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> Right []<font color=Cyan>)</font>+<a name="(line93)"></a> <font color=Blue>-- mplus :: Parser s t e a -> Parser s t e a -> Parser s t e a</font>+<a name="(line94)"></a> <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`mplus`</font> <font color=Cyan>(</font>P q<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> joinresults <font color=Cyan>(</font>p st inp<font color=Cyan>)</font> <font color=Cyan>(</font>q st inp<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line95)"></a>+<a name="(line96)"></a><a name="joinresults"></a><font color=Blue>-- joinresults ensures that explicitly raised errors are dominant,</font>+<a name="(line97)"></a><font color=Blue>-- provided no parse has yet been found. The commented out code is</font>+<a name="(line98)"></a><font color=Blue>-- a slightly stricter specification of the real code.</font>+<a name="(line99)"></a>joinresults <font color=Red>::</font> ParseResult s t e a <font color=Red>-></font> ParseResult s t e a <font color=Red>-></font> ParseResult s t e a+<a name="(line100)"></a><font color=Blue>{-+<a name="(line101)"></a>joinresults (Left p) (Left q) = Left p+<a name="(line102)"></a>joinresults (Left p) (Right _) = Left p+<a name="(line103)"></a>joinresults (Right []) (Left q) = Left q+<a name="(line104)"></a>joinresults (Right p) (Left q) = Right p+<a name="(line105)"></a>joinresults (Right p) (Right q) = Right (p++q)+<a name="(line106)"></a>-}</font>+<a name="(line107)"></a>joinresults <font color=Cyan>(</font>Left p<font color=Cyan>)</font> q <font color=Red>=</font> Left p+<a name="(line108)"></a>joinresults <font color=Cyan>(</font>Right []<font color=Cyan>)</font> q <font color=Red>=</font> q+<a name="(line109)"></a>joinresults <font color=Cyan>(</font>Right p<font color=Cyan>)</font> q <font color=Red>=</font> Right <font color=Cyan>(</font>p<font color=Cyan>++</font> <font color=Green><u>case</u></font> q <font color=Green><u>of</u></font> Left <font color=Green><u>_</u></font> <font color=Red>-></font> []+<a name="(line110)"></a> Right r <font color=Red>-></font> r<font color=Cyan>)</font>+<a name="(line111)"></a>+<a name="(line112)"></a>+<a name="(line113)"></a><font color=Blue>--- Primitive parser combinators ---------------------------------------------</font>+<a name="(line114)"></a>+<a name="(line115)"></a><a name="item"></a><font color=Blue>-- | Deliver the first remaining token.</font>+<a name="(line116)"></a>item <font color=Red>::</font> Parser s t e t+<a name="(line117)"></a>item <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>+<a name="(line118)"></a> [] <font color=Red>-></font> Right []+<a name="(line119)"></a> <font color=Cyan>(</font>Left e<font color=Red><b>:</b></font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left e+<a name="(line120)"></a> <font color=Cyan>(</font>Right x<font color=Red><b>:</b></font> xs<font color=Cyan>)</font> <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>x<font color=Cyan>,</font>st<font color=Cyan>,</font>xs<font color=Cyan>)</font><font color=Red>]</font>+<a name="(line121)"></a> <font color=Cyan>)</font>+<a name="(line122)"></a>+<a name="(line123)"></a><a name="eof"></a><font color=Blue>-- | Fail if end of input is not reached</font>+<a name="(line124)"></a>eof <font color=Red>::</font> Show p <font color=Red>=></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String ()+<a name="(line125)"></a>eof <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>+<a name="(line126)"></a> [] <font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>()<font color=Cyan>,</font>st<font color=Cyan>,</font>[]<font color=Cyan>)</font><font color=Red>]</font>+<a name="(line127)"></a> <font color=Cyan>(</font>Left e<font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left e+<a name="(line128)"></a> <font color=Cyan>(</font>Right <font color=Cyan>(</font>p<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left <font color=Cyan>(</font><font color=Magenta>"End of input expected at "</font>+<a name="(line129)"></a> <font color=Cyan>++</font>show p<font color=Cyan>++</font><font color=Magenta>"\n but found text"</font><font color=Cyan>)</font>+<a name="(line130)"></a> <font color=Cyan>)</font>+<a name="(line131)"></a>+<a name="(line132)"></a><font color=Blue>{-+<a name="(line133)"></a>-- | Ensure the value delivered by the parser is evaluated to WHNF.+<a name="(line134)"></a>force :: Parser s t e a -> Parser s t e a+<a name="(line135)"></a>force (P p) = P (\st inp -> let Right xs = p st inp+<a name="(line136)"></a> h = head xs in+<a name="(line137)"></a> h `seq` Right (h: tail xs)+<a name="(line138)"></a> )+<a name="(line139)"></a>-- [[[GK]]] ^^^^^^+<a name="(line140)"></a>-- WHNF = Weak Head Normal Form, meaning that it has no top-level redex.+<a name="(line141)"></a>-- In this case, I think that means that the first element of the list+<a name="(line142)"></a>-- is fully evaluated.+<a name="(line143)"></a>--+<a name="(line144)"></a>-- NOTE: the original form of this function fails if there is no parse+<a name="(line145)"></a>-- result for p st inp (head xs fails if xs is null), so the modified+<a name="(line146)"></a>-- form can assume a Right value only.+<a name="(line147)"></a>--+<a name="(line148)"></a>-- Why is this needed?+<a name="(line149)"></a>-- It's not exported, and the only use of this I see is commented out.+<a name="(line150)"></a>---------------------------------------+<a name="(line151)"></a>-}</font>+<a name="(line152)"></a>+<a name="(line153)"></a>+<a name="(line154)"></a><a name="first"></a><font color=Blue>-- | Deliver the first parse result only, eliminating any backtracking.</font>+<a name="(line155)"></a>first <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e a+<a name="(line156)"></a>first <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font> <font color=Green><u>case</u></font> p st inp <font color=Green><u>of</u></font>+<a name="(line157)"></a> Right <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font> <font color=Red>-></font> Right <font color=Red>[</font>x<font color=Red>]</font>+<a name="(line158)"></a> otherwise <font color=Red>-></font> otherwise+<a name="(line159)"></a> <font color=Cyan>)</font>+<a name="(line160)"></a>+<a name="(line161)"></a><a name="papply"></a><font color=Blue>-- | Apply the parser to some real input, given an initial state value.</font>+<a name="(line162)"></a><font color=Blue>-- If the parser fails, raise 'error' to halt the program.</font>+<a name="(line163)"></a><font color=Blue>-- (This is the original exported behaviour - to allow the caller to</font>+<a name="(line164)"></a><font color=Blue>-- deal with the error differently, see @papply'@.)</font>+<a name="(line165)"></a>papply <font color=Red>::</font> Parser s t String a <font color=Red>-></font> s <font color=Red>-></font> <font color=Red>[</font>Either String t<font color=Red>]</font>+<a name="(line166)"></a> <font color=Red>-></font> <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s<font color=Cyan>,</font><font color=Red>[</font>Either String t<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>+<a name="(line167)"></a>papply <font color=Cyan>(</font>P p<font color=Cyan>)</font> st inp <font color=Red>=</font> either error id <font color=Cyan>(</font>p st inp<font color=Cyan>)</font>+<a name="(line168)"></a>+<a name="(line169)"></a><a name="papply'"></a><font color=Blue>-- | Apply the parser to some real input, given an initial state value.</font>+<a name="(line170)"></a><font color=Blue>-- If the parser fails, return a diagnostic message to the caller.</font>+<a name="(line171)"></a>papply' <font color=Red>::</font> Parser s t e a <font color=Red>-></font> s <font color=Red>-></font> <font color=Red>[</font>Either e t<font color=Red>]</font>+<a name="(line172)"></a> <font color=Red>-></font> Either e <font color=Red>[</font><font color=Cyan>(</font>a<font color=Cyan>,</font>s<font color=Cyan>,</font><font color=Red>[</font>Either e t<font color=Red>]</font><font color=Cyan>)</font><font color=Red>]</font>+<a name="(line173)"></a>papply' <font color=Cyan>(</font>P p<font color=Cyan>)</font> st inp <font color=Red>=</font> p st inp+<a name="(line174)"></a>+<a name="(line175)"></a><font color=Blue>--- Derived combinators ------------------------------------------------------</font>+<a name="(line176)"></a>+<a name="(line177)"></a><a name="+++"></a><font color=Blue>-- | A choice between parsers. Keep only the first success.</font>+<a name="(line178)"></a><font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e a <font color=Red>-></font> Parser s t e a+<a name="(line179)"></a><a name="p"></a>p <font color=Cyan>+++</font> q <font color=Red>=</font> first <font color=Cyan>(</font>p <font color=Cyan>`mplus`</font> q<font color=Cyan>)</font>+<a name="(line180)"></a>+<a name="(line181)"></a><a name="sat"></a><font color=Blue>-- | Deliver the first token if it satisfies a predicate.</font>+<a name="(line182)"></a>sat <font color=Red>::</font> <font color=Cyan>(</font>t <font color=Red>-></font> Bool<font color=Cyan>)</font> <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e t+<a name="(line183)"></a>sat p <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>x<font color=Cyan>)</font> <font color=Red><-</font> item<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> mzero<font color=Cyan>}</font>+<a name="(line184)"></a>+<a name="(line185)"></a><a name="tok"></a><font color=Blue>-- | Deliver the first token if it equals the argument.</font>+<a name="(line186)"></a>tok <font color=Red>::</font> Eq t <font color=Red>=></font> t <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e t+<a name="(line187)"></a>tok t <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>x<font color=Cyan>)</font> <font color=Red><-</font> item<font color=Cyan>;</font> <font color=Green><u>if</u></font> x<font color=Cyan>==</font>t <font color=Green><u>then</u></font> return t <font color=Green><u>else</u></font> mzero<font color=Cyan>}</font>+<a name="(line188)"></a>+<a name="(line189)"></a><a name="nottok"></a><font color=Blue>-- | Deliver the first token if it does not equal the argument.</font>+<a name="(line190)"></a>nottok <font color=Red>::</font> Eq t <font color=Red>=></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e t+<a name="(line191)"></a>nottok ts <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>x<font color=Cyan>)</font> <font color=Red><-</font> item<font color=Cyan>;</font> <font color=Green><u>if</u></font> x <font color=Cyan>`notElem`</font> ts <font color=Green><u>then</u></font> return x+<a name="(line192)"></a> <font color=Green><u>else</u></font> mzero<font color=Cyan>}</font>+<a name="(line193)"></a>+<a name="(line194)"></a><a name="many"></a><font color=Blue>-- | Deliver zero or more values of @a@.</font>+<a name="(line195)"></a>many <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line196)"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>+++</font> return []+<a name="(line197)"></a><font color=Blue>--many p = force (many1 p +++ return [])</font>+<a name="(line198)"></a>+<a name="(line199)"></a><a name="many1"></a><font color=Blue>-- | Deliver one or more values of @a@.</font>+<a name="(line200)"></a>many1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line201)"></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>;</font> xs <font color=Red><-</font> many p<font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line202)"></a>+<a name="(line203)"></a><a name="sepby"></a><font color=Blue>-- | Deliver zero or more values of @a@ separated by @b@'s.</font>+<a name="(line204)"></a>sepby <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e b <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line205)"></a><a name="sepby"></a>p <font color=Cyan>`sepby`</font> sep <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`sepby1`</font> sep<font color=Cyan>)</font> <font color=Cyan>+++</font> return []+<a name="(line206)"></a>+<a name="(line207)"></a><a name="sepby1"></a><font color=Blue>-- | Deliver one or more values of @a@ separated by @b@'s.</font>+<a name="(line208)"></a>sepby1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e b <font color=Red>-></font> Parser s t e <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line209)"></a><a name="sepby1"></a>p <font color=Cyan>`sepby1`</font> sep <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> xs <font color=Red><-</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><font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line210)"></a>+<a name="(line211)"></a><a name="chainl"></a>chainl <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> a+<a name="(line212)"></a> <font color=Red>-></font> Parser s t e a+<a name="(line213)"></a>chainl p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainl1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v+<a name="(line214)"></a>+<a name="(line215)"></a><a name="chainl1"></a>chainl1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e a+<a name="(line216)"></a><a name="chainl1"></a>p <font color=Cyan>`chainl1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>+<a name="(line217)"></a> <font color=Green><u>where</u></font>+<a name="(line218)"></a> rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>f <font color=Red><-</font> op<font color=Cyan>;</font> y <font color=Red><-</font> p<font color=Cyan>;</font> rest <font color=Cyan>(</font>f x y<font color=Cyan>)</font><font color=Cyan>}</font>+<a name="(line219)"></a> <font color=Cyan>+++</font> return x+<a name="(line220)"></a>+<a name="(line221)"></a><a name="chainr"></a>chainr <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> a+<a name="(line222)"></a> <font color=Red>-></font> Parser s t e a+<a name="(line223)"></a>chainr p op v <font color=Red>=</font> <font color=Cyan>(</font>p <font color=Cyan>`chainr1`</font> op<font color=Cyan>)</font> <font color=Cyan>+++</font> return v+<a name="(line224)"></a>+<a name="(line225)"></a><a name="chainr1"></a>chainr1 <font color=Red>::</font> Parser s t e a <font color=Red>-></font> Parser s t e <font color=Cyan>(</font>a<font color=Red>-></font>a<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e a+<a name="(line226)"></a><a name="chainr1"></a>p <font color=Cyan>`chainr1`</font> op <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font>x <font color=Red><-</font> p<font color=Cyan>;</font> rest x<font color=Cyan>}</font>+<a name="(line227)"></a> <font color=Green><u>where</u></font>+<a name="(line228)"></a> rest x <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> f <font color=Red><-</font> op+<a name="(line229)"></a> <font color=Cyan>;</font> y <font color=Red><-</font> p <font color=Cyan>`chainr1`</font> op+<a name="(line230)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>f x y<font color=Cyan>)</font>+<a name="(line231)"></a> <font color=Cyan>}</font>+<a name="(line232)"></a> <font color=Cyan>+++</font> return x+<a name="(line233)"></a>+<a name="(line234)"></a><a name="ops"></a>ops <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>Parser s t e a<font color=Cyan>,</font> b<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser s t e b+<a name="(line235)"></a>ops xs <font color=Red>=</font> foldr1 <font color=Cyan>(</font><font color=Cyan>+++</font><font color=Cyan>)</font> <font color=Red>[</font><font color=Green><u>do</u></font> <font color=Cyan>{</font>p<font color=Cyan>;</font> return op<font color=Cyan>}</font> <font color=Red>|</font> <font color=Cyan>(</font>p<font color=Cyan>,</font>op<font color=Cyan>)</font> <font color=Red><-</font> xs<font color=Red>]</font>+<a name="(line236)"></a>+<a name="(line237)"></a><a name="bracket"></a>bracket <font color=Red>::</font> <font color=Cyan>(</font>Show p<font color=Cyan>,</font>Show t<font color=Cyan>)</font> <font color=Red>=></font>+<a name="(line238)"></a> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e a <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e b <font color=Red>-></font>+<a name="(line239)"></a> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e c <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> e b+<a name="(line240)"></a>bracket open p close <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> open+<a name="(line241)"></a> <font color=Cyan>;</font> x <font color=Red><-</font> p+<a name="(line242)"></a> <font color=Cyan>;</font> close <font color=Blue>-- `elserror` "improperly matched construct";</font>+<a name="(line243)"></a> <font color=Cyan>;</font> return x+<a name="(line244)"></a> <font color=Cyan>}</font>+<a name="(line245)"></a>+<a name="(line246)"></a><a name="toEOF"></a><font color=Blue>-- | Accept a complete parse of the input only, no partial parses.</font>+<a name="(line247)"></a>toEOF <font color=Red>::</font> Show p <font color=Red>=></font>+<a name="(line248)"></a> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a+<a name="(line249)"></a>toEOF 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>;</font> eof<font color=Cyan>;</font> return x <font color=Cyan>}</font>+<a name="(line250)"></a>+<a name="(line251)"></a>+<a name="(line252)"></a><font color=Blue>--- Error handling -----------------------------------------------------------</font>+<a name="(line253)"></a>+<a name="(line254)"></a><a name="parseerror"></a><font color=Blue>-- | Return an error using the supplied diagnostic string, and a token type</font>+<a name="(line255)"></a><font color=Blue>-- which includes position information.</font>+<a name="(line256)"></a>parseerror <font color=Red>::</font> <font color=Cyan>(</font>Show p<font color=Cyan>,</font>Show t<font color=Cyan>)</font> <font color=Red>=></font> String <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a+<a name="(line257)"></a>parseerror err <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp <font color=Red>-></font>+<a name="(line258)"></a> <font color=Green><u>case</u></font> inp <font color=Green><u>of</u></font>+<a name="(line259)"></a> [] <font color=Red>-></font> Left <font color=Magenta>"Parse error: unexpected EOF\n"</font>+<a name="(line260)"></a> <font color=Cyan>(</font>Left e<font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> Left <font color=Cyan>(</font><font color=Magenta>"Lexical error: "</font><font color=Cyan>++</font>e<font color=Cyan>)</font>+<a name="(line261)"></a> <font color=Cyan>(</font>Right <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font><font color=Red><b>:</b></font><font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font>+<a name="(line262)"></a> Left <font color=Cyan>(</font><font color=Magenta>"Parse error: in "</font><font color=Cyan>++</font>show p<font color=Cyan>++</font><font color=Magenta>"\n "</font>+<a name="(line263)"></a> <font color=Cyan>++</font>err<font color=Cyan>++</font><font color=Magenta>"\n "</font><font color=Cyan>++</font><font color=Magenta>"Found "</font><font color=Cyan>++</font>show t<font color=Cyan>)</font>+<a name="(line264)"></a> <font color=Cyan>)</font>+<a name="(line265)"></a>+<a name="(line266)"></a>+<a name="(line267)"></a><a name="elserror"></a><font color=Blue>-- | If the parser fails, generate an error message.</font>+<a name="(line268)"></a>elserror <font color=Red>::</font> <font color=Cyan>(</font>Show p<font color=Cyan>,</font>Show t<font color=Cyan>)</font> <font color=Red>=></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a <font color=Red>-></font> String+<a name="(line269)"></a> <font color=Red>-></font> Parser s <font color=Cyan>(</font>p<font color=Cyan>,</font>t<font color=Cyan>)</font> String a+<a name="(line270)"></a><a name="elserror"></a>p <font color=Cyan>`elserror`</font> s <font color=Red>=</font> p <font color=Cyan>+++</font> parseerror s+<a name="(line271)"></a>+<a name="(line272)"></a><font color=Blue>--- State handling -----------------------------------------------------------</font>+<a name="(line273)"></a>+<a name="(line274)"></a><a name="stupd"></a><font color=Blue>-- | Update the internal state.</font>+<a name="(line275)"></a>stupd <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e ()+<a name="(line276)"></a>stupd f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> <font color=Blue>{-let newst = f st in newst `seq`-}</font>+<a name="(line277)"></a> Right <font color=Red>[</font><font color=Cyan>(</font>()<font color=Cyan>,</font> f st<font color=Cyan>,</font> inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line278)"></a>+<a name="(line279)"></a><a name="stquery"></a><font color=Blue>-- | Query the internal state.</font>+<a name="(line280)"></a>stquery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t e a+<a name="(line281)"></a>stquery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>f st<font color=Cyan>,</font> st<font color=Cyan>,</font> inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line282)"></a>+<a name="(line283)"></a><a name="stget"></a><font color=Blue>-- | Deliver the entire internal state.</font>+<a name="(line284)"></a>stget <font color=Red>::</font> Parser s t e s+<a name="(line285)"></a>stget <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>st<font color=Cyan>,</font> st<font color=Cyan>,</font> inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line286)"></a>+<a name="(line287)"></a>+<a name="(line288)"></a><font color=Blue>--- Push some tokens back onto the input stream and reparse ------------------</font>+<a name="(line289)"></a>+<a name="(line290)"></a><a name="reparse"></a><font color=Blue>-- | This is useful for recursively expanding macros. When the</font>+<a name="(line291)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line292)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line293)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line294)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>Either e t<font color=Red>]</font> <font color=Red>-></font> Parser s t e ()+<a name="(line295)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>st inp<font color=Red>-></font> Right <font color=Red>[</font><font color=Cyan>(</font>()<font color=Cyan>,</font> st<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Red>]</font><font color=Cyan>)</font>+<a name="(line296)"></a>+<a name="(line297)"></a><font color=Blue>------------------------------------------------------------------------------</font> </pre>+</html>
docs/haddock/src/Text/ParserCombinators/Poly.html view
@@ -1,239 +1,251 @@-<pre><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly- <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>- Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad</font>- <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser t a -> [t] -> (Either String a, [t])</font>- <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser t a</font>- <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser t a -> Parser t a</font>-- <font color=Blue>-- * Combinators:</font>- <font color=Blue>-- ** Primitives</font>- <font color=Cyan>,</font> next <font color=Blue>-- :: Parser t t</font>- <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser t t</font>- <font color=Cyan>,</font> apply <font color=Blue>-- :: Parser t (a->b) -> Parser t a -> Parser t b</font>- <font color=Cyan>,</font> discard <font color=Blue>-- :: Parser t a -> Parser t b -> Parser t a</font>- <font color=Blue>-- ** Error-handling</font>- <font color=Cyan>,</font> adjustErr <font color=Blue>-- :: Parser t a -> (String->String) -> Parser t a</font>- <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: Parser t a -> (String->String) -> Parser t a</font>- <font color=Cyan>,</font> indent <font color=Blue>-- :: Int -> String -> String</font>- <font color=Blue>-- ** Choices</font>- <font color=Cyan>,</font> onFail <font color=Blue>-- :: Parser t a -> Parser t a -> Parser t a</font>- <font color=Cyan>,</font> oneOf <font color=Blue>-- :: Show t => [Parser t a] -> Parser t a</font>- <font color=Cyan>,</font> oneOf' <font color=Blue>-- :: [(String,Parser t a)] -> Parser t a</font>- <font color=Cyan>,</font> optional <font color=Blue>-- :: Parser t a -> Parser t (Maybe a)</font>- <font color=Blue>-- ** Sequences</font>- <font color=Cyan>,</font> many <font color=Blue>-- :: Parser t a -> Parser t [a]</font>- <font color=Cyan>,</font> many1 <font color=Blue>-- :: Parser t a -> Parser t [a]</font>- <font color=Cyan>,</font> sepBy <font color=Blue>-- :: Parser t a -> Parser t sep -> Parser t [a]</font>- <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: Parser t a -> Parser t sep -> Parser t [a]</font>- <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: Parser t bra -> Parser t sep -> Parser t ket</font>- <font color=Blue>-- -> Parser t a -> Parser t [a]</font>- <font color=Cyan>,</font> bracket <font color=Blue>-- :: Parser t bra -> Parser t ket -> Parser t a</font>- <font color=Blue>-- -> Parser t a</font>- <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser t a -> Parser t z -> Parser t [a]</font>- <font color=Blue>-- ** re-parsing</font>- <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser t ()</font>- <font color=Cyan>)</font> <font color=Green><u>where</u></font>---<font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>-<font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>-<font color=Blue>-- String input. (If you require a running state, use module PolyState</font>-<font color=Blue>-- instead)</font>-<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>EitherE String a<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- A return type like Either, that distinguishes not only between</font>-<font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>-<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--<font color=Blue>-- | Apply a parser to an input token sequence.</font>-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>Either String a<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>-<a name="runParser"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font>- <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 <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>m<font color=Cyan>)</font><font color=Red>-></font>Left m<font color=Cyan>;</font> Right m<font color=Red>-></font>Right m<font color=Cyan>}</font><font color=Cyan>,</font> ts<font color=Cyan>)</font> <font color=Cyan>)</font>- <font color=Cyan>.</font> p--<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>- 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>- <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>- <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>-<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>- 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>- <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>- <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>- <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>- 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 <font color=Cyan>(</font>False<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | When a simple fail is not strong enough, use failBad for emphasis.</font>-<font color=Blue>-- An emphasised (severe) error can propagate out through choice operators.</font>-failBad <font color=Red>::</font> String <font color=Red>-></font> Parser t a-<a name="failBad"></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>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>-<font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>-<font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>-<font color=Blue>-- they fail hard.</font>-commit <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t a-<a name="commit"></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>- <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>---<font color=Blue>-- Combinators</font>--<font color=Blue>-- | One token</font>-next <font color=Red>::</font> Parser t t-<a name="next"></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>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- <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>--<font color=Blue>-- | One token satifying a predicate</font>-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="satisfy"></a>satisfy p <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> x <font color=Red><-</font> next- <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>- <font color=Cyan>}</font>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>-<font color=Blue>-- | Apply a parsed function to a parsed value</font>-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="apply"></a>pf <font color=Cyan>`apply`</font> px <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> f <font color=Red><-</font> pf<font color=Cyan>;</font> x <font color=Red><-</font> px<font color=Cyan>;</font> return <font color=Cyan>(</font>f x<font color=Cyan>)</font> <font color=Cyan>}</font>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>-<font color=Blue>-- | @x `discard` y@ parses both x and y, but discards the result of y</font>-discard <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t b <font color=Red>-></font> Parser t 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> <font color=Green><u>_</u></font> <font color=Red><-</font> py<font color=Cyan>;</font> return x <font color=Cyan>}</font>--<font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>-<font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>-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="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>- <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>-<font color=Blue>-- severity of the error.</font>-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="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>--<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>-<font color=Blue>-- | @p `onFail` q@ means parse p unless p fails in which case parse q instead.</font>-<font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>-<font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>-<font color=Blue>-- message from that defined in p to something different.)</font>-<font color=Blue>-- However, a *severe* failure in p cannot be ignored.</font>-onFail <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t 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>- r<font color=Red>@</font><font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r- <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- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>-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="oneOf"></a>oneOf <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> n <font color=Red><-</font> next- <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>- <font color=Cyan>}</font>-<font color=Blue>--oneOf :: Show t => [Parser t a] -> Parser t a</font>-<font color=Blue>--oneOf [] = do { n <- next</font>-<font color=Blue>-- ; fail ("failed to parse any of the possible choices"</font>-<font color=Blue>-- ++"\n next token is "++show n)</font>-<font color=Blue>-- }</font>-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--<font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>-<font color=Blue>-- report only the severe errors, and if none of those, then report</font>-<font color=Blue>-- all the soft errors.</font>-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="oneOf'"></a>oneOf' <font color=Red>=</font> accum <font color=Red>[</font><font color=Red>]</font>- <font color=Green><u>where</u></font> accum errs <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font>- <font color=Green><u>case</u></font> filter isBad errs <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>- <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>- <font color=Red>[</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> failBad e- es <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>- <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>- 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>- 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>- <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- <font color=Green><u>in</u></font> p ts- right <font color=Red>-></font> right <font color=Cyan>)</font>- showErr <font color=Cyan>(</font>name<font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>err<font color=Cyan>)</font><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- isBad <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> b--<font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>-indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String-<a name="indent"></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--<font color=Blue>-- | 'optional' indicates whether the parser succeeded through the Maybe type.</font>-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="optional"></a>optional p <font color=Red>=</font> fmap Just p <font color=Cyan>`onFail`</font> return Nothing--<font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>-<font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>-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="many"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items.</font>-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="many1"></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>- <font color=Cyan>;</font> xs <font color=Red><-</font> many p- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>-<font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n\t"++)</font>--<font color=Blue>-- | Parse a list of items separated by discarded junk.</font>-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="sepBy"></a>sepBy p sep <font color=Red>=</font> <font color=Green><u>do</u></font> sepBy1 p sep <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>-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="sepBy1"></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- <font color=Cyan>;</font> xs <font color=Red><-</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>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>- <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>- -<font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>-<font color=Blue>-- items.</font>-bracketSep <font color=Red>::</font> Parser t bra <font color=Red>-></font> Parser t sep <font color=Red>-></font> Parser t ket- <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>-<a name="bracketSep"></a>bracketSep open sep close p <font color=Red>=</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> open<font color=Cyan>;</font> close<font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>- <font color=Cyan>`onFail`</font>- <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>- <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>- <font color=Cyan>;</font> xs <font color=Red><-</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>- <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> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>--<font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>-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="bracket"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>- <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>- <font color=Cyan>;</font> x <font color=Red><-</font> p- <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> return x- <font color=Cyan>}</font>--<font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>-<font color=Blue>-- terminated by a t. Any parse failures could be due either to</font>-<font color=Blue>-- a badly-formed terminator or a badly-formed element, so raise</font>-<font color=Blue>-- both possible errors.</font>-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="manyFinally"></a>manyFinally p t <font color=Red>=</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> xs <font color=Red><-</font> many p- <font color=Cyan>;</font> oneOf' <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"sequence terminator"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> t<font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Cyan>)</font> <font color=Cyan>}</font> <font color=Cyan>)</font>- <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"item in a sequence"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> p<font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Cyan>)</font> <font color=Cyan>}</font> <font color=Cyan>)</font>- <font color=Red>]</font>- <font color=Cyan>;</font> return xs- <font color=Cyan>}</font>--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>-<font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>-<font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>-<font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>-<font color=Blue>-- lexed expansion back down into the parser.</font>-reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser t <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="reparse"></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><font color=Cyan>)</font><font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>+<!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+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser t a -> [t] -> (Either String a, [t])</font>+<a name="(line5)"></a> <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser t a</font>+<a name="(line6)"></a> <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser t a -> Parser t a</font>+<a name="(line7)"></a>+<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>+<a name="(line39)"></a><a name="Parser"></a><font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line40)"></a><a name="Parser"></a><font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>+<a name="(line41)"></a><a name="Parser"></a><font color=Blue>-- String input. (If you require a running state, use module PolyState</font>+<a name="(line42)"></a><a name="Parser"></a><font color=Blue>-- instead)</font>+<a name="(line43)"></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>EitherE 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="(line44)"></a>+<a name="(line45)"></a><a name="EitherE"></a><font color=Blue>-- A return type like Either, that distinguishes not only between</font>+<a name="(line46)"></a><a name="EitherE"></a><font color=Blue>-- right and wrong answers, but also has gradations of wrongness.</font>+<a name="(line47)"></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="(line48)"></a>+<a name="(line49)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence.</font>+<a name="(line50)"></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>Either String a<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line51)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font>+<a name="(line52)"></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 <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>m<font color=Cyan>)</font><font color=Red>-></font>Left m<font color=Cyan>;</font> Right m<font color=Red>-></font>Right m<font color=Cyan>}</font><font color=Cyan>,</font> ts<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line53)"></a> <font color=Cyan>.</font> p+<a name="(line54)"></a>+<a name="(line55)"></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="(line56)"></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="(line57)"></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="(line58)"></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="(line59)"></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="(line60)"></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="(line61)"></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="(line62)"></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="(line63)"></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="(line64)"></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 <font color=Cyan>(</font>False<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line65)"></a>+<a name="(line66)"></a><a name="failBad"></a><font color=Blue>-- | When a simple fail is not strong enough, use failBad for emphasis.</font>+<a name="(line67)"></a><font color=Blue>-- An emphasised (severe) error can propagate out through choice operators.</font>+<a name="(line68)"></a>failBad <font color=Red>::</font> String <font color=Red>-></font> Parser t a+<a name="(line69)"></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>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line70)"></a>+<a name="(line71)"></a><a name="commit"></a><font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>+<a name="(line72)"></a><font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>+<a name="(line73)"></a><font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>+<a name="(line74)"></a><font color=Blue>-- they fail hard.</font>+<a name="(line75)"></a>commit <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t a+<a name="(line76)"></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="(line77)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line78)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line79)"></a>+<a name="(line80)"></a>+<a name="(line81)"></a><font color=Blue>-- Combinators</font>+<a name="(line82)"></a>+<a name="(line83)"></a><a name="next"></a><font color=Blue>-- | One token</font>+<a name="(line84)"></a>next <font color=Red>::</font> Parser t t+<a name="(line85)"></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="(line86)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>)</font><font color=Cyan>,</font> []<font color=Cyan>)</font>+<a name="(line87)"></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="(line88)"></a>+<a name="(line89)"></a><a name="satisfy"></a><font color=Blue>-- | One token satifying a predicate</font>+<a name="(line90)"></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="(line91)"></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="(line92)"></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="(line93)"></a> <font color=Cyan>}</font>+<a name="(line94)"></a>+<a name="(line95)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>+<a name="(line96)"></a><a name="apply"></a><font color=Blue>-- | Apply a parsed function to a parsed value</font>+<a name="(line97)"></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="(line98)"></a><a name="apply"></a>pf <font color=Cyan>`apply`</font> px <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> f <font color=Red><-</font> pf<font color=Cyan>;</font> x <font color=Red><-</font> px<font color=Cyan>;</font> return <font color=Cyan>(</font>f x<font color=Cyan>)</font> <font color=Cyan>}</font>+<a name="(line99)"></a>+<a name="(line100)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>+<a name="(line101)"></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="(line102)"></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="(line103)"></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> <font color=Green><u>_</u></font> <font color=Red><-</font> py<font color=Cyan>;</font> return x <font color=Cyan>}</font>+<a name="(line104)"></a>+<a name="(line105)"></a><a name="adjustErr"></a><font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>+<a name="(line106)"></a><font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>+<a name="(line107)"></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="(line108)"></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="(line109)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line110)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line111)"></a>+<a name="(line112)"></a><a name="adjustErrBad"></a><font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>+<a name="(line113)"></a><font color=Blue>-- severity of the error.</font>+<a name="(line114)"></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="(line115)"></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="(line116)"></a>+<a name="(line117)"></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="(line118)"></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="(line119)"></a><font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>+<a name="(line120)"></a><font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>+<a name="(line121)"></a><font color=Blue>-- message from that defined in p to something different.)</font>+<a name="(line122)"></a><font color=Blue>-- However, a *severe* failure in p cannot be ignored.</font>+<a name="(line123)"></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="(line124)"></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="(line125)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line126)"></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="(line127)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line128)"></a>+<a name="(line129)"></a><a name="oneOf"></a><font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>+<a name="(line130)"></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="(line131)"></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="(line132)"></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="(line133)"></a> <font color=Cyan>}</font>+<a name="(line134)"></a><font color=Blue>--oneOf :: Show t => [Parser t a] -> Parser t a</font>+<a name="(line135)"></a><font color=Blue>--oneOf [] = do { n <- next</font>+<a name="(line136)"></a><font color=Blue>-- ; fail ("failed to parse any of the possible choices"</font>+<a name="(line137)"></a><font color=Blue>-- ++"\n next token is "++show n)</font>+<a name="(line138)"></a><font color=Blue>-- }</font>+<a name="(line139)"></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="(line140)"></a>+<a name="(line141)"></a><a name="oneOf'"></a><font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>+<a name="(line142)"></a><font color=Blue>-- report only the severe errors, and if none of those, then report</font>+<a name="(line143)"></a><font color=Blue>-- all the soft errors.</font>+<a name="(line144)"></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="(line145)"></a>oneOf' <font color=Red>=</font> accum []+<a name="(line146)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line147)"></a> <font color=Green><u>case</u></font> filter isBad errs <font color=Green><u>of</u></font>+<a name="(line148)"></a> [] <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line149)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line150)"></a> <font color=Red>[</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> failBad e+<a name="(line151)"></a> es <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>+<a name="(line152)"></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="(line153)"></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="(line154)"></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="(line155)"></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="(line156)"></a> <font color=Green><u>in</u></font> p ts+<a name="(line157)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line158)"></a> showErr <font color=Cyan>(</font>name<font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>err<font color=Cyan>)</font><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="(line159)"></a> isBad <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> b+<a name="(line160)"></a>+<a name="(line161)"></a><a name="indent"></a><font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>+<a name="(line162)"></a>indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String+<a name="(line163)"></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="(line164)"></a>+<a name="(line165)"></a><a name="optional"></a><font color=Blue>-- | 'optional' indicates whether the parser succeeded through the Maybe type.</font>+<a name="(line166)"></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="(line167)"></a>optional p <font color=Red>=</font> fmap Just p <font color=Cyan>`onFail`</font> return Nothing+<a name="(line168)"></a>+<a name="(line169)"></a><a name="exactly"></a><font color=Blue>-- | 'exactly n p' parses a precise number of items, n, using the parser</font>+<a name="(line170)"></a><font color=Blue>-- p, in sequence.</font>+<a name="(line171)"></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="(line172)"></a>exactly <font color=Magenta>0</font> p <font color=Red>=</font> return []+<a name="(line173)"></a>exactly n p <font color=Red>=</font> <font color=Green><u>do</u></font> x <font color=Red><-</font> p+<a name="(line174)"></a> xs <font color=Red><-</font> exactly <font color=Cyan>(</font>n<font color=Blue>-</font><font color=Magenta>1</font><font color=Cyan>)</font> p+<a name="(line175)"></a> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line176)"></a>+<a name="(line177)"></a><a name="many"></a><font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>+<a name="(line178)"></a><font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>+<a name="(line179)"></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="(line180)"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return []+<a name="(line181)"></a>+<a name="(line182)"></a><a name="many1"></a><font color=Blue>-- | Parse a non-empty list of items.</font>+<a name="(line183)"></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="(line184)"></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="(line185)"></a> <font color=Cyan>;</font> xs <font color=Red><-</font> many p+<a name="(line186)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line187)"></a> <font color=Cyan>}</font>+<a name="(line188)"></a><font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n\t"++)</font>+<a name="(line189)"></a>+<a name="(line190)"></a><a name="sepBy"></a><font color=Blue>-- | Parse a list of items separated by discarded junk.</font>+<a name="(line191)"></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="(line192)"></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="(line193)"></a>+<a name="(line194)"></a><a name="sepBy1"></a><font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>+<a name="(line195)"></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="(line196)"></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="(line197)"></a> <font color=Cyan>;</font> xs <font color=Red><-</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="(line198)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line199)"></a> <font color=Cyan>}</font>+<a name="(line200)"></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="(line201)"></a> +<a name="(line202)"></a><a name="bracketSep"></a><font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>+<a name="(line203)"></a><font color=Blue>-- items.</font>+<a name="(line204)"></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="(line205)"></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="(line206)"></a>bracketSep open sep close p <font color=Red>=</font>+<a name="(line207)"></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="(line208)"></a> <font color=Cyan>`onFail`</font>+<a name="(line209)"></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="(line210)"></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="(line211)"></a> <font color=Cyan>;</font> xs <font color=Red><-</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="(line212)"></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>+<a name="(line213)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line214)"></a> <font color=Cyan>}</font>+<a name="(line215)"></a>+<a name="(line216)"></a><a name="bracket"></a><font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>+<a name="(line217)"></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="(line218)"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>+<a name="(line219)"></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="(line220)"></a> <font color=Cyan>;</font> x <font color=Red><-</font> p+<a name="(line221)"></a> <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>+<a name="(line222)"></a> <font color=Cyan>;</font> return x+<a name="(line223)"></a> <font color=Cyan>}</font>+<a name="(line224)"></a>+<a name="(line225)"></a><a name="manyFinally"></a><font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>+<a name="(line226)"></a><font color=Blue>-- terminated by a t. Any parse failures could be due either to</font>+<a name="(line227)"></a><font color=Blue>-- a badly-formed terminator or a badly-formed element, so raise</font>+<a name="(line228)"></a><font color=Blue>-- both possible errors.</font>+<a name="(line229)"></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="(line230)"></a>manyFinally p t <font color=Red>=</font>+<a name="(line231)"></a> <font color=Green><u>do</u></font> <font color=Cyan>{</font> xs <font color=Red><-</font> many p+<a name="(line232)"></a> <font color=Cyan>;</font> oneOf' <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"sequence terminator"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> t<font color=Cyan>;</font> return () <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line233)"></a> <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"item in a sequence"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> p<font color=Cyan>;</font> return () <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line234)"></a> <font color=Red>]</font>+<a name="(line235)"></a> <font color=Cyan>;</font> return xs+<a name="(line236)"></a> <font color=Cyan>}</font>+<a name="(line237)"></a>+<a name="(line238)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line239)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line240)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line241)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line242)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line243)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line244)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser t ()+<a name="(line245)"></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="(line246)"></a>+<a name="(line247)"></a><font color=Blue>------------------------------------------------------------------------</font> </pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/Base.html view
@@ -0,0 +1,194 @@+<!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>Base+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The PolyParse class</font>+<a name="(line3)"></a> PolyParse<font color=Cyan>(</font><font color=Red>..</font><font color=Cyan>)</font> <font color=Blue>-- class of all monadic two-level-error parsers</font>+<a name="(line4)"></a>+<a name="(line5)"></a> <font color=Blue>-- * Combinators general to all parser types.</font>+<a name="(line6)"></a> <font color=Blue>-- ** Simple combinators</font>+<a name="(line7)"></a> <font color=Cyan>,</font> discard <font color=Blue>-- :: PolyParse p => p a -> p b -> p a</font>+<a name="(line8)"></a> <font color=Blue>-- ** Error-handling</font>+<a name="(line9)"></a> <font color=Cyan>,</font> failBad <font color=Blue>-- :: PolyParse p => String -> p a</font>+<a name="(line10)"></a> <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: PolyParse p => p a -> (String->String) -> p a</font>+<a name="(line11)"></a> <font color=Cyan>,</font> indent <font color=Blue>-- :: Int -> String -> String</font>+<a name="(line12)"></a> <font color=Blue>-- ** Choices</font>+<a name="(line13)"></a> <font color=Cyan>,</font> oneOf <font color=Blue>-- :: PolyParse p => [p a] -> p a</font>+<a name="(line14)"></a> <font color=Cyan>,</font> optional <font color=Blue>-- :: PolyParse p => p a -> p (Maybe a)</font>+<a name="(line15)"></a> <font color=Blue>-- ** Sequences</font>+<a name="(line16)"></a> <font color=Cyan>,</font> exactly <font color=Blue>-- :: PolyParse p => Int -> p a -> p [a]</font>+<a name="(line17)"></a> <font color=Cyan>,</font> many <font color=Blue>-- :: PolyParse p => p a -> p [a]</font>+<a name="(line18)"></a> <font color=Cyan>,</font> many1 <font color=Blue>-- :: PolyParse p => p a -> p [a]</font>+<a name="(line19)"></a> <font color=Cyan>,</font> sepBy <font color=Blue>-- :: PolyParse p => p a -> p sep -> p [a]</font>+<a name="(line20)"></a> <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: PolyParse p => p a -> p sep -> p [a]</font>+<a name="(line21)"></a> <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: PolyParse p => p bra -> p sep -> p ket -> p a -> p [a]</font>+<a name="(line22)"></a> <font color=Cyan>,</font> bracket <font color=Blue>-- :: PolyParse p => p bra -> p ket -> p a -> p a</font>+<a name="(line23)"></a> <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: PolyParse p => p a -> p z -> p [a]</font>+<a name="(line24)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line25)"></a>+<a name="(line26)"></a><a name="PolyParse"></a><font color=Blue>-- | The @PolyParse@ class is an abstraction over all the current</font>+<a name="(line27)"></a><a name="PolyParse"></a><font color=Blue>-- concrete representations of monadic parser combinators in this</font>+<a name="(line28)"></a><a name="PolyParse"></a><font color=Blue>-- package. The common feature is two-level error-handling.</font>+<a name="(line29)"></a><a name="PolyParse"></a><font color=Blue>-- Some primitives must be implemented specific to each parser type</font>+<a name="(line30)"></a><a name="PolyParse"></a><font color=Blue>-- (e.g. depending on whether the parser has a running state, or</font>+<a name="(line31)"></a><a name="PolyParse"></a><font color=Blue>-- whether it is lazy). But given those primitives, large numbers of</font>+<a name="(line32)"></a><a name="PolyParse"></a><font color=Blue>-- combinators do not depend any further on the internal structure of</font>+<a name="(line33)"></a><a name="PolyParse"></a><font color=Blue>-- the particular parser.</font>+<a name="(line34)"></a><a name="PolyParse"></a><font color=Blue>--</font>+<a name="(line35)"></a><a name="PolyParse"></a><font color=Blue>-- There are two additional basic combinators that we expect to be implemented</font>+<a name="(line36)"></a><a name="PolyParse"></a><font color=Blue>-- afresh for every concrete type, but which (for technical reasons)</font>+<a name="(line37)"></a><a name="PolyParse"></a><font color=Blue>-- cannot be class methods. They are @next@ and @satisfy@.</font>+<a name="(line38)"></a><a name="PolyParse"></a><font color=Green><u>class</u></font> <font color=Cyan>(</font>Functor p<font color=Cyan>,</font> Monad p<font color=Cyan>)</font> <font color=Red>=></font> PolyParse p <font color=Green><u>where</u></font>+<a name="(line39)"></a> <font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>+<a name="(line40)"></a> <font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>+<a name="(line41)"></a> <font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>+<a name="(line42)"></a> <font color=Blue>-- they fail hard.</font>+<a name="(line43)"></a> commit <font color=Red>::</font> p a <font color=Red>-></font> p a+<a name="(line44)"></a> <font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>+<a name="(line45)"></a> <font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>+<a name="(line46)"></a> adjustErr <font color=Red>::</font> p a <font color=Red>-></font> <font color=Cyan>(</font>String <font color=Red>-></font> String<font color=Cyan>)</font> <font color=Red>-></font> p a+<a name="(line47)"></a> <font color=Blue>-- | @p `onFail` q@ means parse p, unless p fails, in which case</font>+<a name="(line48)"></a> <font color=Blue>-- parse q instead.</font>+<a name="(line49)"></a> <font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>+<a name="(line50)"></a> <font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>+<a name="(line51)"></a> <font color=Blue>-- message from that defined in p to something different.)</font>+<a name="(line52)"></a> <font color=Blue>-- However, a severe failure in p cannot be ignored.</font>+<a name="(line53)"></a> onFail <font color=Red>::</font> p a <font color=Red>-></font> p a <font color=Red>-></font> p a+<a name="(line54)"></a> <font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>+<a name="(line55)"></a> <font color=Blue>-- report only the severe errors, and if none of those, then report</font>+<a name="(line56)"></a> <font color=Blue>-- all the soft errors.</font>+<a name="(line57)"></a> oneOf' <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font> p a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> p a+<a name="(line58)"></a> <font color=Blue>-- | Apply a parsed function to a parsed value.</font>+<a name="(line59)"></a> <font color=Blue>-- Rather like ordinary function application lifted into parsers.</font>+<a name="(line60)"></a> apply <font color=Red>::</font> p <font color=Cyan>(</font>a<font color=Red>-></font>b<font color=Cyan>)</font> <font color=Red>-></font> p a <font color=Red>-></font> p b+<a name="(line61)"></a> pf <font color=Cyan>`apply`</font> px <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> f <font color=Red><-</font> pf<font color=Cyan>;</font> x <font color=Red><-</font> px<font color=Cyan>;</font> return <font color=Cyan>(</font>f x<font color=Cyan>)</font> <font color=Cyan>}</font>+<a name="(line62)"></a> <font color=Blue>-- note: the Poly.Lazy variants override this defn with a lazier one.</font>+<a name="(line63)"></a>+<a name="(line64)"></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="(line65)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>+<a name="(line66)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>+<a name="(line67)"></a>+<a name="(line68)"></a><font color=Blue>{-+<a name="(line69)"></a>-- Combinators we expect most concrete parser types to implement.+<a name="(line70)"></a>-- For technical reasons, they cannot be class members.+<a name="(line71)"></a>+<a name="(line72)"></a>-- | Yield the next token+<a name="(line73)"></a>next :: PolyParse p => p t+<a name="(line74)"></a> -- where t is constrained to be the input token type+<a name="(line75)"></a>+<a name="(line76)"></a>-- | One token satisfying a predicate.+<a name="(line77)"></a>satisfy :: PolyParse p => (t->Bool) -> p t t+<a name="(line78)"></a>satisfy p = do{ x <- next+<a name="(line79)"></a> ; if p x then return x else fail "Parse.satisfy: failed"+<a name="(line80)"></a> }+<a name="(line81)"></a> -- note: must be re-defined for each implementation because+<a name="(line82)"></a> -- its type cannot be expressed otherwise.+<a name="(line83)"></a>-}</font>+<a name="(line84)"></a>+<a name="(line85)"></a><a name="failBad"></a><font color=Blue>-- | When a simple fail is not strong enough, use failBad for emphasis.</font>+<a name="(line86)"></a><font color=Blue>-- An emphasised (severe) error cannot be overridden by choice</font>+<a name="(line87)"></a><font color=Blue>-- operators.</font>+<a name="(line88)"></a>failBad <font color=Red>::</font> PolyParse p <font color=Red>=></font> String <font color=Red>-></font> p a+<a name="(line89)"></a>failBad e <font color=Red>=</font> commit <font color=Cyan>(</font>fail e<font color=Cyan>)</font>+<a name="(line90)"></a>+<a name="(line91)"></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="(line92)"></a><font color=Blue>-- Rather like @const@ lifted into parsers.</font>+<a name="(line93)"></a>discard <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> p b <font color=Red>-></font> p a+<a name="(line94)"></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>const x<font color=Cyan>)</font> <font color=Cyan>`apply`</font> py<font color=Cyan>;</font> <font color=Cyan>}</font>+<a name="(line95)"></a>+<a name="(line96)"></a><a name="adjustErrBad"></a><font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>+<a name="(line97)"></a><font color=Blue>-- severity of the error.</font>+<a name="(line98)"></a>adjustErrBad <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> <font color=Cyan>(</font>String<font color=Red>-></font>String<font color=Cyan>)</font> <font color=Red>-></font> p a+<a name="(line99)"></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="(line100)"></a>+<a name="(line101)"></a><a name="oneOf"></a><font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>+<a name="(line102)"></a>oneOf <font color=Red>::</font> PolyParse p <font color=Red>=></font> <font color=Red>[</font>p a<font color=Red>]</font> <font color=Red>-></font> p a+<a name="(line103)"></a>oneOf [] <font color=Red>=</font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices"</font><font color=Cyan>)</font>+<a name="(line104)"></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="(line105)"></a><font color=Blue>--oneOf :: Show t => [Parser t a] -> Parser t a</font>+<a name="(line106)"></a><font color=Blue>--oneOf [] = do { n <- next</font>+<a name="(line107)"></a><font color=Blue>-- ; fail ("failed to parse any of the possible choices"</font>+<a name="(line108)"></a><font color=Blue>-- ++"\n next token is "++show n)</font>+<a name="(line109)"></a><font color=Blue>-- }</font>+<a name="(line110)"></a><font color=Blue>--oneOf (p:ps) = p `onFail` oneOf ps</font>+<a name="(line111)"></a>+<a name="(line112)"></a><a name="indent"></a><font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>+<a name="(line113)"></a>indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String+<a name="(line114)"></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="(line115)"></a>+<a name="(line116)"></a><a name="optional"></a><font color=Blue>-- | 'optional' indicates whether the parser succeeded through the Maybe type.</font>+<a name="(line117)"></a>optional <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> p <font color=Cyan>(</font>Maybe a<font color=Cyan>)</font>+<a name="(line118)"></a>optional p <font color=Red>=</font> fmap Just p <font color=Cyan>`onFail`</font> return Nothing+<a name="(line119)"></a>+<a name="(line120)"></a><a name="exactly"></a><font color=Blue>-- | 'exactly n p' parses precisely n items, using the parser p, in sequence.</font>+<a name="(line121)"></a>exactly <font color=Red>::</font> PolyParse p <font color=Red>=></font> Int <font color=Red>-></font> p a <font color=Red>-></font> p <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line122)"></a>exactly <font color=Magenta>0</font> p <font color=Red>=</font> return []+<a name="(line123)"></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> <font color=Cyan>(</font>p <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Cyan>(</font><font color=Magenta>"When expecting exactly "</font>+<a name="(line124)"></a> <font color=Cyan>++</font>show n<font color=Cyan>++</font><font color=Magenta>" more items"</font><font color=Cyan>)</font><font color=Cyan>++</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line125)"></a> <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="(line126)"></a>+<a name="(line127)"></a><a name="many"></a><font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>+<a name="(line128)"></a><font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>+<a name="(line129)"></a>many <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> p <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line130)"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return []+<a name="(line131)"></a>+<a name="(line132)"></a><a name="many1"></a><font color=Blue>-- | Parse a non-empty list of items.</font>+<a name="(line133)"></a>many1 <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> p <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line134)"></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="(line135)"></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="(line136)"></a> <font color=Cyan>}</font>+<a name="(line137)"></a><font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n\t"++)</font>+<a name="(line138)"></a>+<a name="(line139)"></a><a name="sepBy"></a><font color=Blue>-- | Parse a list of items separated by discarded junk.</font>+<a name="(line140)"></a>sepBy <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> p sep <font color=Red>-></font> p <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line141)"></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="(line142)"></a>+<a name="(line143)"></a><a name="sepBy1"></a><font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>+<a name="(line144)"></a>sepBy1 <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> p sep <font color=Red>-></font> p <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line145)"></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="(line146)"></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="(line147)"></a> <font color=Cyan>}</font>+<a name="(line148)"></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="(line149)"></a> +<a name="(line150)"></a><a name="bracketSep"></a><font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>+<a name="(line151)"></a><font color=Blue>-- items.</font>+<a name="(line152)"></a>bracketSep <font color=Red>::</font> PolyParse p <font color=Red>=></font> p bra <font color=Red>-></font> p sep <font color=Red>-></font> p ket <font color=Red>-></font> p a <font color=Red>-></font> p <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line153)"></a>bracketSep open sep close p <font color=Red>=</font>+<a name="(line154)"></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="(line155)"></a> <font color=Cyan>`onFail`</font>+<a name="(line156)"></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="(line157)"></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="(line158)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font><font color=Cyan>)</font>+<a name="(line159)"></a> <font color=Cyan>`apply`</font> 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="(line160)"></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="(line161)"></a> <font color=Cyan>}</font>+<a name="(line162)"></a>+<a name="(line163)"></a><a name="bracket"></a><font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>+<a name="(line164)"></a>bracket <font color=Red>::</font> PolyParse p <font color=Red>=></font> p bra <font color=Red>-></font> p ket <font color=Red>-></font> p a <font color=Red>-></font> p a+<a name="(line165)"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>+<a name="(line166)"></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="(line167)"></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="(line168)"></a> <font color=Cyan>}</font>+<a name="(line169)"></a>+<a name="(line170)"></a><a name="manyFinally"></a><font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>+<a name="(line171)"></a><font color=Blue>-- terminated by a t. The final t is discarded. Any parse failures</font>+<a name="(line172)"></a><font color=Blue>-- could be due either to a badly-formed terminator or a badly-formed</font>+<a name="(line173)"></a><font color=Blue>-- element, so it raises both possible errors.</font>+<a name="(line174)"></a>manyFinally <font color=Red>::</font> PolyParse p <font color=Red>=></font> p a <font color=Red>-></font> p z <font color=Red>-></font> p <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line175)"></a>manyFinally p t <font color=Red>=</font>+<a name="(line176)"></a> <font color=Cyan>(</font>many p <font color=Cyan>`discard`</font> t<font color=Cyan>)</font>+<a name="(line177)"></a> <font color=Cyan>`onFail`</font>+<a name="(line178)"></a> oneOf' <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"sequence terminator"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> t<font color=Cyan>;</font> return [] <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line179)"></a> <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"item in a sequence"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> p<font color=Cyan>;</font> return [] <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line180)"></a> <font color=Red>]</font>+<a name="(line181)"></a><font color=Blue>{-+<a name="(line182)"></a>manyFinally p t =+<a name="(line183)"></a> do { xs <- many p+<a name="(line184)"></a> ; oneOf' [ ("sequence terminator", do { t; return () } )+<a name="(line185)"></a> , ("item in a sequence", do { p; return () } )+<a name="(line186)"></a> ]+<a name="(line187)"></a> ; return xs+<a name="(line188)"></a> }+<a name="(line189)"></a>-}</font>+<a name="(line190)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/Lazy.html view
@@ -0,0 +1,140 @@+<!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 -> [t] -> (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->Bool) -> 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 -> Parser t z -> 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] -> 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>-></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>-></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>-></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>-></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="(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>-></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="(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>-></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>-></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>-></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>-></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>>>=</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="(line59)"></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="(line60)"></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="(line61)"></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="(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>-></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>-></font> <font color=Cyan>(</font>throwE e<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line67)"></a> right <font color=Red>-></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>-></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>-></font> q ts+<a name="(line70)"></a> right <font color=Red>-></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>-></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>-></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>-></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>-></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>-></font> fail e+<a name="(line80)"></a> es <font color=Red>-></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>-></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>-></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>-></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>-></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>-></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>-></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>-></font> x+<a name="(line97)"></a> <font color=Cyan>;</font> Left e <font color=Red>-></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>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>+<a name="(line102)"></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="(line103)"></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="(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>-></font>Bool<font color=Cyan>)</font> <font color=Red>-></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><-</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>-></font> Parser t z <font color=Red>-></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>-></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>-></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>-></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>-></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>-></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>-></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>-></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>
+ docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/Lazy.html view
@@ -0,0 +1,130 @@+<!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>NoLeak<font color=Cyan>.</font>Lazy+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad, PolyParse</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser t a -> [t] -> (Either String a, [t])</font>+<a name="(line5)"></a> <font color=Blue>-- ** basic parsers</font>+<a name="(line6)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser t t</font>+<a name="(line7)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser t t</font>+<a name="(line8)"></a>+<a name="(line9)"></a> <font color=Blue>-- ** re-parsing</font>+<a name="(line10)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser t ()</font>+<a name="(line11)"></a> <font color=Blue>-- * Re-export all more general combinators</font>+<a name="(line12)"></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="(line13)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line14)"></a>+<a name="(line15)"></a>+<a name="(line16)"></a><font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Base+<a name="(line17)"></a>+<a name="(line18)"></a><font color=Magenta><em>#if __GLASGOW_HASKELL__</em></font>+<a name="(line19)"></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="(line20)"></a><a name="throwE"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line21)"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>+<a name="(line22)"></a><font color=Magenta><em>#else</em></font>+<a name="(line23)"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line24)"></a>throwE msg <font color=Red>=</font> error msg+<a name="(line25)"></a><font color=Magenta><em>#endif</em></font>+<a name="(line26)"></a>+<a name="(line27)"></a>+<a name="(line28)"></a><a name="Parser"></a><font color=Blue>-- | This @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line29)"></a><a name="Parser"></a><font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>+<a name="(line30)"></a><a name="Parser"></a><font color=Blue>-- String input. (If you require a running state, use module PolyState</font>+<a name="(line31)"></a><a name="Parser"></a><font color=Blue>-- instead)</font>+<a name="(line32)"></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> Result <font color=Red>[</font>t<font color=Red>]</font> a<font color=Cyan>)</font>+<a name="(line33)"></a>+<a name="(line34)"></a><a name="Result"></a><font color=Blue>-- A return type like Either, that distinguishes not only between</font>+<a name="(line35)"></a><a name="Result"></a><font color=Blue>-- right and wrong answers, but also has gradations of wrongness.</font>+<a name="(line36)"></a><a name="Result"></a><font color=Green><u>data</u></font> Result z a <font color=Red>=</font> Success z a+<a name="(line37)"></a> <font color=Red>|</font> Failure z String+<a name="(line38)"></a> <font color=Red>|</font> Committed <font color=Cyan>(</font>Result z a<font color=Cyan>)</font> <font color=Blue>-- still needed</font>+<a name="(line39)"></a>+<a name="(line40)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Result z<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line41)"></a> fmap f <font color=Cyan>(</font>Success z a<font color=Cyan>)</font> <font color=Red>=</font> Success z <font color=Cyan>(</font>f a<font color=Cyan>)</font>+<a name="(line42)"></a> fmap f <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> Failure z e+<a name="(line43)"></a> fmap f <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>fmap f r<font color=Cyan>)</font>+<a name="(line44)"></a>+<a name="(line45)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence.</font>+<a name="(line46)"></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="(line47)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> fromResult <font color=Cyan>.</font> p+<a name="(line48)"></a> <font color=Green><u>where</u></font>+<a name="(line49)"></a> fromResult <font color=Red>::</font> Result z a <font color=Red>-></font> <font color=Cyan>(</font>a<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line50)"></a> fromResult <font color=Cyan>(</font>Success z a<font color=Cyan>)</font> <font color=Red>=</font> <font color=Cyan>(</font>a<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line51)"></a> fromResult <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> throwE e+<a name="(line52)"></a> fromResult <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> fromResult r+<a name="(line53)"></a>+<a name="(line54)"></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="(line55)"></a> fmap f <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font>fmap f <font color=Cyan>.</font> p<font color=Cyan>)</font>+<a name="(line56)"></a>+<a name="(line57)"></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="(line58)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> Success ts x<font color=Cyan>)</font>+<a name="(line59)"></a> fail e <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> Failure ts e<font color=Cyan>)</font>+<a name="(line60)"></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>continue <font color=Cyan>.</font> f<font color=Cyan>)</font>+<a name="(line61)"></a> <font color=Green><u>where</u></font>+<a name="(line62)"></a> continue <font color=Cyan>(</font>Success ts x<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+<a name="(line63)"></a> continue <font color=Cyan>(</font>Committed <font color=Cyan>(</font>Committed r<font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font>+<a name="(line64)"></a> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>continue r<font color=Cyan>)</font>+<a name="(line65)"></a> continue <font color=Cyan>(</font>Failure ts e<font color=Cyan>)</font> <font color=Red>=</font> Failure ts e+<a name="(line66)"></a>+<a name="(line67)"></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="(line68)"></a> commit <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font>Committed <font color=Cyan>.</font> p<font color=Cyan>)</font>+<a name="(line69)"></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>adjust <font color=Cyan>.</font> p<font color=Cyan>)</font>+<a name="(line70)"></a> <font color=Green><u>where</u></font>+<a name="(line71)"></a> adjust <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> Failure z <font color=Cyan>(</font>f e<font color=Cyan>)</font>+<a name="(line72)"></a> adjust <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>adjust r<font color=Cyan>)</font>+<a name="(line73)"></a> adjust good <font color=Red>=</font> good+<a name="(line74)"></a>+<a name="(line75)"></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> continue ts <font color=Cyan>$</font> p ts<font color=Cyan>)</font>+<a name="(line76)"></a> <font color=Green><u>where</u></font>+<a name="(line77)"></a> continue ts <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> q ts+<a name="(line78)"></a> <font color=Blue>-- continue _ (Committed r) = r -- no, remain Committed</font>+<a name="(line79)"></a> continue <font color=Green><u>_</u></font> r <font color=Red>=</font> r+<a name="(line80)"></a>+<a name="(line81)"></a> oneOf' <font color=Red>=</font> accum []+<a name="(line82)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line83)"></a> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line84)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line85)"></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="(line86)"></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="(line87)"></a> Failure <font color=Green><u>_</u></font> err <font color=Red>-></font>+<a name="(line88)"></a> <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="(line89)"></a> <font color=Green><u>in</u></font> p ts+<a name="(line90)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Success z a<font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line91)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Committed <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r <font color=Cyan>)</font>+<a name="(line92)"></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="(line93)"></a>+<a name="(line94)"></a> <font color=Blue>-- Apply a parsed function to a parsed value. This version</font>+<a name="(line95)"></a> <font color=Blue>-- is strict in the result of the function parser, but</font>+<a name="(line96)"></a> <font color=Blue>-- lazy in the result of the argument parser. (Argument laziness is</font>+<a name="(line97)"></a> <font color=Blue>-- the distinctive feature over other implementations.)</font>+<a name="(line98)"></a> <font color=Cyan>(</font>P pf<font color=Cyan>)</font> <font color=Cyan>`apply`</font> px <font color=Red>=</font> P <font color=Cyan>(</font>continue <font color=Cyan>.</font> pf<font color=Cyan>)</font>+<a name="(line99)"></a> <font color=Green><u>where</u></font>+<a name="(line100)"></a> continue <font color=Cyan>(</font>Success z f<font color=Cyan>)</font> <font color=Red>=</font> <font color=Green><u>let</u></font> <font color=Cyan>(</font>x<font color=Cyan>,</font>z'<font color=Cyan>)</font> <font color=Red>=</font> runParser px z+<a name="(line101)"></a> <font color=Green><u>in</u></font> Success z' <font color=Cyan>(</font>f x<font color=Cyan>)</font>+<a name="(line102)"></a> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>continue r<font color=Cyan>)</font>+<a name="(line103)"></a> continue <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> Failure z e+<a name="(line104)"></a>+<a name="(line105)"></a>+<a name="(line106)"></a><a name="next"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line107)"></a>next <font color=Red>::</font> Parser t t+<a name="(line108)"></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="(line109)"></a> [] <font color=Red>-></font> Failure [] <font color=Magenta>"Ran out of input (EOF)"</font>+<a name="(line110)"></a> <font color=Cyan>(</font>t<font color=Red><b>:</b></font>ts'<font color=Cyan>)</font> <font color=Red>-></font> Success ts' t <font color=Cyan>)</font>+<a name="(line111)"></a>+<a name="(line112)"></a><a name="satisfy"></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 pred <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> pred 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><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line118)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line119)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line120)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line121)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line122)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line123)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser t ()+<a name="(line124)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp<font color=Red>-></font> Success <font color=Cyan>(</font>ts<font color=Cyan>++</font>inp<font color=Cyan>)</font> ()<font color=Cyan>)</font>+<a name="(line125)"></a>+<a name="(line126)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/Plain.html view
@@ -0,0 +1,109 @@+<!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>NoLeak<font color=Cyan>.</font>Plain+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad, PolyParse</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser t a -> [t] -> (Either String a, [t])</font>+<a name="(line5)"></a> <font color=Blue>-- ** basic parsers</font>+<a name="(line6)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser t t</font>+<a name="(line7)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser t t</font>+<a name="(line8)"></a>+<a name="(line9)"></a> <font color=Blue>-- ** re-parsing</font>+<a name="(line10)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser t ()</font>+<a name="(line11)"></a> <font color=Blue>-- * Re-export all more general combinators</font>+<a name="(line12)"></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="(line13)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line14)"></a>+<a name="(line15)"></a>+<a name="(line16)"></a><font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Base+<a name="(line17)"></a>+<a name="(line18)"></a><a name="Parser"></a><font color=Blue>-- | This @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line19)"></a><a name="Parser"></a><font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>+<a name="(line20)"></a><a name="Parser"></a><font color=Blue>-- String input. (If you require a running state, use module PolyState</font>+<a name="(line21)"></a><a name="Parser"></a><font color=Blue>-- instead)</font>+<a name="(line22)"></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> Result <font color=Red>[</font>t<font color=Red>]</font> a<font color=Cyan>)</font>+<a name="(line23)"></a>+<a name="(line24)"></a><a name="Result"></a><font color=Blue>-- A return type like Either, that distinguishes not only between</font>+<a name="(line25)"></a><a name="Result"></a><font color=Blue>-- right and wrong answers, but also has commitment, so that a failure</font>+<a name="(line26)"></a><a name="Result"></a><font color=Blue>-- cannot be undone.</font>+<a name="(line27)"></a><a name="Result"></a><font color=Green><u>data</u></font> Result z a <font color=Red>=</font> Success z a+<a name="(line28)"></a> <font color=Red>|</font> Failure z String+<a name="(line29)"></a> <font color=Red>|</font> Committed <font color=Cyan>(</font>Result z a<font color=Cyan>)</font>+<a name="(line30)"></a>+<a name="(line31)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Result z<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line32)"></a> fmap f <font color=Cyan>(</font>Success z a<font color=Cyan>)</font> <font color=Red>=</font> Success z <font color=Cyan>(</font>f a<font color=Cyan>)</font>+<a name="(line33)"></a> fmap f <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> Failure z e+<a name="(line34)"></a> fmap f <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>fmap f r<font color=Cyan>)</font>+<a name="(line35)"></a>+<a name="(line36)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence.</font>+<a name="(line37)"></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>Either String a<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line38)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> resultToEither <font color=Cyan>.</font> p+<a name="(line39)"></a> <font color=Green><u>where</u></font>+<a name="(line40)"></a> resultToEither <font color=Red>::</font> Result z a <font color=Red>-></font> <font color=Cyan>(</font>Either String a<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line41)"></a> resultToEither <font color=Cyan>(</font>Success z a<font color=Cyan>)</font> <font color=Red>=</font> <font color=Cyan>(</font>Right a<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line42)"></a> resultToEither <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line43)"></a> resultToEither <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> resultToEither r+<a name="(line44)"></a>+<a name="(line45)"></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="(line46)"></a> fmap f <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font>fmap f <font color=Cyan>.</font> p<font color=Cyan>)</font>+<a name="(line47)"></a>+<a name="(line48)"></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="(line49)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> Success ts x<font color=Cyan>)</font>+<a name="(line50)"></a> fail e <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>ts<font color=Red>-></font> Failure ts e<font color=Cyan>)</font>+<a name="(line51)"></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>continue <font color=Cyan>.</font> f<font color=Cyan>)</font>+<a name="(line52)"></a> <font color=Green><u>where</u></font>+<a name="(line53)"></a> continue <font color=Cyan>(</font>Success ts x<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+<a name="(line54)"></a> continue <font color=Cyan>(</font>Committed <font color=Cyan>(</font>Committed r<font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font>+<a name="(line55)"></a> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>continue r<font color=Cyan>)</font>+<a name="(line56)"></a> continue <font color=Cyan>(</font>Failure ts e<font color=Cyan>)</font> <font color=Red>=</font> Failure ts e+<a name="(line57)"></a>+<a name="(line58)"></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="(line59)"></a> commit <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> P <font color=Cyan>(</font>Committed <font color=Cyan>.</font> p<font color=Cyan>)</font>+<a name="(line60)"></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>adjust <font color=Cyan>.</font> p<font color=Cyan>)</font>+<a name="(line61)"></a> <font color=Green><u>where</u></font>+<a name="(line62)"></a> adjust <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> Failure z <font color=Cyan>(</font>f e<font color=Cyan>)</font>+<a name="(line63)"></a> adjust <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>adjust r<font color=Cyan>)</font>+<a name="(line64)"></a> adjust good <font color=Red>=</font> good+<a name="(line65)"></a>+<a name="(line66)"></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> continue ts <font color=Cyan>$</font> p ts<font color=Cyan>)</font>+<a name="(line67)"></a> <font color=Green><u>where</u></font>+<a name="(line68)"></a> continue ts <font color=Cyan>(</font>Failure z e<font color=Cyan>)</font> <font color=Red>=</font> q ts+<a name="(line69)"></a> <font color=Blue>-- continue _ (Committed r) = r -- no, remain Committed</font>+<a name="(line70)"></a> continue <font color=Green><u>_</u></font> r <font color=Red>=</font> r+<a name="(line71)"></a>+<a name="(line72)"></a> oneOf' <font color=Red>=</font> accum []+<a name="(line73)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line74)"></a> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line75)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line76)"></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="(line77)"></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="(line78)"></a> Failure <font color=Green><u>_</u></font> err <font color=Red>-></font>+<a name="(line79)"></a> <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="(line80)"></a> <font color=Green><u>in</u></font> p ts+<a name="(line81)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Success z a<font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line82)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Committed <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r <font color=Cyan>)</font>+<a name="(line83)"></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="(line84)"></a>+<a name="(line85)"></a><a name="next"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line86)"></a>next <font color=Red>::</font> Parser t t+<a name="(line87)"></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="(line88)"></a> [] <font color=Red>-></font> Failure [] <font color=Magenta>"Ran out of input (EOF)"</font>+<a name="(line89)"></a> <font color=Cyan>(</font>t<font color=Red><b>:</b></font>ts'<font color=Cyan>)</font> <font color=Red>-></font> Success ts' t <font color=Cyan>)</font>+<a name="(line90)"></a>+<a name="(line91)"></a><a name="satisfy"></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="(line92)"></a>satisfy pred <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> next+<a name="(line93)"></a> <font color=Cyan>;</font> <font color=Green><u>if</u></font> pred 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="(line94)"></a> <font color=Cyan>}</font>+<a name="(line95)"></a>+<a name="(line96)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line97)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line98)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line99)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line100)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line101)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line102)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser t ()+<a name="(line103)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>inp<font color=Red>-></font> Success <font color=Cyan>(</font>ts<font color=Cyan>++</font>inp<font color=Cyan>)</font> ()<font color=Cyan>)</font>+<a name="(line104)"></a>+<a name="(line105)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/State.html view
@@ -0,0 +1,126 @@+<!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>NoLeak<font color=Cyan>.</font>State+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad, PolyParse</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])</font>+<a name="(line5)"></a> <font color=Blue>-- ** basic parsers</font>+<a name="(line6)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser s t t</font>+<a name="(line7)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>+<a name="(line8)"></a> <font color=Blue>-- ** State-handling</font>+<a name="(line9)"></a> <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>+<a name="(line10)"></a> <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>+<a name="(line11)"></a> <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>+<a name="(line12)"></a> <font color=Blue>-- ** re-parsing</font>+<a name="(line13)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s 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>+<a name="(line19)"></a><font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Base+<a name="(line20)"></a>+<a name="(line21)"></a><a name="Parser"></a><font color=Blue>-- | This @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line22)"></a><a name="Parser"></a><font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>+<a name="(line23)"></a><a name="Parser"></a><font color=Blue>-- String input. (If you require a running state, use module PolyState</font>+<a name="(line24)"></a><a name="Parser"></a><font color=Blue>-- instead)</font>+<a name="(line25)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Result <font color=Red>[</font>t<font color=Red>]</font> s a<font color=Cyan>)</font>+<a name="(line26)"></a>+<a name="(line27)"></a><a name="Result"></a><font color=Blue>-- A return type like Either, that distinguishes not only between</font>+<a name="(line28)"></a><a name="Result"></a><font color=Blue>-- right and wrong answers, but also has gradations of wrongness.</font>+<a name="(line29)"></a><a name="Result"></a><font color=Green><u>data</u></font> Result z s a <font color=Red>=</font> Success z s a+<a name="(line30)"></a> <font color=Red>|</font> Failure z s String+<a name="(line31)"></a> <font color=Red>|</font> Committed <font color=Cyan>(</font>Result z s a<font color=Cyan>)</font>+<a name="(line32)"></a>+<a name="(line33)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Result z s<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line34)"></a> fmap f <font color=Cyan>(</font>Success z s a<font color=Cyan>)</font> <font color=Red>=</font> Success z s <font color=Cyan>(</font>f a<font color=Cyan>)</font>+<a name="(line35)"></a> fmap f <font color=Cyan>(</font>Failure z s e<font color=Cyan>)</font> <font color=Red>=</font> Failure z s e+<a name="(line36)"></a> fmap f <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>fmap f r<font color=Cyan>)</font>+<a name="(line37)"></a>+<a name="(line38)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence.</font>+<a name="(line39)"></a>runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <font color=Red>-></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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line40)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> <font color=Red>\</font>s<font color=Red>-></font> resultToEither <font color=Cyan>.</font> p s+<a name="(line41)"></a> <font color=Green><u>where</u></font>+<a name="(line42)"></a> resultToEither <font color=Red>::</font> Result z s a <font color=Red>-></font> <font color=Cyan>(</font>Either String a<font color=Cyan>,</font> s<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line43)"></a> resultToEither <font color=Cyan>(</font>Success z s a<font color=Cyan>)</font> <font color=Red>=</font> <font color=Cyan>(</font>Right a<font color=Cyan>,</font> s<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line44)"></a> resultToEither <font color=Cyan>(</font>Failure z s e<font color=Cyan>)</font> <font color=Red>=</font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line45)"></a> resultToEither <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> resultToEither r+<a name="(line46)"></a>+<a name="(line47)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line48)"></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>s<font color=Red>-></font> fmap f <font color=Cyan>.</font> p s<font color=Cyan>)</font>+<a name="(line49)"></a>+<a name="(line50)"></a><font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line51)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts s x<font color=Cyan>)</font>+<a name="(line52)"></a> fail e <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Failure ts s e<font color=Cyan>)</font>+<a name="(line53)"></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>s<font color=Red>-></font> continue <font color=Cyan>.</font> f s<font color=Cyan>)</font>+<a name="(line54)"></a> <font color=Green><u>where</u></font>+<a name="(line55)"></a> continue <font color=Cyan>(</font>Success ts s x<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' s ts+<a name="(line56)"></a> continue <font color=Cyan>(</font>Committed <font color=Cyan>(</font>Committed r<font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font>+<a name="(line57)"></a> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>continue r<font color=Cyan>)</font>+<a name="(line58)"></a> continue <font color=Cyan>(</font>Failure ts s e<font color=Cyan>)</font> <font color=Red>=</font> Failure ts s e+<a name="(line59)"></a>+<a name="(line60)"></a><font color=Green><u>instance</u></font> PolyParse <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line61)"></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>s<font color=Red>-></font> Committed <font color=Cyan>.</font> p s<font color=Cyan>)</font>+<a name="(line62)"></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>s<font color=Red>-></font> adjust <font color=Cyan>.</font> p s<font color=Cyan>)</font>+<a name="(line63)"></a> <font color=Green><u>where</u></font>+<a name="(line64)"></a> adjust <font color=Cyan>(</font>Failure z s e<font color=Cyan>)</font> <font color=Red>=</font> Failure z s <font color=Cyan>(</font>f e<font color=Cyan>)</font>+<a name="(line65)"></a> adjust <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>adjust r<font color=Cyan>)</font>+<a name="(line66)"></a> adjust good <font color=Red>=</font> good+<a name="(line67)"></a>+<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>s ts<font color=Red>-></font> continue s ts <font color=Cyan>$</font> p s ts<font color=Cyan>)</font>+<a name="(line69)"></a> <font color=Green><u>where</u></font>+<a name="(line70)"></a> continue s ts <font color=Cyan>(</font>Failure <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>=</font> q s ts+<a name="(line71)"></a> <font color=Blue>-- continue _ _ (Committed r) = r -- no, remain Committed</font>+<a name="(line72)"></a> continue <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> r <font color=Red>=</font> r+<a name="(line73)"></a>+<a name="(line74)"></a> oneOf' <font color=Red>=</font> accum []+<a name="(line75)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line76)"></a> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line77)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line78)"></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="(line79)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line80)"></a> Failure <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> err <font color=Red>-></font>+<a name="(line81)"></a> <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="(line82)"></a> <font color=Green><u>in</u></font> p s ts+<a name="(line83)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Success z <font color=Green><u>_</u></font> a<font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line84)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Committed <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r <font color=Cyan>)</font>+<a name="(line85)"></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="(line86)"></a>+<a name="(line87)"></a><a name="next"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line88)"></a>next <font color=Red>::</font> Parser s t t+<a name="(line89)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>+<a name="(line90)"></a> [] <font color=Red>-></font> Failure [] s <font color=Magenta>"Ran out of input (EOF)"</font>+<a name="(line91)"></a> <font color=Cyan>(</font>t<font color=Red><b>:</b></font>ts'<font color=Cyan>)</font> <font color=Red>-></font> Success ts' s t <font color=Cyan>)</font>+<a name="(line92)"></a>+<a name="(line93)"></a><a name="satisfy"></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 s t t+<a name="(line94)"></a>satisfy pred <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> next+<a name="(line95)"></a> <font color=Cyan>;</font> <font color=Green><u>if</u></font> pred 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="(line96)"></a> <font color=Cyan>}</font>+<a name="(line97)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line98)"></a><font color=Blue>-- State handling</font>+<a name="(line99)"></a>+<a name="(line100)"></a><a name="stUpdate"></a><font color=Blue>-- | Update the internal state.</font>+<a name="(line101)"></a>stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t ()+<a name="(line102)"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts <font color=Cyan>(</font>f s<font color=Cyan>)</font> ()<font color=Cyan>)</font>+<a name="(line103)"></a>+<a name="(line104)"></a><a name="stQuery"></a><font color=Blue>-- | Query the internal state.</font>+<a name="(line105)"></a>stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a+<a name="(line106)"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts s <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line107)"></a>+<a name="(line108)"></a><a name="stGet"></a><font color=Blue>-- | Deliver the entire internal state.</font>+<a name="(line109)"></a>stGet <font color=Red>::</font> Parser s t s+<a name="(line110)"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts s s<font color=Cyan>)</font>+<a name="(line111)"></a>+<a name="(line112)"></a>+<a name="(line113)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line114)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line115)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line116)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line117)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line118)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line119)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t ()+<a name="(line120)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> Success <font color=Cyan>(</font>ts<font color=Cyan>++</font>inp<font color=Cyan>)</font> s ()<font color=Cyan>)</font>+<a name="(line121)"></a>+<a name="(line122)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/NoLeak/StateLazy.html view
@@ -0,0 +1,176 @@+<!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>NoLeak<font color=Cyan>.</font>StateLazy+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad, PolyParse</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])</font>+<a name="(line5)"></a> <font color=Blue>-- ** basic parsers</font>+<a name="(line6)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser s t t</font>+<a name="(line7)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>+<a name="(line8)"></a> <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser s t a -> Parser s t z -> Parser s t [a]</font>+<a name="(line9)"></a> <font color=Blue>-- ** State-handling</font>+<a name="(line10)"></a> <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>+<a name="(line11)"></a> <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>+<a name="(line12)"></a> <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>+<a name="(line13)"></a> <font color=Blue>-- ** re-parsing</font>+<a name="(line14)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s t ()</font>+<a name="(line15)"></a> <font color=Blue>-- * Re-export all more general combinators</font>+<a name="(line16)"></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="(line17)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line18)"></a>+<a name="(line19)"></a>+<a name="(line20)"></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="(line21)"></a>+<a name="(line22)"></a><font color=Magenta><em>#if __GLASGOW_HASKELL__</em></font>+<a name="(line23)"></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="(line24)"></a><a name="throwE"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line25)"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>+<a name="(line26)"></a><font color=Magenta><em>#else</em></font>+<a name="(line27)"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line28)"></a>throwE msg <font color=Red>=</font> error msg+<a name="(line29)"></a><font color=Magenta><em>#endif</em></font>+<a name="(line30)"></a>+<a name="(line31)"></a>+<a name="(line32)"></a><a name="Parser"></a><font color=Blue>-- | This @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line33)"></a><a name="Parser"></a><font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>+<a name="(line34)"></a><a name="Parser"></a><font color=Blue>-- String input. (If you require a running state, use module PolyState</font>+<a name="(line35)"></a><a name="Parser"></a><font color=Blue>-- instead)</font>+<a name="(line36)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Result <font color=Red>[</font>t<font color=Red>]</font> s a<font color=Cyan>)</font>+<a name="(line37)"></a>+<a name="(line38)"></a><a name="Result"></a><font color=Blue>-- A return type like Either, that distinguishes not only between</font>+<a name="(line39)"></a><a name="Result"></a><font color=Blue>-- right and wrong answers, but also has gradations of wrongness.</font>+<a name="(line40)"></a><a name="Result"></a><font color=Green><u>data</u></font> Result z s a <font color=Red>=</font> Success z s a+<a name="(line41)"></a> <font color=Red>|</font> Failure z s String+<a name="(line42)"></a> <font color=Red>|</font> Committed <font color=Cyan>(</font>Result z s a<font color=Cyan>)</font>+<a name="(line43)"></a>+<a name="(line44)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Result z s<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line45)"></a> fmap f <font color=Cyan>(</font>Success z s a<font color=Cyan>)</font> <font color=Red>=</font> Success z s <font color=Cyan>(</font>f a<font color=Cyan>)</font>+<a name="(line46)"></a> fmap f <font color=Cyan>(</font>Failure z s e<font color=Cyan>)</font> <font color=Red>=</font> Failure z s e+<a name="(line47)"></a> fmap f <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>fmap f r<font color=Cyan>)</font>+<a name="(line48)"></a>+<a name="(line49)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence.</font>+<a name="(line50)"></a>runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line51)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font> <font color=Red>\</font>s <font color=Red>-></font> fromResult <font color=Cyan>.</font> p s+<a name="(line52)"></a> <font color=Green><u>where</u></font>+<a name="(line53)"></a> fromResult <font color=Red>::</font> Result z s a <font color=Red>-></font> <font color=Cyan>(</font>a<font color=Cyan>,</font> s<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line54)"></a> fromResult <font color=Cyan>(</font>Success z s a<font color=Cyan>)</font> <font color=Red>=</font> <font color=Cyan>(</font>a<font color=Cyan>,</font> s<font color=Cyan>,</font> z<font color=Cyan>)</font>+<a name="(line55)"></a> fromResult <font color=Cyan>(</font>Failure z s e<font color=Cyan>)</font> <font color=Red>=</font> throwE e+<a name="(line56)"></a> fromResult <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> fromResult r+<a name="(line57)"></a>+<a name="(line58)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line59)"></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>s <font color=Red>-></font> fmap f <font color=Cyan>.</font> p s<font color=Cyan>)</font>+<a name="(line60)"></a>+<a name="(line61)"></a><font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line62)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts s x<font color=Cyan>)</font>+<a name="(line63)"></a> fail e <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Failure ts s e<font color=Cyan>)</font>+<a name="(line64)"></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>s<font color=Red>-></font> continue <font color=Cyan>.</font> f s<font color=Cyan>)</font>+<a name="(line65)"></a> <font color=Green><u>where</u></font>+<a name="(line66)"></a> continue <font color=Cyan>(</font>Success ts s x<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' s ts+<a name="(line67)"></a> continue <font color=Cyan>(</font>Committed <font color=Cyan>(</font>Committed r<font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font>+<a name="(line68)"></a> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>continue r<font color=Cyan>)</font>+<a name="(line69)"></a> continue <font color=Cyan>(</font>Failure ts s e<font color=Cyan>)</font> <font color=Red>=</font> Failure ts s e+<a name="(line70)"></a>+<a name="(line71)"></a><font color=Green><u>instance</u></font> PolyParse <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line72)"></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>s<font color=Red>-></font> Committed <font color=Cyan>.</font> p s<font color=Cyan>)</font>+<a name="(line73)"></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>s<font color=Red>-></font> adjust <font color=Cyan>.</font> p s<font color=Cyan>)</font>+<a name="(line74)"></a> <font color=Green><u>where</u></font>+<a name="(line75)"></a> adjust <font color=Cyan>(</font>Failure z s e<font color=Cyan>)</font> <font color=Red>=</font> Failure z s <font color=Cyan>(</font>f e<font color=Cyan>)</font>+<a name="(line76)"></a> adjust <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>adjust r<font color=Cyan>)</font>+<a name="(line77)"></a> adjust good <font color=Red>=</font> good+<a name="(line78)"></a>+<a name="(line79)"></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>s ts<font color=Red>-></font> continue s ts <font color=Cyan>$</font> p s ts<font color=Cyan>)</font>+<a name="(line80)"></a> <font color=Green><u>where</u></font>+<a name="(line81)"></a> continue s ts <font color=Cyan>(</font>Failure <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>=</font> q s ts+<a name="(line82)"></a> <font color=Blue>-- continue _ _ (Committed r) = r -- no, remain Committed</font>+<a name="(line83)"></a> continue <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> r <font color=Red>=</font> r+<a name="(line84)"></a>+<a name="(line85)"></a> oneOf' <font color=Red>=</font> accum []+<a name="(line86)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line87)"></a> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line88)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line89)"></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="(line90)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line91)"></a> Failure <font color=Green><u>_</u></font> <font color=Green><u>_</u></font> err <font color=Red>-></font>+<a name="(line92)"></a> <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="(line93)"></a> <font color=Green><u>in</u></font> p s ts+<a name="(line94)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Success z <font color=Green><u>_</u></font> a<font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line95)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Committed <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r <font color=Cyan>)</font>+<a name="(line96)"></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="(line97)"></a>+<a name="(line98)"></a> <font color=Blue>-- Apply a parsed function to a parsed value. This version</font>+<a name="(line99)"></a> <font color=Blue>-- is strict in the result of the function parser, but</font>+<a name="(line100)"></a> <font color=Blue>-- lazy in the result of the argument parser. (Argument laziness is</font>+<a name="(line101)"></a> <font color=Blue>-- the distinctive feature over other implementations.)</font>+<a name="(line102)"></a> <font color=Cyan>(</font>P pf<font color=Cyan>)</font> <font color=Cyan>`apply`</font> px <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s<font color=Red>-></font> continue <font color=Cyan>.</font> pf s<font color=Cyan>)</font>+<a name="(line103)"></a> <font color=Green><u>where</u></font>+<a name="(line104)"></a> continue <font color=Cyan>(</font>Success z s f<font color=Cyan>)</font> <font color=Red>=</font> <font color=Green><u>let</u></font> <font color=Cyan>(</font>x<font color=Cyan>,</font>s'<font color=Cyan>,</font>z'<font color=Cyan>)</font> <font color=Red>=</font> runParser px s z+<a name="(line105)"></a> <font color=Green><u>in</u></font> Success z' s' <font color=Cyan>(</font>f x<font color=Cyan>)</font>+<a name="(line106)"></a> continue <font color=Cyan>(</font>Failure z s e<font color=Cyan>)</font> <font color=Red>=</font> Failure z s e+<a name="(line107)"></a> continue <font color=Cyan>(</font>Committed r<font color=Cyan>)</font> <font color=Red>=</font> Committed <font color=Cyan>(</font>continue r<font color=Cyan>)</font>+<a name="(line108)"></a>+<a name="(line109)"></a><a name="manyFinally"></a>manyFinally <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t z <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line110)"></a><font color=Blue>{-+<a name="(line111)"></a>manyFinally pp@(P p) pt@(P t) = P (\s ts -> item s ts (p s ts))+<a name="(line112)"></a> where+<a name="(line113)"></a> item _ _ (Success ts s x) = success ts s x+<a name="(line114)"></a> item s ts (Failure _ _ e) = terminate (t s ts)+<a name="(line115)"></a> item s ts (Committed r) = Committed (within r)+<a name="(line116)"></a>+<a name="(line117)"></a> success ts s x =+<a name="(line118)"></a> let (tail,s',ts') = runParser (manyFinally pp pt) s ts+<a name="(line119)"></a> in Success ts' s' (x:tail)+<a name="(line120)"></a>+<a name="(line121)"></a> terminate (Success ts s _) = Success ts s []+<a name="(line122)"></a> terminate (Failure ts s e) = Failure ts s e+<a name="(line123)"></a> terminate (Committed r) = Committed (terminate r)+<a name="(line124)"></a>+<a name="(line125)"></a> within (Success ts s x) = success ts s x+<a name="(line126)"></a> within (Failure ts s e) = Failure ts s e+<a name="(line127)"></a> within (Committed r) = within r+<a name="(line128)"></a>-}</font>+<a name="(line129)"></a>+<a name="(line130)"></a>manyFinally p z <font color=Red>=</font>+<a name="(line131)"></a> <font color=Cyan>(</font><font color=Green><u>do</u></font> x <font color=Red><-</font> p<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> manyFinally p z<font color=Cyan>)</font>+<a name="(line132)"></a> <font color=Cyan>`onFail`</font>+<a name="(line133)"></a> <font color=Cyan>(</font><font color=Green><u>do</u></font> z<font color=Cyan>;</font> return []<font color=Cyan>)</font>+<a name="(line134)"></a> <font color=Cyan>`onFail`</font>+<a name="(line135)"></a> oneOf' <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"item in sequence"</font><font color=Cyan>,</font> <font color=Cyan>(</font><font color=Green><u>do</u></font> p<font color=Cyan>;</font> return []<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line136)"></a> <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"sequence terminator"</font><font color=Cyan>,</font> <font color=Cyan>(</font><font color=Green><u>do</u></font> z<font color=Cyan>;</font> return []<font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>]</font>+<a name="(line137)"></a>+<a name="(line138)"></a><a name="next"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line139)"></a>next <font color=Red>::</font> Parser s t t+<a name="(line140)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>+<a name="(line141)"></a> [] <font color=Red>-></font> Failure [] s <font color=Magenta>"Ran out of input (EOF)"</font>+<a name="(line142)"></a> <font color=Cyan>(</font>t<font color=Red><b>:</b></font>ts'<font color=Cyan>)</font> <font color=Red>-></font> Success ts' s t <font color=Cyan>)</font>+<a name="(line143)"></a>+<a name="(line144)"></a><a name="satisfy"></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 s t t+<a name="(line145)"></a>satisfy pred <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> next+<a name="(line146)"></a> <font color=Cyan>;</font> <font color=Green><u>if</u></font> pred 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="(line147)"></a> <font color=Cyan>}</font>+<a name="(line148)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line149)"></a><font color=Blue>-- State handling</font>+<a name="(line150)"></a>+<a name="(line151)"></a><a name="stUpdate"></a><font color=Blue>-- | Update the internal state.</font>+<a name="(line152)"></a>stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t ()+<a name="(line153)"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts <font color=Cyan>(</font>f s<font color=Cyan>)</font> ()<font color=Cyan>)</font>+<a name="(line154)"></a>+<a name="(line155)"></a><a name="stQuery"></a><font color=Blue>-- | Query the internal state.</font>+<a name="(line156)"></a>stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a+<a name="(line157)"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts s <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line158)"></a>+<a name="(line159)"></a><a name="stGet"></a><font color=Blue>-- | Deliver the entire internal state.</font>+<a name="(line160)"></a>stGet <font color=Red>::</font> Parser s t s+<a name="(line161)"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> Success ts s s<font color=Cyan>)</font>+<a name="(line162)"></a>+<a name="(line163)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line164)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line165)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line166)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line167)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line168)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line169)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t ()+<a name="(line170)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> Success <font color=Cyan>(</font>ts<font color=Cyan>++</font>inp<font color=Cyan>)</font> s ()<font color=Cyan>)</font>+<a name="(line171)"></a>+<a name="(line172)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/Plain.html view
@@ -0,0 +1,96 @@+<!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>Plain+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad, PolyParse</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser t a -> [t] -> (Either String a, [t])</font>+<a name="(line5)"></a> <font color=Blue>-- ** basic parsers</font>+<a name="(line6)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser t t</font>+<a name="(line7)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser t t</font>+<a name="(line8)"></a>+<a name="(line9)"></a> <font color=Blue>-- ** re-parsing</font>+<a name="(line10)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser t ()</font>+<a name="(line11)"></a> <font color=Blue>-- * Re-export all more general combinators</font>+<a name="(line12)"></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="(line13)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line14)"></a>+<a name="(line15)"></a>+<a name="(line16)"></a><font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Base+<a name="(line17)"></a>+<a name="(line18)"></a><a name="Parser"></a><font color=Blue>-- | This @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line19)"></a><a name="Parser"></a><font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>+<a name="(line20)"></a><a name="Parser"></a><font color=Blue>-- String input. (If you require a running state, use module PolyState</font>+<a name="(line21)"></a><a name="Parser"></a><font color=Blue>-- instead)</font>+<a name="(line22)"></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>EitherE 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="(line23)"></a>+<a name="(line24)"></a><a name="EitherE"></a><font color=Blue>-- A return type like Either, that distinguishes not only between</font>+<a name="(line25)"></a><a name="EitherE"></a><font color=Blue>-- right and wrong answers, but also has gradations of wrongness.</font>+<a name="(line26)"></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="(line27)"></a>+<a name="(line28)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an input token sequence.</font>+<a name="(line29)"></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>Either String a<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line30)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font>+<a name="(line31)"></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 <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>m<font color=Cyan>)</font><font color=Red>-></font>Left m<font color=Cyan>;</font> Right m<font color=Red>-></font>Right m<font color=Cyan>}</font><font color=Cyan>,</font> ts<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line32)"></a> <font color=Cyan>.</font> p+<a name="(line33)"></a>+<a name="(line34)"></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="(line35)"></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="(line36)"></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="(line37)"></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="(line38)"></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="(line39)"></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="(line40)"></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="(line41)"></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="(line42)"></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="(line43)"></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 <font color=Cyan>(</font>False<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line44)"></a>+<a name="(line45)"></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="(line46)"></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="(line47)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line48)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line49)"></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="(line50)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line51)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line52)"></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="(line53)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line54)"></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="(line55)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line56)"></a> oneOf' <font color=Red>=</font> accum []+<a name="(line57)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line58)"></a> <font color=Green><u>case</u></font> filter isBad errs <font color=Green><u>of</u></font>+<a name="(line59)"></a> [] <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line60)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line61)"></a> <font color=Red>[</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> failBad e+<a name="(line62)"></a> es <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>+<a name="(line63)"></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="(line64)"></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="(line65)"></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="(line66)"></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="(line67)"></a> <font color=Green><u>in</u></font> p ts+<a name="(line68)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line69)"></a> showErr <font color=Cyan>(</font>name<font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>err<font color=Cyan>)</font><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="(line70)"></a> isBad <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> b+<a name="(line71)"></a>+<a name="(line72)"></a><a name="next"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line73)"></a>next <font color=Red>::</font> Parser t t+<a name="(line74)"></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="(line75)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>)</font><font color=Cyan>,</font> []<font color=Cyan>)</font>+<a name="(line76)"></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="(line77)"></a>+<a name="(line78)"></a><a name="satisfy"></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="(line79)"></a>satisfy pred <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> x <font color=Red><-</font> next+<a name="(line80)"></a> <font color=Cyan>;</font> <font color=Green><u>if</u></font> pred 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="(line81)"></a> <font color=Cyan>}</font>+<a name="(line82)"></a>+<a name="(line83)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line84)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line85)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line86)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line87)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line88)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line89)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser t ()+<a name="(line90)"></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="(line91)"></a>+<a name="(line92)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/State.html view
@@ -0,0 +1,113 @@+<!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>State+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])</font>+<a name="(line5)"></a> <font color=Blue>-- ** basic parsers</font>+<a name="(line6)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser s t t</font>+<a name="(line7)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>+<a name="(line8)"></a> <font color=Blue>-- ** State-handling</font>+<a name="(line9)"></a> <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>+<a name="(line10)"></a> <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>+<a name="(line11)"></a> <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>+<a name="(line12)"></a> <font color=Blue>-- ** Re-parsing</font>+<a name="(line13)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s 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+<a name="(line19)"></a>+<a name="(line20)"></a><a name="Parser"></a><font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line21)"></a><a name="Parser"></a><font color=Blue>-- reporting and a running state. It can be used for arbitrary token</font>+<a name="(line22)"></a><a name="Parser"></a><font color=Blue>-- types, not just String input.</font>+<a name="(line23)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>EitherE String a<font color=Cyan>,</font> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line24)"></a>+<a name="(line25)"></a><a name="EitherE"></a><font color=Blue>-- | A return type like Either, that distinguishes not only between</font>+<a name="(line26)"></a><a name="EitherE"></a><font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>+<a name="(line27)"></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="(line28)"></a>+<a name="(line29)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an initial state and input token sequence.</font>+<a name="(line30)"></a>runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <font color=Red>-></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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line31)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> s <font color=Red>=</font>+<a name="(line32)"></a> <font color=Cyan>(</font><font color=Red>\</font> <font color=Cyan>(</font>e<font color=Cyan>,</font>s<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> Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>m<font color=Cyan>)</font><font color=Red>-></font>Left m<font color=Cyan>;</font> Right m<font color=Red>-></font>Right m+<a name="(line33)"></a> <font color=Cyan>,</font>s<font color=Cyan>,</font>ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line34)"></a> <font color=Cyan>.</font> p s+<a name="(line35)"></a>+<a name="(line36)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line37)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line38)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line39)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line40)"></a><font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line41)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line42)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> f s ts <font color=Green><u>of</u></font>+<a name="(line43)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line44)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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+<a name="(line45)"></a> <font color=Green><u>in</u></font> g' s' ts'<font color=Cyan>)</font>+<a name="(line46)"></a> fail msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line47)"></a>+<a name="(line48)"></a><font color=Green><u>instance</u></font> PolyParse <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line49)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line50)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line51)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line52)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line53)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line54)"></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=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> q s ts+<a name="(line55)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line56)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line57)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line58)"></a> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line59)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line60)"></a> oneOf' <font color=Red>=</font> accum []+<a name="(line61)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line62)"></a> <font color=Green><u>case</u></font> filter isBad errs <font color=Green><u>of</u></font>+<a name="(line63)"></a> [] <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line64)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line65)"></a> <font color=Red>[</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> failBad e+<a name="(line66)"></a> es <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>+<a name="(line67)"></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="(line68)"></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="(line69)"></a> P <font color=Cyan>(</font><font color=Red>\</font>u ts<font color=Red>-></font> <font color=Green><u>case</u></font> p u ts <font color=Green><u>of</u></font>+<a name="(line70)"></a> <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><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="(line71)"></a> <font color=Green><u>in</u></font> p u ts+<a name="(line72)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line73)"></a> showErr <font color=Cyan>(</font>name<font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>err<font color=Cyan>)</font><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="(line74)"></a> isBad <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> b+<a name="(line75)"></a>+<a name="(line76)"></a><a name="next"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line77)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>+<a name="(line78)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> []<font color=Cyan>)</font>+<a name="(line79)"></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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line80)"></a>+<a name="(line81)"></a><a name="satisfy"></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 s t t+<a name="(line82)"></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="(line83)"></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="(line84)"></a> <font color=Cyan>}</font>+<a name="(line85)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line86)"></a><font color=Blue>-- State handling</font>+<a name="(line87)"></a>+<a name="(line88)"></a><a name="stUpdate"></a><font color=Blue>-- | Update the internal state.</font>+<a name="(line89)"></a>stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t ()+<a name="(line90)"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> f s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line91)"></a>+<a name="(line92)"></a><a name="stQuery"></a><font color=Blue>-- | Query the internal state.</font>+<a name="(line93)"></a>stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a+<a name="(line94)"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line95)"></a>+<a name="(line96)"></a><a name="stGet"></a><font color=Blue>-- | Deliver the entire internal state.</font>+<a name="(line97)"></a>stGet <font color=Red>::</font> Parser s t s+<a name="(line98)"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right s<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line99)"></a>+<a name="(line100)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line101)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line102)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line103)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line104)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line105)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line106)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t ()+<a name="(line107)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line108)"></a>+<a name="(line109)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
+ docs/haddock/src/Text/ParserCombinators/Poly/StateLazy.html view
@@ -0,0 +1,144 @@+<!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>StateLazy+<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 s t a -> s -> [t] -> (a, s, [t])</font>+<a name="(line6)"></a> <font color=Blue>-- * Combinators:</font>+<a name="(line7)"></a> <font color=Blue>-- ** Primitives</font>+<a name="(line8)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser s t t</font>+<a name="(line9)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>+<a name="(line10)"></a> <font color=Blue>-- ** State-handling</font>+<a name="(line11)"></a> <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>+<a name="(line12)"></a> <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>+<a name="(line13)"></a> <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>+<a name="(line14)"></a> <font color=Blue>-- ** Re-parsing</font>+<a name="(line15)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s t ()</font>+<a name="(line16)"></a> <font color=Blue>-- * Re-export all more general combinators</font>+<a name="(line17)"></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="(line18)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line19)"></a>+<a name="(line20)"></a><font color=Green><u>import</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>Poly<font color=Cyan>.</font>Base+<a name="(line21)"></a>+<a name="(line22)"></a><font color=Magenta><em>#if __GLASGOW_HASKELL__</em></font>+<a name="(line23)"></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="(line24)"></a><a name="throwE"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line25)"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>+<a name="(line26)"></a><font color=Magenta><em>#else</em></font>+<a name="(line27)"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line28)"></a>throwE msg <font color=Red>=</font> error msg+<a name="(line29)"></a><font color=Magenta><em>#endif</em></font>+<a name="(line30)"></a>+<a name="(line31)"></a><font color=Blue>-- $parser</font>+<a name="(line32)"></a><font color=Blue>-- Parsers do not return explicit failure. An exception is raised</font>+<a name="(line33)"></a><font color=Blue>-- instead. This allows partial results to be returned before a</font>+<a name="(line34)"></a><font color=Blue>-- full parse is complete.</font>+<a name="(line35)"></a>+<a name="(line36)"></a><a name="Parser"></a><font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line37)"></a><a name="Parser"></a><font color=Blue>-- reporting and a running state. It can be used for arbitrary token</font>+<a name="(line38)"></a><a name="Parser"></a><font color=Blue>-- types, not just String input.</font>+<a name="(line39)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line40)"></a>+<a name="(line41)"></a><a name="EitherE"></a><font color=Blue>-- | A return type like Either, that distinguishes not only between</font>+<a name="(line42)"></a><a name="EitherE"></a><font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>+<a name="(line43)"></a><a name="EitherE"></a><font color=Blue>-- Not used in this library. !!!!!!!!!!!!!!!!!!!!!!!!!!</font>+<a name="(line44)"></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="(line45)"></a>+<a name="(line46)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an initial state and input token sequence.</font>+<a name="(line47)"></a><font color=Blue>-- The parser cannot return an error value explicitly, so errors</font>+<a name="(line48)"></a><font color=Blue>-- raise an exception. Thus, results can be partial (lazily constructed,</font>+<a name="(line49)"></a><font color=Blue>-- but containing undefined).</font>+<a name="(line50)"></a>runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line51)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> s <font color=Red>=</font>+<a name="(line52)"></a> <font color=Cyan>(</font><font color=Red>\</font> <font color=Cyan>(</font>e<font color=Cyan>,</font>s<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> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line53)"></a> <font color=Cyan>.</font> p s+<a name="(line54)"></a>+<a name="(line55)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line56)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line57)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line58)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line59)"></a><font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line60)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line61)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> f s ts <font color=Green><u>of</u></font>+<a name="(line62)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line63)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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+<a name="(line64)"></a> <font color=Green><u>in</u></font> g' s' ts'<font color=Cyan>)</font>+<a name="(line65)"></a> fail msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line66)"></a>+<a name="(line67)"></a><font color=Green><u>instance</u></font> PolyParse <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line68)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line69)"></a> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>throwE e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line70)"></a> right <font color=Red>-></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>+<a name="(line72)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line73)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line74)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line75)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line76)"></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=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> q s ts+<a name="(line77)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line78)"></a> oneOf' ps <font color=Red>=</font> accum [] ps+<a name="(line79)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line80)"></a> <font color=Green><u>case</u></font> errs <font color=Green><u>of</u></font>+<a name="(line81)"></a> [] <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"internal failure in parser (oneOf'):\n"</font>+<a name="(line82)"></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="(line83)"></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="(line84)"></a> es <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>+<a name="(line85)"></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="(line86)"></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="(line87)"></a> P <font color=Cyan>(</font><font color=Red>\</font>u ts<font color=Red>-></font> <font color=Green><u>case</u></font> p u ts <font color=Green><u>of</u></font>+<a name="(line88)"></a> <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><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="(line89)"></a> <font color=Green><u>in</u></font> p u ts+<a name="(line90)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line91)"></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="(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>s ts<font color=Red>-></font>+<a name="(line93)"></a> <font color=Green><u>case</u></font> pf s ts <font color=Green><u>of</u></font>+<a name="(line94)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line95)"></a> <font color=Cyan>(</font>Right f<font color=Cyan>,</font> s'<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>s''<font color=Cyan>,</font>ts''<font color=Cyan>)</font> <font color=Red>=</font> px s' 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>-></font> x+<a name="(line97)"></a> <font color=Cyan>;</font> Left e <font color=Red>-></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> s''<font color=Cyan>,</font> ts''<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line99)"></a>+<a name="(line100)"></a>+<a name="(line101)"></a><font color=Blue>-- Combinators</font>+<a name="(line102)"></a>+<a name="(line103)"></a><a name="next"></a><font color=Blue>-- | Yield one token.</font>+<a name="(line104)"></a>next <font color=Red>::</font> Parser s t t+<a name="(line105)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>+<a name="(line106)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>,</font> s<font color=Cyan>,</font> []<font color=Cyan>)</font>+<a name="(line107)"></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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line108)"></a>+<a name="(line109)"></a><a name="satisfy"></a><font color=Blue>-- | Yield one token if it satisfies a predicate.</font>+<a name="(line110)"></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 s t t+<a name="(line111)"></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="(line112)"></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="(line113)"></a> <font color=Cyan>}</font>+<a name="(line114)"></a>+<a name="(line115)"></a>+<a name="(line116)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line117)"></a><font color=Blue>-- State handling</font>+<a name="(line118)"></a>+<a name="(line119)"></a><a name="stUpdate"></a><font color=Blue>-- | Update the internal state.</font>+<a name="(line120)"></a>stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t ()+<a name="(line121)"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> f s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line122)"></a>+<a name="(line123)"></a><a name="stQuery"></a><font color=Blue>-- | Query the internal state.</font>+<a name="(line124)"></a>stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a+<a name="(line125)"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line126)"></a>+<a name="(line127)"></a><a name="stGet"></a><font color=Blue>-- | Deliver the entire internal state.</font>+<a name="(line128)"></a>stGet <font color=Red>::</font> Parser s t s+<a name="(line129)"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right s<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line130)"></a>+<a name="(line131)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line132)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line133)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line134)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line135)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line136)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line137)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t ()+<a name="(line138)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line139)"></a>+<a name="(line140)"></a><font color=Blue>------------------------------------------------------------------------</font>+</pre>+</html>
docs/haddock/src/Text/ParserCombinators/PolyLazy.html view
@@ -1,268 +1,279 @@-<pre><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>PolyLazy- <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype.</font>- <font color=Blue>-- $parser</font>- Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad</font>- <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser t a -> [t] -> (a, [t])</font>- <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser t a</font>- <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser t a -> Parser t a</font>- <font color=Blue>-- * Combinators:</font>- <font color=Blue>-- ** Primitives</font>- <font color=Cyan>,</font> next <font color=Blue>-- :: Parser t t</font>- <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser t t</font>- <font color=Cyan>,</font> apply <font color=Blue>-- :: Parser t (a->b) -> Parser t a -> Parser t b</font>- <font color=Cyan>,</font> discard <font color=Blue>-- :: Parser t a -> Parser t b -> Parser t a</font>- <font color=Blue>-- ** Error-handling</font>- <font color=Cyan>,</font> adjustErr <font color=Blue>-- :: Parser t a -> (String->String) -> Parser t a</font>- <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: Parser t a -> (String->String) -> Parser t a</font>- <font color=Cyan>,</font> indent <font color=Blue>-- :: Int -> String -> String</font>- <font color=Blue>-- ** Choices</font>- <font color=Cyan>,</font> onFail <font color=Blue>-- :: Parser t a -> Parser t a -> Parser t a</font>- <font color=Cyan>,</font> oneOf <font color=Blue>-- :: Show t => [Parser t a] -> Parser t a</font>- <font color=Cyan>,</font> oneOf' <font color=Blue>-- :: [(String,Parser t a)] -> Parser t a</font>- <font color=Cyan>,</font> optional <font color=Blue>-- :: Parser t a -> Parser t (Maybe a)</font>- <font color=Blue>-- ** Sequences</font>- <font color=Cyan>,</font> many <font color=Blue>-- :: Parser t a -> Parser t [a]</font>- <font color=Cyan>,</font> many1 <font color=Blue>-- :: Parser t a -> Parser t [a]</font>- <font color=Cyan>,</font> sepBy <font color=Blue>-- :: Parser t a -> Parser t sep -> Parser t [a]</font>- <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: Parser t a -> Parser t sep -> Parser t [a]</font>- <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: Parser t bra -> Parser t sep -> Parser t ket</font>- <font color=Blue>-- -> Parser t a -> Parser t [a]</font>- <font color=Cyan>,</font> bracket <font color=Blue>-- :: Parser t bra -> Parser t ket -> Parser t a</font>- <font color=Blue>-- -> Parser t a</font>- <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser t a -> Parser t z -> Parser t [a]</font>- <font color=Blue>-- ** Re-parsing</font>- <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser t ()</font>- <font color=Cyan>)</font> <font color=Green><u>where</u></font>--<font color=Cyan>#</font><font color=Green><u>if</u></font> <b><font color=Magenta>__GLASGOW_HASKELL__</font></b>-<font color=Green><u>import</u></font> Control<font color=Cyan>.</font>Exception hiding <font color=Cyan>(</font>bracket<font color=Cyan>)</font>-throwE <font color=Red>::</font> String <font color=Red>-></font> a-<a name="throwE"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>-<font color=Cyan>#</font><font color=Green><u>else</u></font>-throwE <font color=Red>::</font> String <font color=Red>-></font> a-throwE msg <font color=Red>=</font> error msg-<font color=Cyan>#</font>endif--<font color=Blue>-- $parser</font>-<font color=Blue>-- When applied, these parsers do not return explicit failure.</font>-<font color=Blue>-- An exception is</font>-<font color=Blue>-- raised instead. This allows partial results to be returned</font>-<font color=Blue>-- before a full parse is complete.</font>-<font color=Blue>-- One of the key ways to ensure that your parser is properly lazy,</font>-<font color=Blue>-- is to parse the initial portion of text returning a function, then</font>-<font color=Blue>-- use the @apply@ combinator to build the final value.</font>--<font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>-<font color=Blue>-- reporting. It can be used for arbitrary token types, not just</font>-<font color=Blue>-- String input. (If you require a running state, use module PolyStateLazy</font>-<font color=Blue>-- instead.)</font>-<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>--<font color=Blue>-- A return type like Either, that distinguishes not only between</font>-<font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>-<font color=Blue>-- Not used in this library. !!!!!!!!!!!!!!!!!!!!!!!!!!!</font>-<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--<font color=Blue>-- | Apply a parser to an input token sequence. The parser cannot return</font>-<font color=Blue>-- an error value explicitly, so errors raise an exception. Thus, results</font>-<font color=Blue>-- can be partial (lazily constructed, but containing undefined).</font>-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="runParser"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Red>=</font>- <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>- <font color=Cyan>.</font> p--<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>- 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>- <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>- <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>-<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>- 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>- <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>- <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>- <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>- 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>--<font color=Blue>-- | Simple failure can be corrected, but when a simple fail is not strong</font>-<font color=Blue>-- enough, use failBad for emphasis. It guarantees parsing will</font>-<font color=Blue>-- terminate with an exception.</font>--failBad <font color=Red>::</font> String <font color=Red>-></font> Parser t a-<a name="failBad"></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>--<font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>-<font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>-<font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>-<font color=Blue>-- they fail hard.</font>-commit <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t a-<a name="commit"></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>- <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>- right <font color=Red>-></font> right <font color=Cyan>)</font>---<font color=Blue>-- Combinators</font>--<font color=Blue>-- | One token</font>-next <font color=Red>::</font> Parser t t-<a name="next"></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>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>,</font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- <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>--<font color=Blue>-- | One token satifying a predicate</font>-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="satisfy"></a>satisfy p <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> x <font color=Red><-</font> next- <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>- <font color=Cyan>}</font>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>-<font color=Blue>-- | Apply a parsed function to a parsed value</font>-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-<font color=Blue>--pf `apply` px = do { f <- pf; x <- px; return (f x) }</font>-<font color=Blue>-- Needs to be lazier! Must not force the argument value too early. </font>-<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>- <font color=Green><u>case</u></font> pf ts <font color=Green><u>of</u></font>- <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>- <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'- 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>- <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>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>-<font color=Blue>-- | @x `discard` y@ parses both x and y, but discards the result of y</font>-discard <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t b <font color=Red>-></font> Parser t 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> <font color=Green><u>_</u></font> <font color=Red><-</font> py<font color=Cyan>;</font> return x <font color=Cyan>}</font>--<font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>-<font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>-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="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>- <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>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>-<font color=Blue>-- severity of the error.</font>-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="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>--<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>-<font color=Blue>-- | @p `onFail` q@ means parse p unless p fails in which case parse q instead.</font>-<font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>-<font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>-<font color=Blue>-- message from that defined in p to something different.)</font>-<font color=Blue>-- However, a *severe* failure in p cannot be ignored.</font>-onFail <font color=Red>::</font> Parser t a <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t 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>- <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- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>-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="oneOf"></a>oneOf <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> n <font color=Red><-</font> next- <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>- <font color=Cyan>}</font>-<font color=Blue>--oneOf :: Show t => [Parser t a] -> Parser t a</font>-<font color=Blue>--oneOf [] = do { n <- next</font>-<font color=Blue>-- ; fail ("failed to parse any of the possible choices"</font>-<font color=Blue>-- ++"\n next token is "++show n)</font>-<font color=Blue>-- }</font>-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--<font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>-<font color=Blue>-- report only the severe errors, and if none of those, then report</font>-<font color=Blue>-- all the soft errors.</font>-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="oneOf'"></a>oneOf' ps <font color=Red>=</font> accum <font color=Red>[</font><font color=Red>]</font> ps- <font color=Green><u>where</u></font> accum errs <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font>- <font color=Green><u>case</u></font> errs <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"internal failure in parser (oneOf'):\n"</font>- <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>- <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- es <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>- <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>- 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>- 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>- <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- <font color=Green><u>in</u></font> p ts- right <font color=Red>-></font> right <font color=Cyan>)</font>- 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--<font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>-indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String-<a name="indent"></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--<font color=Blue>-- | 'optional' indicates whether the parser succeeded through the Maybe type.</font>-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="optional"></a>optional p <font color=Red>=</font> fmap Just p <font color=Cyan>`onFail`</font> return Nothing--<font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>-<font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>-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="many"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items.</font>-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="many1"></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>- <font color=Cyan>;</font> xs <font color=Red><-</font> many p- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>-<font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n\t"++)</font>--<font color=Blue>-- | Parse a list of items separated by discarded junk.</font>-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="sepBy"></a>sepBy p sep <font color=Red>=</font> <font color=Green><u>do</u></font> sepBy1 p sep <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>-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="sepBy1"></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- <font color=Cyan>;</font> xs <font color=Red><-</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>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>- <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>- -<font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>-<font color=Blue>-- items.</font>-bracketSep <font color=Red>::</font> Parser t bra <font color=Red>-></font> Parser t sep <font color=Red>-></font> Parser t ket- <font color=Red>-></font> Parser t a <font color=Red>-></font> Parser t <font color=Red>[</font>a<font color=Red>]</font>-<a name="bracketSep"></a>bracketSep open sep close p <font color=Red>=</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> open<font color=Cyan>;</font> close<font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>- <font color=Cyan>`onFail`</font>- <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>- <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>- <font color=Cyan>;</font> xs <font color=Red><-</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>- <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> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>--<font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>-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="bracket"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>- <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>- <font color=Cyan>;</font> x <font color=Red><-</font> p- <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> return x- <font color=Cyan>}</font>--<font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>-<font color=Blue>-- terminated by a t. Any parse failures could be due either to</font>-<font color=Blue>-- a badly-formed terminator or a badly-formed element, so raise</font>-<font color=Blue>-- both possible errors.</font>-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="manyFinally"></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>- <font color=Green><u>case</u></font> p ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left e<font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font>- <font color=Green><u>case</u></font> t ts <font color=Green><u>of</u></font>- <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=Red>[</font><font color=Red>]</font><font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <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>- <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>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'- <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>--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>-<font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>-<font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>-<font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>-<font color=Blue>-- lexed expansion back down into the parser.</font>-reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser t <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="reparse"></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><font color=Cyan>)</font><font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>+<!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>
docs/haddock/src/Text/ParserCombinators/PolyState.html view
@@ -1,249 +1,261 @@-<pre><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>PolyState- <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>- Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad</font>- <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])</font>- <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser s t a</font>- <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser s t a -> Parser s t a</font>- <font color=Blue>-- * Combinators:</font>- <font color=Blue>-- ** Primitives</font>- <font color=Cyan>,</font> next <font color=Blue>-- :: Parser s t t</font>- <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>- <font color=Cyan>,</font> apply <font color=Blue>-- :: Parser t (a->b) -> Parser s t a -> Parser s t b</font>- <font color=Cyan>,</font> discard <font color=Blue>-- :: Parser s t a -> Parser s t b -> Parser s t a</font>- <font color=Blue>-- ** Error-handling</font>- <font color=Cyan>,</font> adjustErr <font color=Blue>-- :: Parser s t a -> (String->String) -> Parser s t a</font>- <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: Parser s t a -> (String->String) -> Parser s t a</font>- <font color=Cyan>,</font> indent <font color=Blue>-- :: Int -> String -> String</font>- <font color=Blue>-- ** Choices</font>- <font color=Cyan>,</font> onFail <font color=Blue>-- :: Parser s t a -> Parser s t a -> Parser s t a</font>- <font color=Cyan>,</font> oneOf <font color=Blue>-- :: [Parser s t a] -> Parser s t a</font>- <font color=Cyan>,</font> oneOf' <font color=Blue>-- :: [(String, Parser s t a)] -> Parser s t a</font>- <font color=Blue>-- ** Sequences</font>- <font color=Cyan>,</font> many <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>- <font color=Cyan>,</font> many1 <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>- <font color=Cyan>,</font> sepBy <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>- <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>- <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: Parser s t bra -> Parser s t sep -> Parser s t ket</font>- <font color=Blue>-- -> Parser s t a -> Parser s t [a]</font>- <font color=Cyan>,</font> bracket <font color=Blue>-- :: Parser s t bra -> Parser s t ket -> Parser s t a</font>- <font color=Blue>-- -> Parser s t a</font>- <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser s t a -> Parser s t z -> Parser s t [a]</font>- <font color=Blue>-- ** State-handling</font>- <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>- <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>- <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>- <font color=Blue>-- ** Re-parsing</font>- <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s t ()</font>- <font color=Cyan>)</font> <font color=Green><u>where</u></font>--<font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>-<font color=Blue>-- reporting and a running state. It can be used for arbitrary token</font>-<font color=Blue>-- types, not just String input.</font>-<font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>EitherE String a<font color=Cyan>,</font> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | A return type like Either, that distinguishes not only between</font>-<font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>-<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--<font color=Blue>-- | Apply a parser to an initial state and input token sequence.</font>-runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <font color=Red>-></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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>-<a name="runParser"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> s <font color=Red>=</font>- <font color=Cyan>(</font><font color=Red>\</font> <font color=Cyan>(</font>e<font color=Cyan>,</font>s<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> Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>m<font color=Cyan>)</font><font color=Red>-></font>Left m<font color=Cyan>;</font> Right m<font color=Red>-></font>Right m- <font color=Cyan>,</font>s<font color=Cyan>,</font>ts<font color=Cyan>)</font><font color=Cyan>)</font>- <font color=Cyan>.</font> p s--<font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>- 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font><font color=Cyan>)</font>-<font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>- return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>- <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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> f s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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' s' ts'<font color=Cyan>)</font>- fail msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | When a simple fail is not strong enough, use failBad for emphasis.</font>-<font color=Blue>-- An emphasised (severe) error can propagate out through choice operators.</font>-failBad <font color=Red>::</font> String <font color=Red>-></font> Parser s t a-<a name="failBad"></a>failBad msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>-<font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>-<font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>-<font color=Blue>-- they fail hard.</font>-commit <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t a-<a name="commit"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- Combinators</font>--<font color=Blue>-- | One token</font>-next <font color=Red>::</font> Parser s t t-<a name="next"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- <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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>--<font color=Blue>-- | One token satifying a predicate</font>-satisfy <font color=Red>::</font> <font color=Cyan>(</font>t<font color=Red>-></font>Bool<font color=Cyan>)</font> <font color=Red>-></font> Parser s t t-<a name="satisfy"></a>satisfy p <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> x <font color=Red><-</font> next- <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>- <font color=Cyan>}</font>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>-<font color=Blue>-- | Apply a parsed function to a parsed value</font>-apply <font color=Red>::</font> Parser s t <font color=Cyan>(</font>a<font color=Red>-></font>b<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t b-<a name="apply"></a>pf <font color=Cyan>`apply`</font> px <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> f <font color=Red><-</font> pf<font color=Cyan>;</font> x <font color=Red><-</font> px<font color=Cyan>;</font> return <font color=Cyan>(</font>f x<font color=Cyan>)</font> <font color=Cyan>}</font>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>-<font color=Blue>-- | @x `discard` y@ parses both x and y, but discards the result of y</font>-discard <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t b <font color=Red>-></font> Parser s t 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> <font color=Green><u>_</u></font> <font color=Red><-</font> py<font color=Cyan>;</font> return x <font color=Cyan>}</font>--<font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>-<font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>-adjustErr <font color=Red>::</font> Parser s 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 s t 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>-<font color=Blue>-- severity of the error.</font>-adjustErrBad <font color=Red>::</font> Parser s 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 s t a-<font color=Blue>-- p `adjustErrBad` f = commit (p `adjustErr` f)</font>-<a name="adjustErrBad"></a><font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`adjustErrBad`</font> f <font color=Red>=</font>- P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<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>-<font color=Blue>-- | @p `onFail` q@ means parse p unless p fails in which case parse q instead.</font>-<font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>-<font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>-<font color=Blue>-- message from that defined in p to something different.)</font>-<font color=Blue>-- However, a severe failure in p cannot be ignored.</font>-onFail <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- r<font color=Red>@</font><font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r- <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=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> q s ts- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>-oneOf <font color=Red>::</font> <font color=Red>[</font>Parser s t a<font color=Red>]</font> <font color=Red>-></font> Parser s t a-<a name="oneOf"></a>oneOf <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font> fail <font color=Cyan>(</font><font color=Magenta>"Failed to parse any of the possible choices"</font><font color=Cyan>)</font>-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--<font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>-<font color=Blue>-- report only the severe errors, and if none of those, then report</font>-<font color=Blue>-- all the soft errors.</font>-oneOf' <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font> Parser s t a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser s t a-<a name="oneOf'"></a>oneOf' <font color=Red>=</font> accum <font color=Red>[</font><font color=Red>]</font>- <font color=Green><u>where</u></font> accum errs <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font>- <font color=Green><u>case</u></font> filter isBad errs <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>- <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>- <font color=Red>[</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> failBad e- es <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>- <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>- 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>- P <font color=Cyan>(</font><font color=Red>\</font>u ts<font color=Red>-></font> <font color=Green><u>case</u></font> p u ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><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- <font color=Green><u>in</u></font> p u ts- right <font color=Red>-></font> right <font color=Cyan>)</font>- showErr <font color=Cyan>(</font>name<font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>err<font color=Cyan>)</font><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- isBad <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> b--<font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>-indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String-<a name="indent"></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--<font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>-<font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>-many <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="many"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items.</font>-many1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="many1"></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>- <font color=Cyan>;</font> xs <font color=Red><-</font> many p- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>-<font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n"++)</font>--<font color=Blue>-- | Parse a list of items separated by discarded junk.</font>-sepBy <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepBy"></a>sepBy p sep <font color=Red>=</font> <font color=Green><u>do</u></font> sepBy1 p sep <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>-sepBy1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepBy1"></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- <font color=Cyan>;</font> xs <font color=Red><-</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>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>- <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for a non-empty sequence with separators:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- -<font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>-<font color=Blue>-- items.</font>-bracketSep <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t ket- <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="bracketSep"></a>bracketSep open sep close p <font color=Red>=</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> open<font color=Cyan>;</font> close<font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>- <font color=Cyan>`onFail`</font>- <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"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <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"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> xs <font color=Red><-</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>- <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for closing bracket:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>--<font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>-bracket <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t ket <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t a-<a name="bracket"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>- <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"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> x <font color=Red><-</font> p- <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"Missing closing bracket:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> return x- <font color=Cyan>}</font>--<font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>-<font color=Blue>-- terminated by a t. Any parse failures could be due either to</font>-<font color=Blue>-- a badly-formed terminator or a badly-formed element, so raise</font>-<font color=Blue>-- both possible errors.</font>-manyFinally <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t z <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="manyFinally"></a>manyFinally p t <font color=Red>=</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> xs <font color=Red><-</font> many p- <font color=Cyan>;</font> oneOf' <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"sequence terminator"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> t<font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Cyan>)</font> <font color=Cyan>}</font> <font color=Cyan>)</font>- <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"item in a sequence"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> p<font color=Cyan>;</font> return <font color=Cyan>(</font><font color=Cyan>)</font> <font color=Cyan>}</font> <font color=Cyan>)</font>- <font color=Red>]</font>- <font color=Cyan>;</font> return xs- <font color=Cyan>}</font>--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- State handling</font>--<font color=Blue>-- | Update the internal state.</font>-stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="stUpdate"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> f s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Query the internal state.</font>-stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a-<a name="stQuery"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Deliver the entire internal state.</font>-stGet <font color=Red>::</font> Parser s t s-<a name="stGet"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right s<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>-<font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>-<font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>-<font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>-<font color=Blue>-- lexed expansion back down into the parser.</font>-reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="reparse"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>+<!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>PolyState+<a name="(line2)"></a> <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype</font>+<a name="(line3)"></a> Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad</font>+<a name="(line4)"></a> <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])</font>+<a name="(line5)"></a> <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser s t a</font>+<a name="(line6)"></a> <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser s t a -> Parser s t a</font>+<a name="(line7)"></a> <font color=Blue>-- * Combinators:</font>+<a name="(line8)"></a> <font color=Blue>-- ** Primitives</font>+<a name="(line9)"></a> <font color=Cyan>,</font> next <font color=Blue>-- :: Parser s t t</font>+<a name="(line10)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>+<a name="(line11)"></a> <font color=Cyan>,</font> apply <font color=Blue>-- :: Parser t (a->b) -> Parser s t a -> Parser s t b</font>+<a name="(line12)"></a> <font color=Cyan>,</font> discard <font color=Blue>-- :: Parser s t a -> Parser s t b -> Parser s t a</font>+<a name="(line13)"></a> <font color=Blue>-- ** Error-handling</font>+<a name="(line14)"></a> <font color=Cyan>,</font> adjustErr <font color=Blue>-- :: Parser s t a -> (String->String) -> Parser s t a</font>+<a name="(line15)"></a> <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: Parser s t a -> (String->String) -> Parser s t a</font>+<a name="(line16)"></a> <font color=Cyan>,</font> indent <font color=Blue>-- :: Int -> String -> String</font>+<a name="(line17)"></a> <font color=Blue>-- ** Choices</font>+<a name="(line18)"></a> <font color=Cyan>,</font> onFail <font color=Blue>-- :: Parser s t a -> Parser s t a -> Parser s t a</font>+<a name="(line19)"></a> <font color=Cyan>,</font> oneOf <font color=Blue>-- :: [Parser s t a] -> Parser s t a</font>+<a name="(line20)"></a> <font color=Cyan>,</font> oneOf' <font color=Blue>-- :: [(String, Parser s t a)] -> Parser s t a</font>+<a name="(line21)"></a> <font color=Blue>-- ** Sequences</font>+<a name="(line22)"></a> <font color=Cyan>,</font> exactly <font color=Blue>-- :: Int -> Parser s t a -> Parser s t [a]</font>+<a name="(line23)"></a> <font color=Cyan>,</font> many <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>+<a name="(line24)"></a> <font color=Cyan>,</font> many1 <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>+<a name="(line25)"></a> <font color=Cyan>,</font> sepBy <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>+<a name="(line26)"></a> <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>+<a name="(line27)"></a> <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: Parser s t bra -> Parser s t sep -> Parser s t ket</font>+<a name="(line28)"></a> <font color=Blue>-- -> Parser s t a -> Parser s t [a]</font>+<a name="(line29)"></a> <font color=Cyan>,</font> bracket <font color=Blue>-- :: Parser s t bra -> Parser s t ket -> Parser s t a</font>+<a name="(line30)"></a> <font color=Blue>-- -> Parser s t a</font>+<a name="(line31)"></a> <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser s t a -> Parser s t z -> Parser s t [a]</font>+<a name="(line32)"></a> <font color=Blue>-- ** State-handling</font>+<a name="(line33)"></a> <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>+<a name="(line34)"></a> <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>+<a name="(line35)"></a> <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>+<a name="(line36)"></a> <font color=Blue>-- ** Re-parsing</font>+<a name="(line37)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s t ()</font>+<a name="(line38)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line39)"></a>+<a name="(line40)"></a><a name="Parser"></a><font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>+<a name="(line41)"></a><a name="Parser"></a><font color=Blue>-- reporting and a running state. It can be used for arbitrary token</font>+<a name="(line42)"></a><a name="Parser"></a><font color=Blue>-- types, not just String input.</font>+<a name="(line43)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>EitherE String a<font color=Cyan>,</font> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line44)"></a>+<a name="(line45)"></a><a name="EitherE"></a><font color=Blue>-- | A return type like Either, that distinguishes not only between</font>+<a name="(line46)"></a><a name="EitherE"></a><font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>+<a name="(line47)"></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="(line48)"></a>+<a name="(line49)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an initial state and input token sequence.</font>+<a name="(line50)"></a>runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <font color=Red>-></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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>+<a name="(line51)"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> s <font color=Red>=</font>+<a name="(line52)"></a> <font color=Cyan>(</font><font color=Red>\</font> <font color=Cyan>(</font>e<font color=Cyan>,</font>s<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> Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>m<font color=Cyan>)</font><font color=Red>-></font>Left m<font color=Cyan>;</font> Right m<font color=Red>-></font>Right m+<a name="(line53)"></a> <font color=Cyan>,</font>s<font color=Cyan>,</font>ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line54)"></a> <font color=Cyan>.</font> p s+<a name="(line55)"></a>+<a name="(line56)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line57)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line58)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line59)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line60)"></a><font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line61)"></a> return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line62)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> f s ts <font color=Green><u>of</u></font>+<a name="(line63)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line64)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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+<a name="(line65)"></a> <font color=Green><u>in</u></font> g' s' ts'<font color=Cyan>)</font>+<a name="(line66)"></a> fail msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line67)"></a>+<a name="(line68)"></a><a name="failBad"></a><font color=Blue>-- | When a simple fail is not strong enough, use failBad for emphasis.</font>+<a name="(line69)"></a><font color=Blue>-- An emphasised (severe) error can propagate out through choice operators.</font>+<a name="(line70)"></a>failBad <font color=Red>::</font> String <font color=Red>-></font> Parser s t a+<a name="(line71)"></a>failBad msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line72)"></a>+<a name="(line73)"></a><a name="commit"></a><font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>+<a name="(line74)"></a><font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>+<a name="(line75)"></a><font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>+<a name="(line76)"></a><font color=Blue>-- they fail hard.</font>+<a name="(line77)"></a>commit <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t a+<a name="(line78)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line79)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line80)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line81)"></a>+<a name="(line82)"></a><font color=Blue>-- Combinators</font>+<a name="(line83)"></a>+<a name="(line84)"></a><a name="next"></a><font color=Blue>-- | One token</font>+<a name="(line85)"></a>next <font color=Red>::</font> Parser s t t+<a name="(line86)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>+<a name="(line87)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>False<font color=Cyan>,</font><font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> []<font color=Cyan>)</font>+<a name="(line88)"></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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line89)"></a>+<a name="(line90)"></a><a name="satisfy"></a><font color=Blue>-- | One token satifying a predicate</font>+<a name="(line91)"></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 s t t+<a name="(line92)"></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="(line93)"></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="(line94)"></a> <font color=Cyan>}</font>+<a name="(line95)"></a>+<a name="(line96)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>+<a name="(line97)"></a><a name="apply"></a><font color=Blue>-- | Apply a parsed function to a parsed value</font>+<a name="(line98)"></a>apply <font color=Red>::</font> Parser s t <font color=Cyan>(</font>a<font color=Red>-></font>b<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t b+<a name="(line99)"></a><a name="apply"></a>pf <font color=Cyan>`apply`</font> px <font color=Red>=</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> f <font color=Red><-</font> pf<font color=Cyan>;</font> x <font color=Red><-</font> px<font color=Cyan>;</font> return <font color=Cyan>(</font>f x<font color=Cyan>)</font> <font color=Cyan>}</font>+<a name="(line100)"></a>+<a name="(line101)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>+<a name="(line102)"></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="(line103)"></a>discard <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t b <font color=Red>-></font> Parser s t a+<a name="(line104)"></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> <font color=Green><u>_</u></font> <font color=Red><-</font> py<font color=Cyan>;</font> return x <font color=Cyan>}</font>+<a name="(line105)"></a>+<a name="(line106)"></a><a name="adjustErr"></a><font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>+<a name="(line107)"></a><font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>+<a name="(line108)"></a>adjustErr <font color=Red>::</font> Parser s 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 s t a+<a name="(line109)"></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>+<a name="(line110)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line111)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line112)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line113)"></a>+<a name="(line114)"></a><a name="adjustErrBad"></a><font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>+<a name="(line115)"></a><font color=Blue>-- severity of the error.</font>+<a name="(line116)"></a>adjustErrBad <font color=Red>::</font> Parser s 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 s t a+<a name="(line117)"></a><a name="adjustErrBad"></a><font color=Blue>-- p `adjustErrBad` f = commit (p `adjustErr` f)</font>+<a name="(line118)"></a><a name="adjustErrBad"></a><font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`adjustErrBad`</font> f <font color=Red>=</font>+<a name="(line119)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line120)"></a> <font color=Cyan>(</font>Left <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>msg<font color=Cyan>)</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line121)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line122)"></a>+<a name="(line123)"></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="(line124)"></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="(line125)"></a><font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>+<a name="(line126)"></a><font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>+<a name="(line127)"></a><font color=Blue>-- message from that defined in p to something different.)</font>+<a name="(line128)"></a><font color=Blue>-- However, a severe failure in p cannot be ignored.</font>+<a name="(line129)"></a>onFail <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t a+<a name="(line130)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line131)"></a> r<font color=Red>@</font><font color=Cyan>(</font>Left <font color=Cyan>(</font>True<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> r+<a name="(line132)"></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=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> q s ts+<a name="(line133)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line134)"></a>+<a name="(line135)"></a><a name="oneOf"></a><font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>+<a name="(line136)"></a>oneOf <font color=Red>::</font> <font color=Red>[</font>Parser s t a<font color=Red>]</font> <font color=Red>-></font> Parser s t a+<a name="(line137)"></a>oneOf [] <font color=Red>=</font> fail <font color=Cyan>(</font><font color=Magenta>"Failed to parse any of the possible choices"</font><font color=Cyan>)</font>+<a name="(line138)"></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="(line139)"></a>+<a name="(line140)"></a><a name="oneOf'"></a><font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>+<a name="(line141)"></a><font color=Blue>-- report only the severe errors, and if none of those, then report</font>+<a name="(line142)"></a><font color=Blue>-- all the soft errors.</font>+<a name="(line143)"></a>oneOf' <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font> Parser s t a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser s t a+<a name="(line144)"></a>oneOf' <font color=Red>=</font> accum []+<a name="(line145)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line146)"></a> <font color=Green><u>case</u></font> filter isBad errs <font color=Green><u>of</u></font>+<a name="(line147)"></a> [] <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"failed to parse any of the possible choices:\n"</font>+<a name="(line148)"></a> <font color=Cyan>++</font>indent <font color=Magenta>2</font> <font color=Cyan>(</font>concatMap showErr <font color=Cyan>(</font>reverse errs<font color=Cyan>)</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line149)"></a> <font color=Red>[</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>e<font color=Cyan>)</font><font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> failBad e+<a name="(line150)"></a> es <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>+<a name="(line151)"></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="(line152)"></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="(line153)"></a> P <font color=Cyan>(</font><font color=Red>\</font>u ts<font color=Red>-></font> <font color=Green><u>case</u></font> p u ts <font color=Green><u>of</u></font>+<a name="(line154)"></a> <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><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="(line155)"></a> <font color=Green><u>in</u></font> p u ts+<a name="(line156)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line157)"></a> showErr <font color=Cyan>(</font>name<font color=Cyan>,</font><font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font>err<font color=Cyan>)</font><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="(line158)"></a> isBad <font color=Cyan>(</font><font color=Green><u>_</u></font><font color=Cyan>,</font><font color=Cyan>(</font>b<font color=Cyan>,</font><font color=Green><u>_</u></font><font color=Cyan>)</font><font color=Cyan>)</font> <font color=Red>=</font> b+<a name="(line159)"></a>+<a name="(line160)"></a><a name="indent"></a><font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>+<a name="(line161)"></a>indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String+<a name="(line162)"></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="(line163)"></a>+<a name="(line164)"></a><a name="exactly"></a><font color=Blue>-- | 'exactly n p' parses a precise number of items, n, using the parser</font>+<a name="(line165)"></a><font color=Blue>-- p, in sequence.</font>+<a name="(line166)"></a>exactly <font color=Red>::</font> Int <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line167)"></a>exactly <font color=Magenta>0</font> p <font color=Red>=</font> return []+<a name="(line168)"></a>exactly n p <font color=Red>=</font> <font color=Green><u>do</u></font> x <font color=Red><-</font> p+<a name="(line169)"></a> xs <font color=Red><-</font> exactly <font color=Cyan>(</font>n<font color=Blue>-</font><font color=Magenta>1</font><font color=Cyan>)</font> p+<a name="(line170)"></a> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line171)"></a>+<a name="(line172)"></a><a name="many"></a><font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>+<a name="(line173)"></a><font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>+<a name="(line174)"></a>many <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line175)"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return []+<a name="(line176)"></a>+<a name="(line177)"></a><a name="many1"></a><font color=Blue>-- | Parse a non-empty list of items.</font>+<a name="(line178)"></a>many1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line179)"></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="(line180)"></a> <font color=Cyan>;</font> xs <font color=Red><-</font> many p+<a name="(line181)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line182)"></a> <font color=Cyan>}</font>+<a name="(line183)"></a><font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n"++)</font>+<a name="(line184)"></a>+<a name="(line185)"></a><a name="sepBy"></a><font color=Blue>-- | Parse a list of items separated by discarded junk.</font>+<a name="(line186)"></a>sepBy <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line187)"></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="(line188)"></a>+<a name="(line189)"></a><a name="sepBy1"></a><font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>+<a name="(line190)"></a>sepBy1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line191)"></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="(line192)"></a> <font color=Cyan>;</font> xs <font color=Red><-</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="(line193)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line194)"></a> <font color=Cyan>}</font>+<a name="(line195)"></a> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for a non-empty sequence with separators:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line196)"></a> +<a name="(line197)"></a><a name="bracketSep"></a><font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>+<a name="(line198)"></a><font color=Blue>-- items.</font>+<a name="(line199)"></a>bracketSep <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t ket+<a name="(line200)"></a> <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line201)"></a>bracketSep open sep close p <font color=Red>=</font>+<a name="(line202)"></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="(line203)"></a> <font color=Cyan>`onFail`</font>+<a name="(line204)"></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"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line205)"></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"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line206)"></a> <font color=Cyan>;</font> xs <font color=Red><-</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="(line207)"></a> <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for closing bracket:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line208)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line209)"></a> <font color=Cyan>}</font>+<a name="(line210)"></a>+<a name="(line211)"></a><a name="bracket"></a><font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>+<a name="(line212)"></a>bracket <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t ket <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t a+<a name="(line213)"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>+<a name="(line214)"></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"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line215)"></a> <font color=Cyan>;</font> x <font color=Red><-</font> p+<a name="(line216)"></a> <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"Missing closing bracket:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line217)"></a> <font color=Cyan>;</font> return x+<a name="(line218)"></a> <font color=Cyan>}</font>+<a name="(line219)"></a>+<a name="(line220)"></a><a name="manyFinally"></a><font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>+<a name="(line221)"></a><font color=Blue>-- terminated by a t. Any parse failures could be due either to</font>+<a name="(line222)"></a><font color=Blue>-- a badly-formed terminator or a badly-formed element, so raise</font>+<a name="(line223)"></a><font color=Blue>-- both possible errors.</font>+<a name="(line224)"></a>manyFinally <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t z <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line225)"></a>manyFinally p t <font color=Red>=</font>+<a name="(line226)"></a> <font color=Green><u>do</u></font> <font color=Cyan>{</font> xs <font color=Red><-</font> many p+<a name="(line227)"></a> <font color=Cyan>;</font> oneOf' <font color=Red>[</font> <font color=Cyan>(</font><font color=Magenta>"sequence terminator"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> t<font color=Cyan>;</font> return () <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line228)"></a> <font color=Cyan>,</font> <font color=Cyan>(</font><font color=Magenta>"item in a sequence"</font><font color=Cyan>,</font> <font color=Green><u>do</u></font> <font color=Cyan>{</font> p<font color=Cyan>;</font> return () <font color=Cyan>}</font> <font color=Cyan>)</font>+<a name="(line229)"></a> <font color=Red>]</font>+<a name="(line230)"></a> <font color=Cyan>;</font> return xs+<a name="(line231)"></a> <font color=Cyan>}</font>+<a name="(line232)"></a>+<a name="(line233)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line234)"></a><font color=Blue>-- State handling</font>+<a name="(line235)"></a>+<a name="(line236)"></a><a name="stUpdate"></a><font color=Blue>-- | Update the internal state.</font>+<a name="(line237)"></a>stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t ()+<a name="(line238)"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> f s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line239)"></a>+<a name="(line240)"></a><a name="stQuery"></a><font color=Blue>-- | Query the internal state.</font>+<a name="(line241)"></a>stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a+<a name="(line242)"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line243)"></a>+<a name="(line244)"></a><a name="stGet"></a><font color=Blue>-- | Deliver the entire internal state.</font>+<a name="(line245)"></a>stGet <font color=Red>::</font> Parser s t s+<a name="(line246)"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right s<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line247)"></a>+<a name="(line248)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line249)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line250)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line251)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line252)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line253)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line254)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t ()+<a name="(line255)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line256)"></a>+<a name="(line257)"></a><font color=Blue>------------------------------------------------------------------------</font> </pre>+</html>
docs/haddock/src/Text/ParserCombinators/PolyStateLazy.html view
@@ -1,282 +1,294 @@-<pre><font color=Green><u>module</u></font> Text<font color=Cyan>.</font>ParserCombinators<font color=Cyan>.</font>PolyStateLazy- <font color=Cyan>(</font> <font color=Blue>-- * The Parser datatype.</font>- <font color=Blue>-- $parser</font>- Parser<font color=Cyan>(</font>P<font color=Cyan>)</font> <font color=Blue>-- datatype, instance of: Functor, Monad</font>- <font color=Cyan>,</font> runParser <font color=Blue>-- :: Parser s t a -> s -> [t] -> (a, s, [t])</font>- <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser s t a</font>- <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser s t a -> Parser s t a</font>- <font color=Blue>-- * Combinators:</font>- <font color=Blue>-- ** Primitives</font>- <font color=Cyan>,</font> next <font color=Blue>-- :: Parser s t t</font>- <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>- <font color=Cyan>,</font> apply <font color=Blue>-- :: Parser t (a->b) -> Parser s t a -> Parser s t b</font>- <font color=Cyan>,</font> discard <font color=Blue>-- :: Parser s t a -> Parser s t b -> Parser s t a</font>- <font color=Blue>-- ** Error-handling</font>- <font color=Cyan>,</font> adjustErr <font color=Blue>-- :: Parser s t a -> (String->String) -> Parser s t a</font>- <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: Parser s t a -> (String->String) -> Parser s t a</font>- <font color=Cyan>,</font> indent <font color=Blue>-- :: Int -> String -> String</font>- <font color=Blue>-- ** Choices</font>- <font color=Cyan>,</font> onFail <font color=Blue>-- :: Parser s t a -> Parser s t a -> Parser s t a</font>- <font color=Cyan>,</font> oneOf <font color=Blue>-- :: [Parser s t a] -> Parser s t a</font>- <font color=Cyan>,</font> oneOf' <font color=Blue>-- :: [(String, Parser s t a)] -> Parser s t a</font>- <font color=Cyan>,</font> optional <font color=Blue>-- :: Parser s t a -> Parser s t (Maybe a)</font>- <font color=Blue>-- ** Sequences</font>- <font color=Cyan>,</font> many <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>- <font color=Cyan>,</font> many1 <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>- <font color=Cyan>,</font> sepBy <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>- <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>- <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: Parser s t bra -> Parser s t sep -> Parser s t ket</font>- <font color=Blue>-- -> Parser s t a -> Parser s t [a]</font>- <font color=Cyan>,</font> bracket <font color=Blue>-- :: Parser s t bra -> Parser s t ket -> Parser s t a</font>- <font color=Blue>-- -> Parser s t a</font>- <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser s t a -> Parser s t z -> Parser s t [a]</font>- <font color=Blue>-- ** State-handling</font>- <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>- <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>- <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>- <font color=Blue>-- ** Re-parsing</font>- <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s t ()</font>- <font color=Cyan>)</font> <font color=Green><u>where</u></font>--<font color=Cyan>#</font><font color=Green><u>if</u></font> <b><font color=Magenta>__GLASGOW_HASKELL__</font></b>-<font color=Green><u>import</u></font> Control<font color=Cyan>.</font>Exception hiding <font color=Cyan>(</font>bracket<font color=Cyan>)</font>-throwE <font color=Red>::</font> String <font color=Red>-></font> a-<a name="throwE"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>-<font color=Cyan>#</font><font color=Green><u>else</u></font>-throwE <font color=Red>::</font> String <font color=Red>-></font> a-throwE msg <font color=Red>=</font> error msg-<font color=Cyan>#</font>endif--<font color=Blue>-- $parser</font>-<font color=Blue>-- Parsers do not return explicit failure. An exception is raised</font>-<font color=Blue>-- instead. This allows partial results to be returned before a</font>-<font color=Blue>-- full parse is complete.</font>--<font color=Blue>-- | The @Parser@ datatype is a fairly generic parsing monad with error</font>-<font color=Blue>-- reporting and a running state. It can be used for arbitrary token</font>-<font color=Blue>-- types, not just String input.</font>-<font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | A return type like Either, that distinguishes not only between</font>-<font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>-<font color=Blue>-- Not used in this library. !!!!!!!!!!!!!!!!!!!!!!!!!!</font>-<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--<font color=Blue>-- | Apply a parser to an initial state and input token sequence.</font>-<font color=Blue>-- The parser cannot return an error value explicitly, so errors</font>-<font color=Blue>-- raise an exception. Thus, results can be partial (lazily constructed,</font>-<font color=Blue>-- but containing undefined).</font>-runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font>-<a name="runParser"></a>runParser <font color=Cyan>(</font>P p<font color=Cyan>)</font> s <font color=Red>=</font>- <font color=Cyan>(</font><font color=Red>\</font> <font color=Cyan>(</font>e<font color=Cyan>,</font>s<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> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>- <font color=Cyan>.</font> p s--<font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>- 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font><font color=Cyan>)</font>-<font color=Green><u>instance</u></font> Monad <font color=Cyan>(</font>Parser s t<font color=Cyan>)</font> <font color=Green><u>where</u></font>- return x <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>- <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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> f s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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' s' ts'<font color=Cyan>)</font>- fail msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Simple failure can be corrected, but when a simple fail is not strong</font>-<font color=Blue>-- enough, use failBad for emphasis. It guarantees parsing will terminate</font>-<font color=Blue>-- with an exception.</font>-failBad <font color=Red>::</font> String <font color=Red>-></font> Parser s t a-<a name="failBad"></a>failBad msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>throwE msg<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Commit is a way of raising the severity of any errors found within</font>-<font color=Blue>-- its argument. Used in the middle of a parser definition, it means that</font>-<font color=Blue>-- any operations prior to commitment fail softly, but after commitment,</font>-<font color=Blue>-- they fail hard.</font>-commit <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t a-<a name="commit"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>throwE e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- Combinators</font>--<font color=Blue>-- | One token</font>-next <font color=Red>::</font> Parser s t t-<a name="next"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>,</font> s<font color=Cyan>,</font> <font color=Red>[</font><font color=Red>]</font><font color=Cyan>)</font>- <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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>--<font color=Blue>-- | One token satifying a predicate</font>-satisfy <font color=Red>::</font> <font color=Cyan>(</font>t<font color=Red>-></font>Bool<font color=Cyan>)</font> <font color=Red>-></font> Parser s t t-<a name="satisfy"></a>satisfy p <font color=Red>=</font> <font color=Green><u>do</u></font><font color=Cyan>{</font> x <font color=Red><-</font> next- <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>- <font color=Cyan>}</font>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>-<font color=Blue>-- | Apply a parsed function to a parsed value</font>-apply <font color=Red>::</font> Parser s t <font color=Cyan>(</font>a<font color=Red>-></font>b<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t b-<font color=Blue>--pf `apply` px = do { f <- pf; x <- px; return (f x) }</font>-<font color=Blue>-- Needs to be lazier! Must not force the argument value too early.</font>-<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>s ts<font color=Red>-></font>- <font color=Green><u>case</u></font> pf s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <font color=Cyan>(</font>Right f<font color=Cyan>,</font> s'<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>s''<font color=Cyan>,</font>ts''<font color=Cyan>)</font> <font color=Red>=</font> px s' ts'- x <font color=Red>=</font> <font color=Green><u>case</u></font> x' <font color=Green><u>of</u></font>- Right x <font color=Red>-></font> x- Left e <font color=Red>-></font> throwE e- <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> s''<font color=Cyan>,</font> ts''<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>-<font color=Blue>-- | @x `discard` y@ parses both x and y, but discards the result of y</font>-discard <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t b <font color=Red>-></font> Parser s t 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> <font color=Green><u>_</u></font> <font color=Red><-</font> py<font color=Cyan>;</font> return x <font color=Cyan>}</font>--<font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>-<font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>-adjustErr <font color=Red>::</font> Parser s 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 s t 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the</font>-<font color=Blue>-- severity of the error.</font>-adjustErrBad <font color=Red>::</font> Parser s 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 s t a-<font color=Blue>-- p `adjustErrBad` f = commit (p `adjustErr` f)</font>-<a name="adjustErrBad"></a><font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`adjustErrBad`</font> f <font color=Red>=</font>- P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>throwE <font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- right <font color=Red>-></font> right <font color=Cyan>)</font>--<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>-<font color=Blue>-- | @p `onFail` q@ means parse p unless p fails in which case parse q instead.</font>-<font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>-<font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>-<font color=Blue>-- message from that defined in p to something different.)</font>-<font color=Blue>-- However, a *severe* failure in p cannot be ignored.</font>-onFail <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <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=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> q s ts- right <font color=Red>-></font> right <font color=Cyan>)</font>--<font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>-oneOf <font color=Red>::</font> <font color=Red>[</font>Parser s t a<font color=Red>]</font> <font color=Red>-></font> Parser s t a-<a name="oneOf"></a>oneOf <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font> fail <font color=Cyan>(</font><font color=Magenta>"Failed to parse any of the possible choices"</font><font color=Cyan>)</font>-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--<font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>-<font color=Blue>-- report only the severe errors, and if none of those, then report</font>-<font color=Blue>-- all the soft errors.</font>-oneOf' <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font> Parser s t a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser s t a-<a name="oneOf'"></a>oneOf' ps <font color=Red>=</font> accum <font color=Red>[</font><font color=Red>]</font> ps- <font color=Green><u>where</u></font> accum errs <font color=Red>[</font><font color=Red>]</font> <font color=Red>=</font>- <font color=Green><u>case</u></font> errs <font color=Green><u>of</u></font>- <font color=Red>[</font><font color=Red>]</font> <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"internal failure in parser (oneOf'):\n"</font>- <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>- <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- es <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>- <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>- 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>- P <font color=Cyan>(</font><font color=Red>\</font>u ts<font color=Red>-></font> <font color=Green><u>case</u></font> p u ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><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- <font color=Green><u>in</u></font> p u ts- right <font color=Red>-></font> right <font color=Cyan>)</font>- 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--<font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>-indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String-<a name="indent"></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--<font color=Blue>-- | 'optional' indicates whether the parser succeeded through the Maybe type.</font>-optional <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Cyan>(</font>Maybe a<font color=Cyan>)</font>-<a name="optional"></a>optional p <font color=Red>=</font> fmap Just p <font color=Cyan>`onFail`</font> return Nothing--<font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>-<font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>-many <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="many"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items.</font>-many1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="many1"></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>- <font color=Cyan>;</font> xs <font color=Red><-</font> many p- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>-<font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n"++)</font>--<font color=Blue>-- | Parse a list of items separated by discarded junk.</font>-sepBy <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepBy"></a>sepBy p sep <font color=Red>=</font> <font color=Green><u>do</u></font> sepBy1 p sep <font color=Cyan>`onFail`</font> return <font color=Red>[</font><font color=Red>]</font>--<font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>-sepBy1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="sepBy1"></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- <font color=Cyan>;</font> xs <font color=Red><-</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>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>- <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for a non-empty sequence with separators:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- -<font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>-<font color=Blue>-- items.</font>-bracketSep <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t ket- <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="bracketSep"></a>bracketSep open sep close p <font color=Red>=</font>- <font color=Green><u>do</u></font> <font color=Cyan>{</font> open<font color=Cyan>;</font> close<font color=Cyan>;</font> return <font color=Red>[</font><font color=Red>]</font> <font color=Cyan>}</font>- <font color=Cyan>`onFail`</font>- <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"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <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"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> xs <font color=Red><-</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>- <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for closing bracket:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>- <font color=Cyan>}</font>--<font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>-bracket <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t ket <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t a-<a name="bracket"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>- <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"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> x <font color=Red><-</font> p- <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"Missing closing bracket:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>- <font color=Cyan>;</font> return x- <font color=Cyan>}</font>--<font color=Blue>-- | 'manyFinally e t' parses a possibly-empty sequence of e's,</font>-<font color=Blue>-- terminated by a t. Any parse failures could be due either to</font>-<font color=Blue>-- a badly-formed terminator or a badly-formed element, so raise</font>-<font color=Blue>-- both possible errors.</font>-manyFinally <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t z <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>-<a name="manyFinally"></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>s ts <font color=Red>-></font>- <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Left e<font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>,</font> <font color=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font>- <font color=Green><u>case</u></font> t s ts <font color=Green><u>of</u></font>- <font color=Cyan>(</font>Right <font color=Green><u>_</u></font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Red>[</font><font color=Red>]</font><font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>- <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font>- <font color=Green><u>let</u></font> <font color=Cyan>(</font>tail<font color=Cyan>,</font>s''<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> s' ts'- <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> s''<font color=Cyan>,</font> ts''<font color=Cyan>)</font> <font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- State handling</font>--<font color=Blue>-- | Update the internal state.</font>-stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="stUpdate"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> f s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Query the internal state.</font>-stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a-<a name="stQuery"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>-- | Deliver the entire internal state.</font>-stGet <font color=Red>::</font> Parser s t s-<a name="stGet"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right s<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>-<font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>-<font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>-<font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>-<font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>-<font color=Blue>-- lexed expansion back down into the parser.</font>-reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t <font color=Cyan>(</font><font color=Cyan>)</font>-<a name="reparse"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font><font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>--<font color=Blue>------------------------------------------------------------------------</font>+<!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>PolyStateLazy+<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 s t a -> s -> [t] -> (a, s, [t])</font>+<a name="(line6)"></a> <font color=Cyan>,</font> failBad <font color=Blue>-- :: String -> Parser s t a</font>+<a name="(line7)"></a> <font color=Cyan>,</font> commit <font color=Blue>-- :: Parser s t a -> Parser s 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 s t t</font>+<a name="(line11)"></a> <font color=Cyan>,</font> satisfy <font color=Blue>-- :: (t->Bool) -> Parser s t t</font>+<a name="(line12)"></a> <font color=Cyan>,</font> apply <font color=Blue>-- :: Parser t (a->b) -> Parser s t a -> Parser s t b</font>+<a name="(line13)"></a> <font color=Cyan>,</font> discard <font color=Blue>-- :: Parser s t a -> Parser s t b -> Parser s 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 s t a -> (String->String) -> Parser s t a</font>+<a name="(line16)"></a> <font color=Cyan>,</font> adjustErrBad<font color=Blue>-- :: Parser s t a -> (String->String) -> Parser s 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 s t a -> Parser s t a -> Parser s t a</font>+<a name="(line20)"></a> <font color=Cyan>,</font> oneOf <font color=Blue>-- :: [Parser s t a] -> Parser s t a</font>+<a name="(line21)"></a> <font color=Cyan>,</font> oneOf' <font color=Blue>-- :: [(String, Parser s t a)] -> Parser s t a</font>+<a name="(line22)"></a> <font color=Cyan>,</font> optional <font color=Blue>-- :: Parser s t a -> Parser s 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 s t a -> Parser s t [a]</font>+<a name="(line25)"></a> <font color=Cyan>,</font> many <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>+<a name="(line26)"></a> <font color=Cyan>,</font> many1 <font color=Blue>-- :: Parser s t a -> Parser s t [a]</font>+<a name="(line27)"></a> <font color=Cyan>,</font> sepBy <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>+<a name="(line28)"></a> <font color=Cyan>,</font> sepBy1 <font color=Blue>-- :: Parser s t a -> Parser s t sep -> Parser s t [a]</font>+<a name="(line29)"></a> <font color=Cyan>,</font> bracketSep <font color=Blue>-- :: Parser s t bra -> Parser s t sep -> Parser s t ket</font>+<a name="(line30)"></a> <font color=Blue>-- -> Parser s t a -> Parser s t [a]</font>+<a name="(line31)"></a> <font color=Cyan>,</font> bracket <font color=Blue>-- :: Parser s t bra -> Parser s t ket -> Parser s t a</font>+<a name="(line32)"></a> <font color=Blue>-- -> Parser s t a</font>+<a name="(line33)"></a> <font color=Cyan>,</font> manyFinally <font color=Blue>-- :: Parser s t a -> Parser s t z -> Parser s t [a]</font>+<a name="(line34)"></a> <font color=Blue>-- ** State-handling</font>+<a name="(line35)"></a> <font color=Cyan>,</font> stUpdate <font color=Blue>-- :: (s->s) -> Parser s t ()</font>+<a name="(line36)"></a> <font color=Cyan>,</font> stQuery <font color=Blue>-- :: (s->a) -> Parser s t a</font>+<a name="(line37)"></a> <font color=Cyan>,</font> stGet <font color=Blue>-- :: Parser s t s</font>+<a name="(line38)"></a> <font color=Blue>-- ** Re-parsing</font>+<a name="(line39)"></a> <font color=Cyan>,</font> reparse <font color=Blue>-- :: [t] -> Parser s t ()</font>+<a name="(line40)"></a> <font color=Cyan>)</font> <font color=Green><u>where</u></font>+<a name="(line41)"></a>+<a name="(line42)"></a><font color=Magenta><em>#if __GLASGOW_HASKELL__</em></font>+<a name="(line43)"></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="(line44)"></a><a name="throwE"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line45)"></a>throwE msg <font color=Red>=</font> throw <font color=Cyan>(</font>ErrorCall msg<font color=Cyan>)</font>+<a name="(line46)"></a><font color=Magenta><em>#else</em></font>+<a name="(line47)"></a>throwE <font color=Red>::</font> String <font color=Red>-></font> a+<a name="(line48)"></a>throwE msg <font color=Red>=</font> error msg+<a name="(line49)"></a><font color=Magenta><em>#endif</em></font>+<a name="(line50)"></a>+<a name="(line51)"></a><font color=Blue>-- $parser</font>+<a name="(line52)"></a><font color=Blue>-- Parsers do not return explicit failure. An exception is raised</font>+<a name="(line53)"></a><font color=Blue>-- instead. This allows partial results to be returned before a</font>+<a name="(line54)"></a><font color=Blue>-- full parse is complete.</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 and a running state. It can be used for arbitrary token</font>+<a name="(line58)"></a><a name="Parser"></a><font color=Blue>-- types, not just String input.</font>+<a name="(line59)"></a><a name="Parser"></a><font color=Green><u>newtype</u></font> Parser s t a <font color=Red>=</font> P <font color=Cyan>(</font>s <font color=Red>-></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> s<font color=Cyan>,</font> <font color=Red>[</font>t<font color=Red>]</font><font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line60)"></a>+<a name="(line61)"></a><a name="EitherE"></a><font color=Blue>-- | A return type like Either, that distinguishes not only between</font>+<a name="(line62)"></a><a name="EitherE"></a><font color=Blue>-- right and wrong answers, but also had gradations of wrongness.</font>+<a name="(line63)"></a><a name="EitherE"></a><font color=Blue>-- Not used in this library. !!!!!!!!!!!!!!!!!!!!!!!!!!</font>+<a name="(line64)"></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="(line65)"></a>+<a name="(line66)"></a><a name="runParser"></a><font color=Blue>-- | Apply a parser to an initial state and input token sequence.</font>+<a name="(line67)"></a><font color=Blue>-- The parser cannot return an error value explicitly, so errors</font>+<a name="(line68)"></a><font color=Blue>-- raise an exception. Thus, results can be partial (lazily constructed,</font>+<a name="(line69)"></a><font color=Blue>-- but containing undefined).</font>+<a name="(line70)"></a>runParser <font color=Red>::</font> Parser s t a <font color=Red>-></font> s <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> s<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> s <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>s<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> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line73)"></a> <font color=Cyan>.</font> p s+<a name="(line74)"></a>+<a name="(line75)"></a><font color=Green><u>instance</u></font> Functor <font color=Cyan>(</font>Parser s 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line77)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line78)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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> s'<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 s 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>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s<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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> f s ts <font color=Green><u>of</u></font>+<a name="(line82)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line83)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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+<a name="(line84)"></a> <font color=Green><u>in</u></font> g' s' ts'<font color=Cyan>)</font>+<a name="(line85)"></a> fail msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line86)"></a>+<a name="(line87)"></a><a name="failBad"></a><font color=Blue>-- | Simple failure can be corrected, but when a simple fail is not strong</font>+<a name="(line88)"></a><font color=Blue>-- enough, use failBad for emphasis. It guarantees parsing will terminate</font>+<a name="(line89)"></a><font color=Blue>-- with an exception.</font>+<a name="(line90)"></a>failBad <font color=Red>::</font> String <font color=Red>-></font> Parser s t a+<a name="(line91)"></a>failBad msg <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>throwE msg<font color=Cyan>,</font> s<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 s t a <font color=Red>-></font> Parser s 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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line99)"></a> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>throwE e<font color=Cyan>,</font> s'<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><font color=Blue>-- Combinators</font>+<a name="(line103)"></a>+<a name="(line104)"></a><a name="next"></a><font color=Blue>-- | One token</font>+<a name="(line105)"></a>next <font color=Red>::</font> Parser s t t+<a name="(line106)"></a>next <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> ts <font color=Green><u>of</u></font>+<a name="(line107)"></a> [] <font color=Red>-></font> <font color=Cyan>(</font>Left <font color=Magenta>"Ran out of input (EOF)"</font><font color=Cyan>,</font> s<font color=Cyan>,</font> []<font color=Cyan>)</font>+<a name="(line108)"></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> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line109)"></a>+<a name="(line110)"></a><a name="satisfy"></a><font color=Blue>-- | One token satifying a predicate</font>+<a name="(line111)"></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 s t t+<a name="(line112)"></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="(line113)"></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="(line114)"></a> <font color=Cyan>}</font>+<a name="(line115)"></a>+<a name="(line116)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`apply`</font>+<a name="(line117)"></a><a name="apply"></a><font color=Blue>-- | Apply a parsed function to a parsed value</font>+<a name="(line118)"></a>apply <font color=Red>::</font> Parser s t <font color=Cyan>(</font>a<font color=Red>-></font>b<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t b+<a name="(line119)"></a><a name="apply"></a><font color=Blue>--pf `apply` px = do { f <- pf; x <- px; return (f x) }</font>+<a name="(line120)"></a><a name="apply"></a><font color=Blue>-- Needs to be lazier! Must not force the argument value too early.</font>+<a name="(line121)"></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>s ts<font color=Red>-></font>+<a name="(line122)"></a> <font color=Green><u>case</u></font> pf s ts <font color=Green><u>of</u></font>+<a name="(line123)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line124)"></a> <font color=Cyan>(</font>Right f<font color=Cyan>,</font> s'<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>s''<font color=Cyan>,</font>ts''<font color=Cyan>)</font> <font color=Red>=</font> px s' ts'+<a name="(line125)"></a> x <font color=Red>=</font> <font color=Green><u>case</u></font> x' <font color=Green><u>of</u></font>+<a name="(line126)"></a> Right x <font color=Red>-></font> x+<a name="(line127)"></a> Left e <font color=Red>-></font> throwE e+<a name="(line128)"></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> s''<font color=Cyan>,</font> ts''<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line129)"></a>+<a name="(line130)"></a><font color=Green><u>infixl</u></font> <font color=Magenta>3</font> <font color=Cyan>`discard`</font>+<a name="(line131)"></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="(line132)"></a>discard <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t b <font color=Red>-></font> Parser s t a+<a name="(line133)"></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> <font color=Green><u>_</u></font> <font color=Red><-</font> py<font color=Cyan>;</font> return x <font color=Cyan>}</font>+<a name="(line134)"></a>+<a name="(line135)"></a><a name="adjustErr"></a><font color=Blue>-- | @p `adjustErr` f@ applies the transformation @f@ to any error message</font>+<a name="(line136)"></a><font color=Blue>-- generated in @p@, having no effect if @p@ succeeds.</font>+<a name="(line137)"></a>adjustErr <font color=Red>::</font> Parser s 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 s t a+<a name="(line138)"></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>+<a name="(line139)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line140)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<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> s<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 s 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 s t a+<a name="(line146)"></a><a name="adjustErrBad"></a><font color=Blue>-- p `adjustErrBad` f = commit (p `adjustErr` f)</font>+<a name="(line147)"></a><a name="adjustErrBad"></a><font color=Cyan>(</font>P p<font color=Cyan>)</font> <font color=Cyan>`adjustErrBad`</font> f <font color=Red>=</font>+<a name="(line148)"></a> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line149)"></a> <font color=Cyan>(</font>Left msg<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>throwE <font color=Cyan>(</font>f msg<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line150)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line151)"></a>+<a name="(line152)"></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="(line153)"></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="(line154)"></a><font color=Blue>-- Can be chained together to give multiple attempts to parse something.</font>+<a name="(line155)"></a><font color=Blue>-- (Note that q could itself be a failing parser, e.g. to change the error</font>+<a name="(line156)"></a><font color=Blue>-- message from that defined in p to something different.)</font>+<a name="(line157)"></a><font color=Blue>-- However, a *severe* failure in p cannot be ignored.</font>+<a name="(line158)"></a>onFail <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t a+<a name="(line159)"></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>s ts<font color=Red>-></font> <font color=Green><u>case</u></font> p s ts <font color=Green><u>of</u></font>+<a name="(line160)"></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=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font> q s ts+<a name="(line161)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line162)"></a>+<a name="(line163)"></a><a name="oneOf"></a><font color=Blue>-- | Parse the first alternative in the list that succeeds.</font>+<a name="(line164)"></a>oneOf <font color=Red>::</font> <font color=Red>[</font>Parser s t a<font color=Red>]</font> <font color=Red>-></font> Parser s t a+<a name="(line165)"></a>oneOf [] <font color=Red>=</font> fail <font color=Cyan>(</font><font color=Magenta>"Failed to parse any of the possible choices"</font><font color=Cyan>)</font>+<a name="(line166)"></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="(line167)"></a>+<a name="(line168)"></a><a name="oneOf'"></a><font color=Blue>-- | Parse the first alternative that succeeds, but if none succeed,</font>+<a name="(line169)"></a><font color=Blue>-- report only the severe errors, and if none of those, then report</font>+<a name="(line170)"></a><font color=Blue>-- all the soft errors.</font>+<a name="(line171)"></a>oneOf' <font color=Red>::</font> <font color=Red>[</font><font color=Cyan>(</font>String<font color=Cyan>,</font> Parser s t a<font color=Cyan>)</font><font color=Red>]</font> <font color=Red>-></font> Parser s t a+<a name="(line172)"></a>oneOf' ps <font color=Red>=</font> accum [] ps+<a name="(line173)"></a> <font color=Green><u>where</u></font> accum errs [] <font color=Red>=</font>+<a name="(line174)"></a> <font color=Green><u>case</u></font> errs <font color=Green><u>of</u></font>+<a name="(line175)"></a> [] <font color=Red>-></font> failBad <font color=Cyan>(</font><font color=Magenta>"internal failure in parser (oneOf'):\n"</font>+<a name="(line176)"></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="(line177)"></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="(line178)"></a> es <font color=Red>-></font> fail <font color=Cyan>(</font><font color=Magenta>"one of the following failures occurred:\n"</font>+<a name="(line179)"></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="(line180)"></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="(line181)"></a> P <font color=Cyan>(</font><font color=Red>\</font>u ts<font color=Red>-></font> <font color=Green><u>case</u></font> p u ts <font color=Green><u>of</u></font>+<a name="(line182)"></a> <font color=Cyan>(</font>Left err<font color=Cyan>,</font><font color=Green><u>_</u></font><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="(line183)"></a> <font color=Green><u>in</u></font> p u ts+<a name="(line184)"></a> right <font color=Red>-></font> right <font color=Cyan>)</font>+<a name="(line185)"></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="(line186)"></a>+<a name="(line187)"></a><a name="indent"></a><font color=Blue>-- | Helper for formatting error messages: indents all lines by a fixed amount.</font>+<a name="(line188)"></a>indent <font color=Red>::</font> Int <font color=Red>-></font> String <font color=Red>-></font> String+<a name="(line189)"></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="(line190)"></a>+<a name="(line191)"></a><a name="optional"></a><font color=Blue>-- | 'optional' indicates whether the parser succeeded through the Maybe type.</font>+<a name="(line192)"></a>optional <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Cyan>(</font>Maybe a<font color=Cyan>)</font>+<a name="(line193)"></a>optional p <font color=Red>=</font> fmap Just p <font color=Cyan>`onFail`</font> return Nothing+<a name="(line194)"></a>+<a name="(line195)"></a><a name="exactly"></a><font color=Blue>-- | 'exactly n p' parses a precise number of items, n, using the parser</font>+<a name="(line196)"></a><font color=Blue>-- p, in sequence.</font>+<a name="(line197)"></a>exactly <font color=Red>::</font> Int <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line198)"></a>exactly <font color=Magenta>0</font> p <font color=Red>=</font> return []+<a name="(line199)"></a>exactly n p <font color=Red>=</font> <font color=Green><u>do</u></font> x <font color=Red><-</font> p+<a name="(line200)"></a> xs <font color=Red><-</font> exactly <font color=Cyan>(</font>n<font color=Blue>-</font><font color=Magenta>1</font><font color=Cyan>)</font> p+<a name="(line201)"></a> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line202)"></a>+<a name="(line203)"></a><a name="many"></a><font color=Blue>-- | 'many p' parses a list of elements with individual parser p.</font>+<a name="(line204)"></a><font color=Blue>-- Cannot fail, since an empty list is a valid return value.</font>+<a name="(line205)"></a>many <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line206)"></a>many p <font color=Red>=</font> many1 p <font color=Cyan>`onFail`</font> return []+<a name="(line207)"></a>+<a name="(line208)"></a><a name="many1"></a><font color=Blue>-- | Parse a non-empty list of items.</font>+<a name="(line209)"></a>many1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line210)"></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="(line211)"></a> <font color=Cyan>;</font> xs <font color=Red><-</font> many p+<a name="(line212)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line213)"></a> <font color=Cyan>}</font>+<a name="(line214)"></a><font color=Blue>-- `adjustErr` ("When looking for a non-empty sequence:\n"++)</font>+<a name="(line215)"></a>+<a name="(line216)"></a><a name="sepBy"></a><font color=Blue>-- | Parse a list of items separated by discarded junk.</font>+<a name="(line217)"></a>sepBy <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line218)"></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="(line219)"></a>+<a name="(line220)"></a><a name="sepBy1"></a><font color=Blue>-- | Parse a non-empty list of items separated by discarded junk.</font>+<a name="(line221)"></a>sepBy1 <font color=Red>::</font> Parser s t a <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line222)"></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="(line223)"></a> <font color=Cyan>;</font> xs <font color=Red><-</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="(line224)"></a> <font color=Cyan>;</font> return <font color=Cyan>(</font>x<font color=Red><b>:</b></font>xs<font color=Cyan>)</font>+<a name="(line225)"></a> <font color=Cyan>}</font>+<a name="(line226)"></a> <font color=Cyan>`adjustErr`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for a non-empty sequence with separators:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line227)"></a> +<a name="(line228)"></a><a name="bracketSep"></a><font color=Blue>-- | Parse a list of items, discarding the start, end, and separator</font>+<a name="(line229)"></a><font color=Blue>-- items.</font>+<a name="(line230)"></a>bracketSep <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t sep <font color=Red>-></font> Parser s t ket+<a name="(line231)"></a> <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t <font color=Red>[</font>a<font color=Red>]</font>+<a name="(line232)"></a>bracketSep open sep close p <font color=Red>=</font>+<a name="(line233)"></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="(line234)"></a> <font color=Cyan>`onFail`</font>+<a name="(line235)"></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"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line236)"></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"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line237)"></a> <font color=Cyan>;</font> xs <font color=Red><-</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="(line238)"></a> <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"When looking for closing bracket:\n"</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>xs<font color=Cyan>)</font>+<a name="(line240)"></a> <font color=Cyan>}</font>+<a name="(line241)"></a>+<a name="(line242)"></a><a name="bracket"></a><font color=Blue>-- | Parse a bracketed item, discarding the brackets.</font>+<a name="(line243)"></a>bracket <font color=Red>::</font> Parser s t bra <font color=Red>-></font> Parser s t ket <font color=Red>-></font> Parser s t a <font color=Red>-></font> Parser s t a+<a name="(line244)"></a>bracket open close p <font color=Red>=</font> <font color=Green><u>do</u></font>+<a name="(line245)"></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"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line246)"></a> <font color=Cyan>;</font> x <font color=Red><-</font> p+<a name="(line247)"></a> <font color=Cyan>;</font> close <font color=Cyan>`adjustErrBad`</font> <font color=Cyan>(</font><font color=Magenta>"Missing closing bracket:\n"</font><font color=Cyan>++</font><font color=Cyan>)</font>+<a name="(line248)"></a> <font color=Cyan>;</font> return x+<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 s t a <font color=Red>-></font> Parser s t z <font color=Red>-></font> Parser s 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>s ts <font color=Red>-></font>+<a name="(line257)"></a> <font color=Green><u>case</u></font> p s 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=Green><u>_</u></font><font color=Cyan>)</font> <font color=Red>-></font>+<a name="(line259)"></a> <font color=Green><u>case</u></font> t s 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> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Right []<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line261)"></a> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font> <font color=Red>-></font> <font color=Cyan>(</font>Left e<font color=Cyan>,</font> s'<font color=Cyan>,</font> ts'<font color=Cyan>)</font>+<a name="(line262)"></a> <font color=Cyan>(</font>Right x<font color=Cyan>,</font> s'<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>s''<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> s' 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> s''<font color=Cyan>,</font> ts''<font color=Cyan>)</font> <font color=Cyan>)</font>+<a name="(line265)"></a>+<a name="(line266)"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line267)"></a><font color=Blue>-- State handling</font>+<a name="(line268)"></a>+<a name="(line269)"></a><a name="stUpdate"></a><font color=Blue>-- | Update the internal state.</font>+<a name="(line270)"></a>stUpdate <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>s<font color=Cyan>)</font> <font color=Red>-></font> Parser s t ()+<a name="(line271)"></a>stUpdate f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> f s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line272)"></a>+<a name="(line273)"></a><a name="stQuery"></a><font color=Blue>-- | Query the internal state.</font>+<a name="(line274)"></a>stQuery <font color=Red>::</font> <font color=Cyan>(</font>s<font color=Red>-></font>a<font color=Cyan>)</font> <font color=Red>-></font> Parser s t a+<a name="(line275)"></a>stQuery f <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right <font color=Cyan>(</font>f s<font color=Cyan>)</font><font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line276)"></a>+<a name="(line277)"></a><a name="stGet"></a><font color=Blue>-- | Deliver the entire internal state.</font>+<a name="(line278)"></a>stGet <font color=Red>::</font> Parser s t s+<a name="(line279)"></a>stGet <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s ts<font color=Red>-></font> <font color=Cyan>(</font>Right s<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line280)"></a>+<a name="(line281)"></a><a name="reparse"></a><font color=Blue>------------------------------------------------------------------------</font>+<a name="(line282)"></a><font color=Blue>-- | Push some tokens back onto the front of the input stream and reparse.</font>+<a name="(line283)"></a><font color=Blue>-- This is useful e.g. for recursively expanding macros. When the</font>+<a name="(line284)"></a><font color=Blue>-- user-parser recognises a macro use, it can lookup the macro</font>+<a name="(line285)"></a><font color=Blue>-- expansion from the parse state, lex it, and then stuff the</font>+<a name="(line286)"></a><font color=Blue>-- lexed expansion back down into the parser.</font>+<a name="(line287)"></a>reparse <font color=Red>::</font> <font color=Red>[</font>t<font color=Red>]</font> <font color=Red>-></font> Parser s t ()+<a name="(line288)"></a>reparse ts <font color=Red>=</font> P <font color=Cyan>(</font><font color=Red>\</font>s inp<font color=Red>-></font> <font color=Cyan>(</font>Right ()<font color=Cyan>,</font> s<font color=Cyan>,</font> ts<font color=Cyan>++</font>inp<font color=Cyan>)</font><font color=Cyan>)</font>+<a name="(line289)"></a>+<a name="(line290)"></a><font color=Blue>------------------------------------------------------------------------</font> </pre>+</html>
docs/index.html view
@@ -71,6 +71,35 @@ useful for large structures like e.g. XML trees. <li> <b>Text.ParserCombinators.PolyStateLazy</b> combines PolyState and PolyLazy.+<li> <b>Text.ParserCombinators.Poly.Base</b>+ Following on from the basic Poly combinators, it became clear that+ all of the variations share a lot in common, and that many of the+ combinators are indeed implemented identically. To reduce code+ duplication in the library, we now provide a class-based interface+ here. The actual implementations for strict, lazy, and so on, are+ instances of the class, defined in modules at the same level in the+ hierarchy (e.g. T.P.Poly.Lazy etc).+<li> <b>Text.ParserCombinators.Poly.Plain</b>+ The class instance for ordinary, strict, parsers, with arbitrary+ token type.+<li> <b>Text.ParserCombinators.Poly.Lazy</b>+ The class instance for lazy parsers, with arbitrary token type.+<li> <b>Text.ParserCombinators.Poly.State</b>+ The class instance for strict parsers, with arbitrary token type+ and running state.+<li> <b>Text.ParserCombinators.Poly.StateLazy</b>+ The class instance for lazy parsers, with arbitrary token type+ and running state.+<li> <b>Text.ParserCombinators.Poly.Stream</b>+ The class instance for strict parsers, where input tokens arrive+ in a Stream datatype rather than a list.+<li> <b>Text.ParserCombinators.Poly.NoLeak.Plain</b>+ An experimental implementation of strict parsers, attempting to+ avoid a particular space leak associated with the choice+ combinator.+<li> <b>Text.ParserCombinators.Poly.NoLeak.Lazy</b>+<li> <b>Text.ParserCombinators.Poly.NoLeak.State</b>+<li> <b>Text.ParserCombinators.Poly.NoLeak.StateLazy</b> <li> <b>Text.Parse</b> The Text.Read class from Haskell'98 is widely recognised to have many problems. It is inefficient. If a read fails, there is no indication of why. Worst of all, a read failure@@ -105,10 +134,29 @@ time. <p>+The original Hutton/Meijer combinators are described in a very nice+tutorial tech report:+<a href="http://eprints.nottingham.ac.uk/archive/00000237/">NOTTCS-TR-96-4</a>++<p> I wrote some motivation for <tt>Text.Parse</tt> (including simple examples) on my blog a while back. <a href="http://nhc98.blogspot.com/2005/11/replacement-for-read-class.html">Here is the posting.</a> <p>+If you are familiar with the Parsec library, then the key insight for+using PolyParse is that the two libraries' approach to backtracking are+the duals of each another. In Parsec, you must explicitly add a+<tt>try</tt> combinator at any location where backtracking might be+necessary. Users often find this a bit of a black art. In PolyParse+by contrast, all parsers are backtracking unless you explicitly add a+<tt>commit</tt> (or one of its variations). It is easy to tell where to+add a commit point, because you have already parsed enough of a data+structure to know that only one outcome is possible. For instance, if+you are parsing a Haskell value produced by 'show', then as soon as you+have parsed the initial constructor, you know that no other constructor+of that datatype is possible, so you can commit to returning it.++<p> User-contributed documentation for polyparse is on the Haskell wiki at: <a href="http://haskell.org/haskellwiki/Polyparse">http://haskell.org/haskellwiki/Polyparse</a> Please edit the wiki if you discover any nice tricks!@@ -129,7 +177,18 @@ http://www.cs.york.ac.uk/fp/darcs/polyparse</tt> <p>-<b>Released version:</b><br>+<b>Current released version:</b><br>+polyparse-1.1, release date 2007.10.23<br>+By HTTP:+<a href="http://www.cs.york.ac.uk/fp/polyparse-1.1.tar.gz">.tar.gz</a>,+<a href="http://www.cs.york.ac.uk/fp/polyparse-1.1.zip">.zip</a>.+<br>+By FTP: +<a href="ftp://ftp.cs.york.ac.uk/pub/haskell/polyparse/">+ftp://ftp.cs.york.ac.uk/pub/haskell/polyparse/</a>++<p>+<b>Older versions:</b><br> polyparse-1.0, release date 2007.01.26<br> By HTTP: <a href="http://www.cs.york.ac.uk/fp/polyparse-1.0.tar.gz">.tar.gz</a>,@@ -169,12 +228,18 @@ <hr> <center><h3><a name="news">Recent news</a></h3></center> <p>+Version 1.1 much improves the laziness characteristics of the Poly*+combinators. There are also a lot of new implementations of the Poly*+parser types, all of which attempt to preserve exactly the same+combinator interface, so it is easy to switch between them.++<p> Version 1.00 is the first release of polyparse as a separate package. It was previously part of the HaXml suite. HaXml continues to use polyparse, but polyparse will be useful more widely. If you are looking for examples of the usage of polyparse, the implementations of-Text.XML.HaXml.Parse and Text.XML.HaXml.XmlContent are two good places-to look.+Text.XML.HaXml.Parse, Text.XML.HaXml.ParseLazy, and+Text.XML.HaXml.XmlContent are good places to look. <br> <a href="changelog.html">Complete Changelog</a><br>@@ -207,27 +272,32 @@ <ul> <li> Parser combinators have a long history in Haskell. The first(?) monadic-combinator tutorial was introduced by Hutton and Meijer in 1994, and the-accompanying library was distributed with Gofer (a precursor to Hugs),-and known simply as ParseLib. That library lives on here as-Text.ParserCombinators.HuttonMeijer.+combinator tutorial was introduced by+<a href="http://eprints.nottingham.ac.uk/archive/00000237/">Hutton and+Meijer</a> in 1996, and the accompanying library was distributed with+Gofer (a precursor to Hugs), and known simply as ParseLib. That library+lives on here as Text.ParserCombinators.HuttonMeijer. -<li>Niklas Rojemo's combinators.-The parser combinators developed and used in the implementation of the-nhc98 compiler are monadic and space-efficient. However, they do not-use the standard do-notation, because in fact they are more general than-the standard monad category.+<li>+<a href="http://www.cs.chalmers.se/~rojemo/thesis.html">Niklas Rojemo's+combinators.</a> The parser combinators developed and used in the+implementation of the nhc98 compiler are monadic and space-efficient.+However, they do not use the standard do-notation, because in fact they+are more general than the standard monad category. -<li>Daan Leijen's parsec.-The parsec library is widely used, since it is distributed with ghc.-Its combinators are fairly robust, but you need to place explicit-backtracking into your parsers, using the <tt>try</tt> operator. This-can be tricky.+<li>+<a href="http://research.microsoft.com/~emeijer/Papers/Parsec.pdf">+Daan Leijen's parsec.</a> The parsec library is widely used, since it is+distributed with ghc. Its combinators are fairly robust, but you need+to place explicit backtracking into your parsers, using the <tt>try</tt>+operator. This can be tricky. -<li>Doaitse Swierstra's UU_Parse.+<li><a href="http://www.cs.uu.nl/wiki/HUT/ParserCombinators">Doaitse+Swierstra's UU_Parse.</a> An all-singing, all-dancing parsing library. Deeply sophisticated.+Allows on-line results, which is closely related to lazy parsing. -<li>Koen Claessen's ReadP.+<li><a href="http://cvs.haskell.org/Hugs/pages/libraries/base/Text-ParserCombinators-ReadP.html">Koen Claessen's ReadP.</a> This is a different proposed replacement for the standard Haskell'98 Read class. It is a whole lot more efficient that Read, but because it is also API-compatible with Read, that unfortunately means it suffers
polyparse.cabal view
@@ -1,7 +1,8 @@ name: polyparse-version: 1.0-ghc-options: -DVERSION="1.0"-cc-options: -DVERSION="1.0"+version: 1.1+ghc-options: -DVERSION="1.1"+cc-options: -DVERSION="1.1"+nhc98-options: -K6M license: LGPL license-file: COPYRIGHT author: Malcolm Wallace <Malcolm.Wallace@cs.york.ac.uk>@@ -23,7 +24,16 @@ Text.ParserCombinators.PolyState, Text.ParserCombinators.PolyLazy, Text.ParserCombinators.PolyStateLazy,+ Text.ParserCombinators.Poly.Base,+ Text.ParserCombinators.Poly.Plain,+ Text.ParserCombinators.Poly.Lazy,+ Text.ParserCombinators.Poly.State,+ Text.ParserCombinators.Poly.StateLazy,+ Text.ParserCombinators.Poly.NoLeak.Plain,+ Text.ParserCombinators.Poly.NoLeak.State,+ Text.ParserCombinators.Poly.NoLeak.Lazy,+ Text.ParserCombinators.Poly.NoLeak.StateLazy, Text.Parse-hs-source-dirs: src+hs-source-dir: src build-depends: base, haskell98 extensions: CPP
src/Makefile view
@@ -1,5 +1,5 @@ SOFTWARE = polyparse-VERSION = 1.0+VERSION = 1.1 LIBSRCS = \ Text/ParserCombinators/HuttonMeijer.hs \@@ -8,6 +8,15 @@ Text/ParserCombinators/PolyState.hs \ Text/ParserCombinators/PolyLazy.hs \ Text/ParserCombinators/PolyStateLazy.hs \+ Text/ParserCombinators/Poly/Base.hs \+ Text/ParserCombinators/Poly/Plain.hs \+ Text/ParserCombinators/Poly/Lazy.hs \+ Text/ParserCombinators/Poly/State.hs \+ Text/ParserCombinators/Poly/StateLazy.hs \+ Text/ParserCombinators/Poly/NoLeak/Plain.hs \+ Text/ParserCombinators/Poly/NoLeak/Lazy.hs \+ Text/ParserCombinators/Poly/NoLeak/State.hs \+ Text/ParserCombinators/Poly/NoLeak/StateLazy.hs \ Text/Parse.hs \ LIBOBJS = $(patsubst %.hs, %.o, $(LIBSRCS))
src/Text/ParserCombinators/HuttonMeijerWallace.hs view
@@ -29,7 +29,7 @@ -- | This library of monadic parser combinators is based on the ones -- defined by Graham Hutton and Erik Meijer. It has been extended by -- Malcolm Wallace to use an abstract token type (no longer just a--- string) as input, and to incorporate a State Transformer monad, useful+-- string) as input, and to incorporate state in the monad, useful -- for symbol tables, macros, and so on. Basic facilities for error -- reporting have also been added, and later extended by Graham Klyne -- to return the errors through an @Either@ type, rather than just
src/Text/ParserCombinators/Poly.hs view
@@ -21,6 +21,7 @@ , oneOf' -- :: [(String,Parser t a)] -> Parser t a , optional -- :: Parser t a -> Parser t (Maybe a) -- ** Sequences+ , exactly -- :: Int -> Parser t a -> Parser t [a] , many -- :: Parser t a -> Parser t [a] , many1 -- :: Parser t a -> Parser t [a] , sepBy -- :: Parser t a -> Parser t sep -> Parser t [a]@@ -42,7 +43,7 @@ newtype Parser t a = P ([t] -> (EitherE String a, [t])) -- A return type like Either, that distinguishes not only between--- right and wrong answers, but also had gradations of wrongness.+-- right and wrong answers, but also has gradations of wrongness. type EitherE a b = Either (Bool,a) b -- | Apply a parser to an input token sequence.@@ -164,6 +165,14 @@ -- | 'optional' indicates whether the parser succeeded through the Maybe type. optional :: Parser t a -> Parser t (Maybe a) optional p = fmap Just p `onFail` return Nothing++-- | 'exactly n p' parses a precise number of items, n, using the parser+-- p, in sequence.+exactly :: Int -> Parser t a -> Parser t [a]+exactly 0 p = return []+exactly n p = do x <- p+ xs <- exactly (n-1) p+ return (x:xs) -- | 'many p' parses a list of elements with individual parser p. -- Cannot fail, since an empty list is a valid return value.
+ src/Text/ParserCombinators/Poly/Base.hs view
@@ -0,0 +1,190 @@+module Text.ParserCombinators.Poly.Base+ ( -- * The PolyParse class+ PolyParse(..) -- class of all monadic two-level-error parsers++ -- * Combinators general to all parser types.+ -- ** Simple combinators+ , discard -- :: PolyParse p => p a -> p b -> p a+ -- ** Error-handling+ , failBad -- :: PolyParse p => String -> p a+ , adjustErrBad-- :: PolyParse p => p a -> (String->String) -> p a+ , indent -- :: Int -> String -> String+ -- ** Choices+ , oneOf -- :: PolyParse p => [p a] -> p a+ , optional -- :: PolyParse p => p a -> p (Maybe a)+ -- ** Sequences+ , exactly -- :: PolyParse p => Int -> p a -> p [a]+ , many -- :: PolyParse p => p a -> p [a]+ , many1 -- :: PolyParse p => p a -> p [a]+ , sepBy -- :: PolyParse p => p a -> p sep -> p [a]+ , sepBy1 -- :: PolyParse p => p a -> p sep -> p [a]+ , bracketSep -- :: PolyParse p => p bra -> p sep -> p ket -> p a -> p [a]+ , bracket -- :: PolyParse p => p bra -> p ket -> p a -> p a+ , manyFinally -- :: PolyParse p => p a -> p z -> p [a]+ ) where++-- | The @PolyParse@ class is an abstraction over all the current+-- concrete representations of monadic parser combinators in this+-- package. The common feature is two-level error-handling.+-- Some primitives must be implemented specific to each parser type+-- (e.g. depending on whether the parser has a running state, or+-- whether it is lazy). But given those primitives, large numbers of+-- combinators do not depend any further on the internal structure of+-- the particular parser.+--+-- There are two additional basic combinators that we expect to be implemented+-- afresh for every concrete type, but which (for technical reasons)+-- cannot be class methods. They are @next@ and @satisfy@.+class (Functor p, Monad p) => PolyParse p where+ -- | Commit is a way of raising the severity of any errors found within+ -- its argument. Used in the middle of a parser definition, it means that+ -- any operations prior to commitment fail softly, but after commitment,+ -- they fail hard.+ commit :: p a -> p a+ -- | @p `adjustErr` f@ applies the transformation @f@ to any error message+ -- generated in @p@, having no effect if @p@ succeeds.+ adjustErr :: p a -> (String -> String) -> p a+ -- | @p `onFail` q@ means parse p, unless p fails, in which case+ -- parse q instead.+ -- Can be chained together to give multiple attempts to parse something.+ -- (Note that q could itself be a failing parser, e.g. to change the error+ -- message from that defined in p to something different.)+ -- However, a severe failure in p cannot be ignored.+ onFail :: p a -> p a -> p a+ -- | Parse the first alternative that succeeds, but if none succeed,+ -- report only the severe errors, and if none of those, then report+ -- all the soft errors.+ oneOf' :: [(String, p a)] -> p a+ -- | Apply a parsed function to a parsed value.+ -- Rather like ordinary function application lifted into parsers.+ apply :: p (a->b) -> p a -> p b+ pf `apply` px = do { f <- pf; x <- px; return (f x) }+ -- note: the Poly.Lazy variants override this defn with a lazier one.++infixl 6 `onFail` -- not sure about precedence 6?+infixl 3 `apply`+infixl 3 `discard`++{-+-- Combinators we expect most concrete parser types to implement.+-- For technical reasons, they cannot be class members.++-- | Yield the next token+next :: PolyParse p => p t+ -- where t is constrained to be the input token type++-- | One token satisfying a predicate.+satisfy :: PolyParse p => (t->Bool) -> p t t+satisfy p = do{ x <- next+ ; if p x then return x else fail "Parse.satisfy: failed"+ }+ -- note: must be re-defined for each implementation because+ -- its type cannot be expressed otherwise.+-}++-- | When a simple fail is not strong enough, use failBad for emphasis.+-- An emphasised (severe) error cannot be overridden by choice+-- operators.+failBad :: PolyParse p => String -> p a+failBad e = commit (fail e)++-- | @x `discard` y@ parses both x and y, but discards the result of y.+-- Rather like @const@ lifted into parsers.+discard :: PolyParse p => p a -> p b -> p a+px `discard` py = do { x <- px; return (const x) `apply` py; }++-- | @adjustErrBad@ is just like @adjustErr@ except it also raises the+-- severity of the error.+adjustErrBad :: PolyParse p => p a -> (String->String) -> p a+p `adjustErrBad` f = commit (p `adjustErr` f)++-- | Parse the first alternative in the list that succeeds.+oneOf :: PolyParse p => [p a] -> p a+oneOf [] = fail ("failed to parse any of the possible choices")+oneOf (p:ps) = p `onFail` oneOf ps+--oneOf :: Show t => [Parser t a] -> Parser t a+--oneOf [] = do { n <- next+-- ; fail ("failed to parse any of the possible choices"+-- ++"\n next token is "++show n)+-- }+--oneOf (p:ps) = p `onFail` oneOf ps++-- | Helper for formatting error messages: indents all lines by a fixed amount.+indent :: Int -> String -> String+indent n = unlines . map (replicate n ' ' ++) . lines++-- | 'optional' indicates whether the parser succeeded through the Maybe type.+optional :: PolyParse p => p a -> p (Maybe a)+optional p = fmap Just p `onFail` return Nothing++-- | 'exactly n p' parses precisely n items, using the parser p, in sequence.+exactly :: PolyParse p => Int -> p a -> p [a]+exactly 0 p = return []+exactly n p = return (:) `apply` (p `adjustErr` (("When expecting exactly "+ ++show n++" more items")++))+ `apply` exactly (n-1) p++-- | 'many p' parses a list of elements with individual parser p.+-- Cannot fail, since an empty list is a valid return value.+many :: PolyParse p => p a -> p [a]+many p = many1 p `onFail` return []++-- | Parse a non-empty list of items.+many1 :: PolyParse p => p a -> p [a]+many1 p = do { x <- p `adjustErr` (("In a sequence:\n"++). indent 2)+ ; return (x:) `apply` many p+ }+-- `adjustErr` ("When looking for a non-empty sequence:\n\t"++)++-- | Parse a list of items separated by discarded junk.+sepBy :: PolyParse p => p a -> p sep -> p [a]+sepBy p sep = do sepBy1 p sep `onFail` return []++-- | Parse a non-empty list of items separated by discarded junk.+sepBy1 :: PolyParse p => p a -> p sep -> p [a]+sepBy1 p sep = do { x <- p+ ; return (x:) `apply` many (do {sep; p})+ }+ `adjustErr` ("When looking for a non-empty sequence with separators:\n\t"++)+ +-- | Parse a list of items, discarding the start, end, and separator+-- items.+bracketSep :: PolyParse p => p bra -> p sep -> p ket -> p a -> p [a]+bracketSep open sep close p =+ do { open; close; return [] }+ `onFail`+ do { open `adjustErr` ("Missing opening bracket:\n\t"++)+ ; x <- p `adjustErr` ("After first bracket in a group:\n\t"++)+ ; return (x:)+ `apply` manyFinally (do {sep; p})+ (close `adjustErrBad` ("When looking for closing bracket:\n\t"++))+ }++-- | Parse a bracketed item, discarding the brackets.+bracket :: PolyParse p => p bra -> p ket -> p a -> p a+bracket open close p = do+ do { open `adjustErr` ("Missing opening bracket:\n\t"++)+ ; p `discard` (close `adjustErrBad` ("Missing closing bracket:\n\t"++))+ }++-- | 'manyFinally e t' parses a possibly-empty sequence of e's,+-- terminated by a t. The final t is discarded. Any parse failures+-- could be due either to a badly-formed terminator or a badly-formed+-- element, so it raises both possible errors.+manyFinally :: PolyParse p => p a -> p z -> p [a]+manyFinally p t =+ (many p `discard` t)+ `onFail`+ oneOf' [ ("sequence terminator", do { t; return [] } )+ , ("item in a sequence", do { p; return [] } )+ ]+{-+manyFinally p t =+ do { xs <- many p+ ; oneOf' [ ("sequence terminator", do { t; return () } )+ , ("item in a sequence", do { p; return () } )+ ]+ ; return xs+ }+-}+------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/Lazy.hs view
@@ -0,0 +1,136 @@+module Text.ParserCombinators.Poly.Lazy+ ( -- * The Parser datatype.+ -- $parser+ Parser(P) -- datatype, instance of: Functor, Monad+ , runParser -- :: Parser t a -> [t] -> (a, [t])+ -- ** basic parsers+ , next -- :: Parser t t+ , satisfy -- :: (t->Bool) -> Parser t t+ -- one defn from 'Base' is overridden here, because it depends+ -- on the representation of the Lazy parser monad+ , manyFinally -- :: Parser t a -> Parser t z -> Parser t [a]+ -- ** Re-parsing+ , reparse -- :: [t] -> Parser t ()+ -- * Re-export all more general combinators+ , module Text.ParserCombinators.Poly.Base+ ) where++import Text.ParserCombinators.Poly.Base hiding ( manyFinally )++#if __GLASGOW_HASKELL__+import Control.Exception hiding (bracket)+throwE :: String -> a+throwE msg = throw (ErrorCall msg)+#else+throwE :: String -> a+throwE msg = error msg+#endif++-- $parser+-- When applied, these parsers do not return explicit failure.+-- An exception is+-- raised instead. This allows partial results to be returned+-- before a full parse is complete.+-- One of the key ways to ensure that your parser is properly lazy,+-- is to parse the initial portion of text returning a function, then+-- use the @apply@ combinator to build the final value.++-- | The @Parser@ datatype is a fairly generic parsing monad with error+-- reporting. It can be used for arbitrary token types, not just+-- String input. (If you require a running state, use module PolyStateLazy+-- instead.)+newtype Parser t a = P ([t] -> (Either String a, [t]))++-- | Apply a parser to an input token sequence. The parser cannot return+-- an error value explicitly, so errors raise an exception. Thus, results+-- can be partial (lazily constructed, but containing undefined).+runParser :: Parser t a -> [t] -> (a, [t])+runParser (P p) =+ (\ (e,ts)-> (case e of {Left m->throwE m; Right x->x}, ts) )+ . p++instance Functor (Parser t) where+ fmap f (P p) = P (\ts-> case p ts of+ (Left msg, ts') -> (Left msg, ts')+ (Right x, ts') -> (Right (f x), ts'))+instance Monad (Parser t) where+ return x = P (\ts-> (Right x, ts))+ (P f) >>= g = P (\ts-> case f ts of+ (Left msg, ts') -> (Left msg, ts')+ (Right x, ts') -> let (P g') = g x in g' ts')+ fail e = P (\ts-> (Left e, ts))+++instance PolyParse (Parser t) where+ commit (P p) = P (\ts-> case p ts of+ (Left e, ts') -> (throwE e, ts')+ right -> right )+ (P p) `onFail` (P q) = P (\ts-> case p ts of+ (Left _, _) -> q ts+ right -> right )+ (P p) `adjustErr` f = P (\ts-> case p ts of+ (Left msg, ts') -> (Left (f msg), ts')+ right -> right )+ oneOf' ps = accum [] ps+ where accum errs [] =+ case errs of+ [] -> failBad ("internal failure in parser (oneOf'):\n"+ ++indent 2 (show (map fst ps)))+ [(_,e)] -> fail e+ es -> fail ("one of the following failures occurred:\n"+ ++indent 2 (concatMap showErr (reverse es)))+ accum errs ((e,P p):ps) =+ P (\ts-> case p ts of+ (Left err,_) -> let (P p) = accum ((e,err):errs) ps+ in p ts+ right -> right )+ showErr (name,err) = name++":\n"++indent 2 err+ -- This version of "apply"+ -- is strict in the result of the function parser, but+ -- lazy in the result of the argument parser. (Argument laziness is+ -- the distinctive feature over other implementations.)+ (P pf) `apply` (P px) = P (\ts->+ case pf ts of+ (Left msg, ts') -> (Left msg, ts')+ (Right f, ts') -> let (x',ts'') = px ts'+ x = case x' of { Right x -> x+ ; Left e -> throwE e }+ in (Right (f x), ts'') )++-- | Next token+next = P (\ts-> case ts of+ [] -> (Left "Ran out of input (EOF)", [])+ (t:ts') -> (Right t, ts') )++-- | One token satifying a predicate+satisfy :: (t->Bool) -> Parser t t+satisfy p = do{ x <- next+ ; if p x then return x else fail "Parse.satisfy: failed"+ }++-- | 'manyFinally e t' parses a possibly-empty sequence of e's,+-- terminated by a t. Any parse failures could be due either to+-- a badly-formed terminator or a badly-formed element, so raise+-- both possible errors.+manyFinally :: Parser t a -> Parser t z -> Parser t [a]+manyFinally pp@(P p) pt@(P t) = P (\ts ->+ case p ts of+ (Left e, _) ->+ case t ts of+ (Right _, ts') -> (Right [], ts')+ (Left e, ts') -> (Left e, ts')+ (Right x, ts') ->+ let (tail,ts'') = runParser (manyFinally pp pt) ts'+ in (Right (x:tail), ts'') )+++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser t ()+reparse ts = P (\inp-> (Right (), ts++inp))++------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/NoLeak/Lazy.hs view
@@ -0,0 +1,126 @@+module Text.ParserCombinators.Poly.NoLeak.Lazy+ ( -- * The Parser datatype+ Parser(P) -- datatype, instance of: Functor, Monad, PolyParse+ , runParser -- :: Parser t a -> [t] -> (Either String a, [t])+ -- ** basic parsers+ , next -- :: Parser t t+ , satisfy -- :: (t->Bool) -> Parser t t++ -- ** re-parsing+ , reparse -- :: [t] -> Parser t ()+ -- * Re-export all more general combinators+ , module Text.ParserCombinators.Poly.Base+ ) where+++import Text.ParserCombinators.Poly.Base++#if __GLASGOW_HASKELL__+import Control.Exception hiding (bracket)+throwE :: String -> a+throwE msg = throw (ErrorCall msg)+#else+throwE :: String -> a+throwE msg = error msg+#endif+++-- | This @Parser@ datatype is a fairly generic parsing monad with error+-- reporting. It can be used for arbitrary token types, not just+-- String input. (If you require a running state, use module PolyState+-- instead)+newtype Parser t a = P ([t] -> Result [t] a)++-- A return type like Either, that distinguishes not only between+-- right and wrong answers, but also has gradations of wrongness.+data Result z a = Success z a+ | Failure z String+ | Committed (Result z a) -- still needed++instance Functor (Result z) where+ fmap f (Success z a) = Success z (f a)+ fmap f (Failure z e) = Failure z e+ fmap f (Committed r) = Committed (fmap f r)++-- | Apply a parser to an input token sequence.+runParser :: Parser t a -> [t] -> (a, [t])+runParser (P p) = fromResult . p+ where+ fromResult :: Result z a -> (a, z)+ fromResult (Success z a) = (a, z)+ fromResult (Failure z e) = throwE e+ fromResult (Committed r) = fromResult r++instance Functor (Parser t) where+ fmap f (P p) = P (fmap f . p)++instance Monad (Parser t) where+ return x = P (\ts-> Success ts x)+ fail e = P (\ts-> Failure ts e)+ (P f) >>= g = P (continue . f)+ where+ continue (Success ts x) = let (P g') = g x in g' ts+ continue (Committed (Committed r)) = continue (Committed r)+ continue (Committed r) = Committed (continue r)+ continue (Failure ts e) = Failure ts e++instance PolyParse (Parser t) where+ commit (P p) = P (Committed . p)+ (P p) `adjustErr` f = P (adjust . p)+ where+ adjust (Failure z e) = Failure z (f e)+ adjust (Committed r) = Committed (adjust r)+ adjust good = good++ (P p) `onFail` (P q) = P (\ts-> continue ts $ p ts)+ where+ continue ts (Failure z e) = q ts+ -- continue _ (Committed r) = r -- no, remain Committed+ continue _ r = r++ oneOf' = accum []+ where accum errs [] =+ fail ("failed to parse any of the possible choices:\n"+ ++indent 2 (concatMap showErr (reverse errs)))+ accum errs ((e,P p):ps) =+ P (\ts-> case p ts of+ Failure _ err ->+ let (P p) = accum ((e,err):errs) ps+ in p ts+ r@(Success z a) -> r+ r@(Committed _) -> r )+ showErr (name,err) = name++":\n"++indent 2 err++ -- Apply a parsed function to a parsed value. This version+ -- is strict in the result of the function parser, but+ -- lazy in the result of the argument parser. (Argument laziness is+ -- the distinctive feature over other implementations.)+ (P pf) `apply` px = P (continue . pf)+ where+ continue (Success z f) = let (x,z') = runParser px z+ in Success z' (f x)+ continue (Committed r) = Committed (continue r)+ continue (Failure z e) = Failure z e+++------------------------------------------------------------------------+next :: Parser t t+next = P (\ts-> case ts of+ [] -> Failure [] "Ran out of input (EOF)"+ (t:ts') -> Success ts' t )++satisfy :: (t->Bool) -> Parser t t+satisfy pred = do { x <- next+ ; if pred x then return x else fail "Parse.satisfy: failed"+ }++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser t ()+reparse ts = P (\inp-> Success (ts++inp) ())++------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/NoLeak/Plain.hs view
@@ -0,0 +1,105 @@+module Text.ParserCombinators.Poly.NoLeak.Plain+ ( -- * The Parser datatype+ Parser(P) -- datatype, instance of: Functor, Monad, PolyParse+ , runParser -- :: Parser t a -> [t] -> (Either String a, [t])+ -- ** basic parsers+ , next -- :: Parser t t+ , satisfy -- :: (t->Bool) -> Parser t t++ -- ** re-parsing+ , reparse -- :: [t] -> Parser t ()+ -- * Re-export all more general combinators+ , module Text.ParserCombinators.Poly.Base+ ) where+++import Text.ParserCombinators.Poly.Base++-- | This @Parser@ datatype is a fairly generic parsing monad with error+-- reporting. It can be used for arbitrary token types, not just+-- String input. (If you require a running state, use module PolyState+-- instead)+newtype Parser t a = P ([t] -> Result [t] a)++-- A return type like Either, that distinguishes not only between+-- right and wrong answers, but also has commitment, so that a failure+-- cannot be undone.+data Result z a = Success z a+ | Failure z String+ | Committed (Result z a)++instance Functor (Result z) where+ fmap f (Success z a) = Success z (f a)+ fmap f (Failure z e) = Failure z e+ fmap f (Committed r) = Committed (fmap f r)++-- | Apply a parser to an input token sequence.+runParser :: Parser t a -> [t] -> (Either String a, [t])+runParser (P p) = resultToEither . p+ where+ resultToEither :: Result z a -> (Either String a, z)+ resultToEither (Success z a) = (Right a, z)+ resultToEither (Failure z e) = (Left e, z)+ resultToEither (Committed r) = resultToEither r++instance Functor (Parser t) where+ fmap f (P p) = P (fmap f . p)++instance Monad (Parser t) where+ return x = P (\ts-> Success ts x)+ fail e = P (\ts-> Failure ts e)+ (P f) >>= g = P (continue . f)+ where+ continue (Success ts x) = let (P g') = g x in g' ts+ continue (Committed (Committed r)) = continue (Committed r)+ continue (Committed r) = Committed (continue r)+ continue (Failure ts e) = Failure ts e++instance PolyParse (Parser t) where+ commit (P p) = P (Committed . p)+ (P p) `adjustErr` f = P (adjust . p)+ where+ adjust (Failure z e) = Failure z (f e)+ adjust (Committed r) = Committed (adjust r)+ adjust good = good++ (P p) `onFail` (P q) = P (\ts-> continue ts $ p ts)+ where+ continue ts (Failure z e) = q ts+ -- continue _ (Committed r) = r -- no, remain Committed+ continue _ r = r++ oneOf' = accum []+ where accum errs [] =+ fail ("failed to parse any of the possible choices:\n"+ ++indent 2 (concatMap showErr (reverse errs)))+ accum errs ((e,P p):ps) =+ P (\ts-> case p ts of+ Failure _ err ->+ let (P p) = accum ((e,err):errs) ps+ in p ts+ r@(Success z a) -> r+ r@(Committed _) -> r )+ showErr (name,err) = name++":\n"++indent 2 err++------------------------------------------------------------------------+next :: Parser t t+next = P (\ts-> case ts of+ [] -> Failure [] "Ran out of input (EOF)"+ (t:ts') -> Success ts' t )++satisfy :: (t->Bool) -> Parser t t+satisfy pred = do { x <- next+ ; if pred x then return x else fail "Parse.satisfy: failed"+ }++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser t ()+reparse ts = P (\inp-> Success (ts++inp) ())++------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/NoLeak/State.hs view
@@ -0,0 +1,122 @@+module Text.ParserCombinators.Poly.NoLeak.State+ ( -- * The Parser datatype+ Parser(P) -- datatype, instance of: Functor, Monad, PolyParse+ , runParser -- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])+ -- ** basic parsers+ , next -- :: Parser s t t+ , satisfy -- :: (t->Bool) -> Parser s t t+ -- ** State-handling+ , stUpdate -- :: (s->s) -> Parser s t ()+ , stQuery -- :: (s->a) -> Parser s t a+ , stGet -- :: Parser s t s+ -- ** re-parsing+ , reparse -- :: [t] -> Parser s t ()+ -- * Re-export all more general combinators+ , module Text.ParserCombinators.Poly.Base+ ) where+++import Text.ParserCombinators.Poly.Base++-- | This @Parser@ datatype is a fairly generic parsing monad with error+-- reporting. It can be used for arbitrary token types, not just+-- String input. (If you require a running state, use module PolyState+-- instead)+newtype Parser s t a = P (s -> [t] -> Result [t] s a)++-- A return type like Either, that distinguishes not only between+-- right and wrong answers, but also has gradations of wrongness.+data Result z s a = Success z s a+ | Failure z s String+ | Committed (Result z s a)++instance Functor (Result z s) where+ fmap f (Success z s a) = Success z s (f a)+ fmap f (Failure z s e) = Failure z s e+ fmap f (Committed r) = Committed (fmap f r)++-- | Apply a parser to an input token sequence.+runParser :: Parser s t a -> s -> [t] -> (Either String a, s, [t])+runParser (P p) = \s-> resultToEither . p s+ where+ resultToEither :: Result z s a -> (Either String a, s, z)+ resultToEither (Success z s a) = (Right a, s, z)+ resultToEither (Failure z s e) = (Left e, s, z)+ resultToEither (Committed r) = resultToEither r++instance Functor (Parser s t) where+ fmap f (P p) = P (\s-> fmap f . p s)++instance Monad (Parser s t) where+ return x = P (\s ts-> Success ts s x)+ fail e = P (\s ts-> Failure ts s e)+ (P f) >>= g = P (\s-> continue . f s)+ where+ continue (Success ts s x) = let (P g') = g x in g' s ts+ continue (Committed (Committed r)) = continue (Committed r)+ continue (Committed r) = Committed (continue r)+ continue (Failure ts s e) = Failure ts s e++instance PolyParse (Parser s t) where+ commit (P p) = P (\s-> Committed . p s)+ (P p) `adjustErr` f = P (\s-> adjust . p s)+ where+ adjust (Failure z s e) = Failure z s (f e)+ adjust (Committed r) = Committed (adjust r)+ adjust good = good++ (P p) `onFail` (P q) = P (\s ts-> continue s ts $ p s ts)+ where+ continue s ts (Failure _ _ _) = q s ts+ -- continue _ _ (Committed r) = r -- no, remain Committed+ continue _ _ r = r++ oneOf' = accum []+ where accum errs [] =+ fail ("failed to parse any of the possible choices:\n"+ ++indent 2 (concatMap showErr (reverse errs)))+ accum errs ((e,P p):ps) =+ P (\s ts-> case p s ts of+ Failure _ _ err ->+ let (P p) = accum ((e,err):errs) ps+ in p s ts+ r@(Success z _ a) -> r+ r@(Committed _) -> r )+ showErr (name,err) = name++":\n"++indent 2 err++------------------------------------------------------------------------+next :: Parser s t t+next = P (\s ts-> case ts of+ [] -> Failure [] s "Ran out of input (EOF)"+ (t:ts') -> Success ts' s t )++satisfy :: (t->Bool) -> Parser s t t+satisfy pred = do { x <- next+ ; if pred x then return x else fail "Parse.satisfy: failed"+ }+------------------------------------------------------------------------+-- State handling++-- | Update the internal state.+stUpdate :: (s->s) -> Parser s t ()+stUpdate f = P (\s ts-> Success ts (f s) ())++-- | Query the internal state.+stQuery :: (s->a) -> Parser s t a+stQuery f = P (\s ts-> Success ts s (f s))++-- | Deliver the entire internal state.+stGet :: Parser s t s+stGet = P (\s ts-> Success ts s s)+++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser s t ()+reparse ts = P (\s inp-> Success (ts++inp) s ())++------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/NoLeak/StateLazy.hs view
@@ -0,0 +1,172 @@+module Text.ParserCombinators.Poly.NoLeak.StateLazy+ ( -- * The Parser datatype+ Parser(P) -- datatype, instance of: Functor, Monad, PolyParse+ , runParser -- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])+ -- ** basic parsers+ , next -- :: Parser s t t+ , satisfy -- :: (t->Bool) -> Parser s t t+ , manyFinally -- :: Parser s t a -> Parser s t z -> Parser s t [a]+ -- ** State-handling+ , stUpdate -- :: (s->s) -> Parser s t ()+ , stQuery -- :: (s->a) -> Parser s t a+ , stGet -- :: Parser s t s+ -- ** re-parsing+ , reparse -- :: [t] -> Parser s t ()+ -- * Re-export all more general combinators+ , module Text.ParserCombinators.Poly.Base+ ) where+++import Text.ParserCombinators.Poly.Base hiding (manyFinally)++#if __GLASGOW_HASKELL__+import Control.Exception hiding (bracket)+throwE :: String -> a+throwE msg = throw (ErrorCall msg)+#else+throwE :: String -> a+throwE msg = error msg+#endif+++-- | This @Parser@ datatype is a fairly generic parsing monad with error+-- reporting. It can be used for arbitrary token types, not just+-- String input. (If you require a running state, use module PolyState+-- instead)+newtype Parser s t a = P (s -> [t] -> Result [t] s a)++-- A return type like Either, that distinguishes not only between+-- right and wrong answers, but also has gradations of wrongness.+data Result z s a = Success z s a+ | Failure z s String+ | Committed (Result z s a)++instance Functor (Result z s) where+ fmap f (Success z s a) = Success z s (f a)+ fmap f (Failure z s e) = Failure z s e+ fmap f (Committed r) = Committed (fmap f r)++-- | Apply a parser to an input token sequence.+runParser :: Parser s t a -> s -> [t] -> (a, s, [t])+runParser (P p) = \s -> fromResult . p s+ where+ fromResult :: Result z s a -> (a, s, z)+ fromResult (Success z s a) = (a, s, z)+ fromResult (Failure z s e) = throwE e+ fromResult (Committed r) = fromResult r++instance Functor (Parser s t) where+ fmap f (P p) = P (\s -> fmap f . p s)++instance Monad (Parser s t) where+ return x = P (\s ts-> Success ts s x)+ fail e = P (\s ts-> Failure ts s e)+ (P f) >>= g = P (\s-> continue . f s)+ where+ continue (Success ts s x) = let (P g') = g x in g' s ts+ continue (Committed (Committed r)) = continue (Committed r)+ continue (Committed r) = Committed (continue r)+ continue (Failure ts s e) = Failure ts s e++instance PolyParse (Parser s t) where+ commit (P p) = P (\s-> Committed . p s)+ (P p) `adjustErr` f = P (\s-> adjust . p s)+ where+ adjust (Failure z s e) = Failure z s (f e)+ adjust (Committed r) = Committed (adjust r)+ adjust good = good++ (P p) `onFail` (P q) = P (\s ts-> continue s ts $ p s ts)+ where+ continue s ts (Failure _ _ _) = q s ts+ -- continue _ _ (Committed r) = r -- no, remain Committed+ continue _ _ r = r++ oneOf' = accum []+ where accum errs [] =+ fail ("failed to parse any of the possible choices:\n"+ ++indent 2 (concatMap showErr (reverse errs)))+ accum errs ((e,P p):ps) =+ P (\s ts-> case p s ts of+ Failure _ _ err ->+ let (P p) = accum ((e,err):errs) ps+ in p s ts+ r@(Success z _ a) -> r+ r@(Committed _) -> r )+ showErr (name,err) = name++":\n"++indent 2 err++ -- Apply a parsed function to a parsed value. This version+ -- is strict in the result of the function parser, but+ -- lazy in the result of the argument parser. (Argument laziness is+ -- the distinctive feature over other implementations.)+ (P pf) `apply` px = P (\s-> continue . pf s)+ where+ continue (Success z s f) = let (x,s',z') = runParser px s z+ in Success z' s' (f x)+ continue (Failure z s e) = Failure z s e+ continue (Committed r) = Committed (continue r)++manyFinally :: Parser s t a -> Parser s t z -> Parser s t [a]+{-+manyFinally pp@(P p) pt@(P t) = P (\s ts -> item s ts (p s ts))+ where+ item _ _ (Success ts s x) = success ts s x+ item s ts (Failure _ _ e) = terminate (t s ts)+ item s ts (Committed r) = Committed (within r)++ success ts s x =+ let (tail,s',ts') = runParser (manyFinally pp pt) s ts+ in Success ts' s' (x:tail)++ terminate (Success ts s _) = Success ts s []+ terminate (Failure ts s e) = Failure ts s e+ terminate (Committed r) = Committed (terminate r)++ within (Success ts s x) = success ts s x+ within (Failure ts s e) = Failure ts s e+ within (Committed r) = within r+-}++manyFinally p z =+ (do x <- p; return (x:) `apply` manyFinally p z)+ `onFail`+ (do z; return [])+ `onFail`+ oneOf' [ ("item in sequence", (do p; return []))+ , ("sequence terminator", (do z; return [])) ]++------------------------------------------------------------------------+next :: Parser s t t+next = P (\s ts-> case ts of+ [] -> Failure [] s "Ran out of input (EOF)"+ (t:ts') -> Success ts' s t )++satisfy :: (t->Bool) -> Parser s t t+satisfy pred = do { x <- next+ ; if pred x then return x else fail "Parse.satisfy: failed"+ }+------------------------------------------------------------------------+-- State handling++-- | Update the internal state.+stUpdate :: (s->s) -> Parser s t ()+stUpdate f = P (\s ts-> Success ts (f s) ())++-- | Query the internal state.+stQuery :: (s->a) -> Parser s t a+stQuery f = P (\s ts-> Success ts s (f s))++-- | Deliver the entire internal state.+stGet :: Parser s t s+stGet = P (\s ts-> Success ts s s)++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser s t ()+reparse ts = P (\s inp-> Success (ts++inp) s ())++------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/Plain.hs view
@@ -0,0 +1,92 @@+module Text.ParserCombinators.Poly.Plain+ ( -- * The Parser datatype+ Parser(P) -- datatype, instance of: Functor, Monad, PolyParse+ , runParser -- :: Parser t a -> [t] -> (Either String a, [t])+ -- ** basic parsers+ , next -- :: Parser t t+ , satisfy -- :: (t->Bool) -> Parser t t++ -- ** re-parsing+ , reparse -- :: [t] -> Parser t ()+ -- * Re-export all more general combinators+ , module Text.ParserCombinators.Poly.Base+ ) where+++import Text.ParserCombinators.Poly.Base++-- | This @Parser@ datatype is a fairly generic parsing monad with error+-- reporting. It can be used for arbitrary token types, not just+-- String input. (If you require a running state, use module PolyState+-- instead)+newtype Parser t a = P ([t] -> (EitherE String a, [t]))++-- A return type like Either, that distinguishes not only between+-- right and wrong answers, but also has gradations of wrongness.+type EitherE a b = Either (Bool,a) b++-- | Apply a parser to an input token sequence.+runParser :: Parser t a -> [t] -> (Either String a, [t])+runParser (P p) =+ (\ (e,ts)-> (case e of {Left (_,m)->Left m; Right m->Right m}, ts) )+ . p++instance Functor (Parser t) where+ fmap f (P p) = P (\ts-> case p ts of+ (Left msg, ts') -> (Left msg, ts')+ (Right x, ts') -> (Right (f x), ts'))+instance Monad (Parser t) where+ return x = P (\ts-> (Right x, ts))+ (P f) >>= g = P (\ts-> case f ts of+ (Left msg, ts') -> (Left msg, ts')+ (Right x, ts') -> let (P g') = g x in g' ts')+ fail e = P (\ts-> (Left (False,e), ts))++instance PolyParse (Parser t) where+ commit (P p) = P (\ts-> case p ts of+ (Left (_,e), ts') -> (Left (True,e), ts')+ right -> right )+ (P p) `adjustErr` f = P (\ts-> case p ts of+ (Left (b,msg), ts') -> (Left (b,(f msg)), ts')+ right -> right )+ (P p) `onFail` (P q) = P (\ts-> case p ts of+ r@(Left (True,_), _) -> r+ (Left _, _) -> q ts+ right -> right )+ oneOf' = accum []+ where accum errs [] =+ case filter isBad errs of+ [] -> fail ("failed to parse any of the possible choices:\n"+ ++indent 2 (concatMap showErr (reverse errs)))+ [(_,(_,e))] -> failBad e+ es -> failBad ("one of the following failures occurred:\n"+ ++indent 2 (concatMap showErr (reverse es)))+ accum errs ((e,P p):ps) =+ P (\ts-> case p ts of+ (Left err,_) -> let (P p) = accum ((e,err):errs) ps+ in p ts+ right -> right )+ showErr (name,(_,err)) = name++":\n"++indent 2 err+ isBad (_,(b,_)) = b++------------------------------------------------------------------------+next :: Parser t t+next = P (\ts-> case ts of+ [] -> (Left (False,"Ran out of input (EOF)"), [])+ (t:ts') -> (Right t, ts') )++satisfy :: (t->Bool) -> Parser t t+satisfy pred = do { x <- next+ ; if pred x then return x else fail "Parse.satisfy: failed"+ }++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser t ()+reparse ts = P (\inp-> (Right (), ts++inp))++------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/State.hs view
@@ -0,0 +1,109 @@+module Text.ParserCombinators.Poly.State+ ( -- * The Parser datatype+ Parser(P) -- datatype, instance of: Functor, Monad+ , runParser -- :: Parser s t a -> s -> [t] -> (Either String a, s, [t])+ -- ** basic parsers+ , next -- :: Parser s t t+ , satisfy -- :: (t->Bool) -> Parser s t t+ -- ** State-handling+ , stUpdate -- :: (s->s) -> Parser s t ()+ , stQuery -- :: (s->a) -> Parser s t a+ , stGet -- :: Parser s t s+ -- ** Re-parsing+ , reparse -- :: [t] -> Parser s t ()+ -- * Re-export all more general combinators.+ , module Text.ParserCombinators.Poly.Base+ ) where++import Text.ParserCombinators.Poly.Base++-- | The @Parser@ datatype is a fairly generic parsing monad with error+-- reporting and a running state. It can be used for arbitrary token+-- types, not just String input.+newtype Parser s t a = P (s -> [t] -> (EitherE String a, s, [t]))++-- | A return type like Either, that distinguishes not only between+-- right and wrong answers, but also had gradations of wrongness.+type EitherE a b = Either (Bool,a) b++-- | Apply a parser to an initial state and input token sequence.+runParser :: Parser s t a -> s -> [t] -> (Either String a, s, [t])+runParser (P p) s =+ (\ (e,s,ts)-> (case e of Left (_,m)->Left m; Right m->Right m+ ,s,ts))+ . p s++instance Functor (Parser s t) where+ fmap f (P p) = P (\s ts-> case p s ts of+ (Left msg, s', ts') -> (Left msg, s', ts')+ (Right x, s', ts') -> (Right (f x), s', ts'))+instance Monad (Parser s t) where+ return x = P (\s ts-> (Right x, s, ts))+ (P f) >>= g = P (\s ts-> case f s ts of+ (Left msg, s', ts') -> (Left msg, s', ts')+ (Right x, s', ts') -> let (P g') = g x+ in g' s' ts')+ fail msg = P (\s ts-> (Left (False,msg), s, ts))++instance PolyParse (Parser s t) where+ commit (P p) = P (\s ts-> case p s ts of+ (Left (_,e), s', ts') -> (Left (True,e), s', ts')+ right -> right )+ (P p) `onFail` (P q) = P (\s ts-> case p s ts of+ r@(Left (True,_), _, _) -> r+ (Left _, _, _) -> q s ts+ right -> right )+ (P p) `adjustErr` f = P (\s ts-> case p s ts of+ (Left (b,msg), s', ts')+ -> (Left (b,(f msg)), s, ts')+ right -> right )+ oneOf' = accum []+ where accum errs [] =+ case filter isBad errs of+ [] -> fail ("failed to parse any of the possible choices:\n"+ ++indent 2 (concatMap showErr (reverse errs)))+ [(_,(_,e))] -> failBad e+ es -> failBad ("one of the following failures occurred:\n"+ ++indent 2 (concatMap showErr (reverse es)))+ accum errs ((e,P p):ps) =+ P (\u ts-> case p u ts of+ (Left err,_,_) -> let (P p) = accum ((e,err):errs) ps+ in p u ts+ right -> right )+ showErr (name,(_,err)) = name++":\n"++indent 2 err+ isBad (_,(b,_)) = b++------------------------------------------------------------------------+next = P (\s ts-> case ts of+ [] -> (Left (False,"Ran out of input (EOF)"), s, [])+ (t:ts') -> (Right t, s, ts') )++satisfy :: (t->Bool) -> Parser s t t+satisfy p = do{ x <- next+ ; if p x then return x else fail "Parse.satisfy: failed"+ }+------------------------------------------------------------------------+-- State handling++-- | Update the internal state.+stUpdate :: (s->s) -> Parser s t ()+stUpdate f = P (\s ts-> (Right (), f s, ts))++-- | Query the internal state.+stQuery :: (s->a) -> Parser s t a+stQuery f = P (\s ts-> (Right (f s), s, ts))++-- | Deliver the entire internal state.+stGet :: Parser s t s+stGet = P (\s ts-> (Right s, s, ts))++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser s t ()+reparse ts = P (\s inp-> (Right (), s, ts++inp))++------------------------------------------------------------------------
+ src/Text/ParserCombinators/Poly/StateLazy.hs view
@@ -0,0 +1,140 @@+module Text.ParserCombinators.Poly.StateLazy+ ( -- * The Parser datatype.+ -- $parser+ Parser(P) -- datatype, instance of: Functor, Monad+ , runParser -- :: Parser s t a -> s -> [t] -> (a, s, [t])+ -- * Combinators:+ -- ** Primitives+ , next -- :: Parser s t t+ , satisfy -- :: (t->Bool) -> Parser s t t+ -- ** State-handling+ , stUpdate -- :: (s->s) -> Parser s t ()+ , stQuery -- :: (s->a) -> Parser s t a+ , stGet -- :: Parser s t s+ -- ** Re-parsing+ , reparse -- :: [t] -> Parser s t ()+ -- * Re-export all more general combinators+ , module Text.ParserCombinators.Poly.Base+ ) where++import Text.ParserCombinators.Poly.Base++#if __GLASGOW_HASKELL__+import Control.Exception hiding (bracket)+throwE :: String -> a+throwE msg = throw (ErrorCall msg)+#else+throwE :: String -> a+throwE msg = error msg+#endif++-- $parser+-- Parsers do not return explicit failure. An exception is raised+-- instead. This allows partial results to be returned before a+-- full parse is complete.++-- | The @Parser@ datatype is a fairly generic parsing monad with error+-- reporting and a running state. It can be used for arbitrary token+-- types, not just String input.+newtype Parser s t a = P (s -> [t] -> (Either String a, s, [t]))++-- | A return type like Either, that distinguishes not only between+-- right and wrong answers, but also had gradations of wrongness.+-- Not used in this library. !!!!!!!!!!!!!!!!!!!!!!!!!!+type EitherE a b = Either (Bool,a) b++-- | Apply a parser to an initial state and input token sequence.+-- The parser cannot return an error value explicitly, so errors+-- raise an exception. Thus, results can be partial (lazily constructed,+-- but containing undefined).+runParser :: Parser s t a -> s -> [t] -> (a, s, [t])+runParser (P p) s =+ (\ (e,s,ts)-> (case e of {Left m->throwE m; Right x->x}, s, ts))+ . p s++instance Functor (Parser s t) where+ fmap f (P p) = P (\s ts-> case p s ts of+ (Left msg, s', ts') -> (Left msg, s', ts')+ (Right x, s', ts') -> (Right (f x), s', ts'))+instance Monad (Parser s t) where+ return x = P (\s ts-> (Right x, s, ts))+ (P f) >>= g = P (\s ts-> case f s ts of+ (Left msg, s', ts') -> (Left msg, s', ts')+ (Right x, s', ts') -> let (P g') = g x+ in g' s' ts')+ fail msg = P (\s ts-> (Left msg, s, ts))++instance PolyParse (Parser s t) where+ commit (P p) = P (\s ts-> case p s ts of+ (Left e, s', ts') -> (throwE e, s', ts')+ right -> right )+ (P p) `adjustErr` f =+ P (\s ts-> case p s ts of+ (Left msg, s', ts') -> (Left (f msg), s, ts')+ right -> right )+ (P p) `onFail` (P q) = P (\s ts-> case p s ts of+ (Left _, _, _) -> q s ts+ right -> right )+ oneOf' ps = accum [] ps+ where accum errs [] =+ case errs of+ [] -> failBad ("internal failure in parser (oneOf'):\n"+ ++indent 2 (show (map fst ps)))+ [(_,e)] -> fail e+ es -> fail ("one of the following failures occurred:\n"+ ++indent 2 (concatMap showErr (reverse es)))+ accum errs ((e,P p):ps) =+ P (\u ts-> case p u ts of+ (Left err,_,_) -> let (P p) = accum ((e,err):errs) ps+ in p u ts+ right -> right )+ showErr (name,err) = name++":\n"++indent 2 err+ (P pf) `apply` (P px) = P (\s ts->+ case pf s ts of+ (Left msg, s', ts') -> (Left msg, s', ts')+ (Right f, s', ts') -> let (x',s'',ts'') = px s' ts'+ x = case x' of { Right x -> x+ ; Left e -> throwE e }+ in (Right (f x), s'', ts'') )+++-- Combinators++-- | Yield one token.+next :: Parser s t t+next = P (\s ts-> case ts of+ [] -> (Left "Ran out of input (EOF)", s, [])+ (t:ts') -> (Right t, s, ts') )++-- | Yield one token if it satisfies a predicate.+satisfy :: (t->Bool) -> Parser s t t+satisfy p = do{ x <- next+ ; if p x then return x else fail "Parse.satisfy: failed"+ }+++------------------------------------------------------------------------+-- State handling++-- | Update the internal state.+stUpdate :: (s->s) -> Parser s t ()+stUpdate f = P (\s ts-> (Right (), f s, ts))++-- | Query the internal state.+stQuery :: (s->a) -> Parser s t a+stQuery f = P (\s ts-> (Right (f s), s, ts))++-- | Deliver the entire internal state.+stGet :: Parser s t s+stGet = P (\s ts-> (Right s, s, ts))++------------------------------------------------------------------------+-- | Push some tokens back onto the front of the input stream and reparse.+-- This is useful e.g. for recursively expanding macros. When the+-- user-parser recognises a macro use, it can lookup the macro+-- expansion from the parse state, lex it, and then stuff the+-- lexed expansion back down into the parser.+reparse :: [t] -> Parser s t ()+reparse ts = P (\s inp-> (Right (), s, ts++inp))++------------------------------------------------------------------------
src/Text/ParserCombinators/PolyLazy.hs view
@@ -21,6 +21,7 @@ , oneOf' -- :: [(String,Parser t a)] -> Parser t a , optional -- :: Parser t a -> Parser t (Maybe a) -- ** Sequences+ , exactly -- :: Int -> Parser t a -> Parser t [a] , many -- :: Parser t a -> Parser t [a] , many1 -- :: Parser t a -> Parser t [a] , sepBy -- :: Parser t a -> Parser t sep -> Parser t [a]@@ -128,7 +129,9 @@ infixl 3 `discard` -- | @x `discard` y@ parses both x and y, but discards the result of y discard :: Parser t a -> Parser t b -> Parser t a-px `discard` py = do { x <- px; _ <- py; return x }+--px `discard` py = do { x <- px; _ <- py; return x }+-- Needs to be lazier! Do not force the discarded portion too early.+px `discard` py = do { x <- px; return (\_-> x) `apply` py } -- | @p `adjustErr` f@ applies the transformation @f@ to any error message -- generated in @p@, having no effect if @p@ succeeds.@@ -192,16 +195,24 @@ optional :: Parser t a -> Parser t (Maybe a) optional p = fmap Just p `onFail` return Nothing +-- | 'exactly n p' parses a precise number of items, n, using the parser+-- p, in sequence.+exactly :: Int -> Parser t a -> Parser t [a]+exactly 0 p = return []+exactly n p = return (:) `apply` p `apply` exactly (n-1) p+ -- | 'many p' parses a list of elements with individual parser p. -- Cannot fail, since an empty list is a valid return value. many :: Parser t a -> Parser t [a] many p = many1 p `onFail` return []+ where many1 p = do { x <- p+ ; return (x:) `apply` many p+ } -- | Parse a non-empty list of items. many1 :: Parser t a -> Parser t [a] many1 p = do { x <- p `adjustErr` (("In a sequence:\n"++). indent 2)- ; xs <- many p- ; return (x:xs)+ ; return (x:) `apply` many p } -- `adjustErr` ("When looking for a non-empty sequence:\n\t"++) @@ -212,10 +223,9 @@ -- | Parse a non-empty list of items separated by discarded junk. sepBy1 :: Parser t a -> Parser t sep -> Parser t [a] sepBy1 p sep = do { x <- p- ; xs <- many (do {sep; p})- ; return (x:xs)+ ; return (x:) `apply` many (do {sep; p}) }- `adjustErr` ("When looking for a non-empty sequence with separators:\n\t"++)+ `adjustErr` ("When looking for a non-empty sequence with separators:\n\t"++) -- | Parse a list of items, discarding the start, end, and separator -- items.@@ -226,18 +236,16 @@ `onFail` do { open `adjustErr` ("Missing opening bracket:\n\t"++) ; x <- p `adjustErr` ("After first bracket in a group:\n\t"++)- ; xs <- many (do {sep; p})- ; close `adjustErrBad` ("When looking for closing bracket:\n\t"++)- ; return (x:xs)+ ; return (x:) `apply`+ manyFinally (do {sep; p})+ (close `adjustErrBad` ("When looking for closing bracket:\n\t"++)) } -- | Parse a bracketed item, discarding the brackets. bracket :: Parser t bra -> Parser t ket -> Parser t a -> Parser t a bracket open close p = do do { open `adjustErr` ("Missing opening bracket:\n\t"++)- ; x <- p- ; close `adjustErrBad` ("Missing closing bracket:\n\t"++)- ; return x+ ; p `discard` (close `adjustErrBad` ("Missing closing bracket:\n\t"++)) } -- | 'manyFinally e t' parses a possibly-empty sequence of e's,
src/Text/ParserCombinators/PolyState.hs view
@@ -19,6 +19,7 @@ , oneOf -- :: [Parser s t a] -> Parser s t a , oneOf' -- :: [(String, Parser s t a)] -> Parser s t a -- ** Sequences+ , exactly -- :: Int -> Parser s t a -> Parser s t [a] , many -- :: Parser s t a -> Parser s t [a] , many1 -- :: Parser s t a -> Parser s t [a] , sepBy -- :: Parser s t a -> Parser s t sep -> Parser s t [a]@@ -159,6 +160,14 @@ -- | Helper for formatting error messages: indents all lines by a fixed amount. indent :: Int -> String -> String indent n = unlines . map (replicate n ' ' ++) . lines++-- | 'exactly n p' parses a precise number of items, n, using the parser+-- p, in sequence.+exactly :: Int -> Parser s t a -> Parser s t [a]+exactly 0 p = return []+exactly n p = do x <- p+ xs <- exactly (n-1) p+ return (x:xs) -- | 'many p' parses a list of elements with individual parser p. -- Cannot fail, since an empty list is a valid return value.
src/Text/ParserCombinators/PolyStateLazy.hs view
@@ -21,6 +21,7 @@ , oneOf' -- :: [(String, Parser s t a)] -> Parser s t a , optional -- :: Parser s t a -> Parser s t (Maybe a) -- ** Sequences+ , exactly -- :: Int -> Parser s t a -> Parser s t [a] , many -- :: Parser s t a -> Parser s t [a] , many1 -- :: Parser s t a -> Parser s t [a] , sepBy -- :: Parser s t a -> Parser s t sep -> Parser s t [a]@@ -190,6 +191,14 @@ -- | 'optional' indicates whether the parser succeeded through the Maybe type. optional :: Parser s t a -> Parser s t (Maybe a) optional p = fmap Just p `onFail` return Nothing++-- | 'exactly n p' parses a precise number of items, n, using the parser+-- p, in sequence.+exactly :: Int -> Parser s t a -> Parser s t [a]+exactly 0 p = return []+exactly n p = do x <- p+ xs <- exactly (n-1) p+ return (x:xs) -- | 'many p' parses a list of elements with individual parser p. -- Cannot fail, since an empty list is a valid return value.