packages feed

parsec1 (empty) → 1.0.0.0

raw patch · 10 files changed

+1430/−0 lines, 10 filesdep +basesetup-changed

Dependencies added: base

Files

+ CHANGELOG view
@@ -0,0 +1,9 @@+parsec2-1.0.0 (Changes from parsec-2.1.0.1)++Sat Jul 24 12:17:43 CDT 2010  Antoine Latter <aslatter@gmail.com>+  * add dcoumentation done for parsec-3++Wed Jun  9 22:23:52 CDT 2010  Antoine Latter <aslatter@gmail.com>+  * in Parsec.Token, sort names after accounting for case sensitivity, not before+  from: Greg Fitzgerald+
+ LICENSE view
@@ -0,0 +1,21 @@+Copyright 1999-2000, Daan Leijen. All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++* Redistributions of source code must retain the above copyright notice,+  this list of conditions and the following disclaimer.+* Redistributions in binary form must reproduce the above copyright+  notice, this list of conditions and the following disclaimer in the+  documentation and/or other materials provided with the distribution.++This software is provided by the copyright holders "as is" and any express or+implied warranties, including, but not limited to, the implied warranties of+merchantability and fitness for a particular purpose are disclaimed. In no+event shall the copyright holders be liable for any direct, indirect,+incidental, special, exemplary, or consequential damages (including, but not+limited to, procurement of substitute goods or services; loss of use, data,+or profits; or business interruption) however caused and on any theory of+liability, whether in contract, strict liability, or tort (including+negligence or otherwise) arising in any way out of the use of this software,+even if advised of the possibility of such damage.
+ Setup.hs view
@@ -0,0 +1,6 @@+module Main (main) where++import Distribution.Simple++main :: IO ()+main = defaultMain
+ Text/ParserCombinators/Parsec.hs view
@@ -0,0 +1,54 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Text.ParserCombinators.Parsec+-- Copyright   :  (c) Daan Leijen 1999-2001+-- License     :  BSD-style (see the file libraries/parsec/LICENSE)+-- +-- Maintainer  :  Antoine Latter <aslatter@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- Parsec, the Fast Monadic Parser combinator library, see+-- <http://www.cs.uu.nl/people/daan/parsec.html>.+--+-- Inspired by:+--+-- * Graham Hutton and Erik Meijer:+--   Monadic Parser Combinators.+--   Technical report NOTTCS-TR-96-4. +--   Department of Computer Science, University of Nottingham, 1996. +--   <http://www.cs.nott.ac.uk/~gmh/monparsing.ps>+--+-- * Andrew Partridge, David Wright: +--   Predictive parser combinators need four values to report errors.+--   Journal of Functional Programming 6(2): 355-364, 1996+--+-- This helper module exports elements from the basic libraries.+--+-----------------------------------------------------------------------------++module Text.ParserCombinators.Parsec+               ( -- complete modules+                 module Text.ParserCombinators.Parsec.Prim+               , module Text.ParserCombinators.Parsec.Combinator+               , module Text.ParserCombinators.Parsec.Char+               +               -- module Text.ParserCombinators.Parsec.Error+               , ParseError   +               , errorPos   +               +               -- module Text.ParserCombinators.Parsec.Pos+               , SourcePos+               , SourceName, Line, Column             +               , sourceName, sourceLine, sourceColumn             +               , incSourceLine, incSourceColumn+               , setSourceLine, setSourceColumn, setSourceName++             ) where++import Text.ParserCombinators.Parsec.Pos            -- textual positions+import Text.ParserCombinators.Parsec.Error          -- parse errors+import Text.ParserCombinators.Parsec.Prim           -- primitive combinators+import Text.ParserCombinators.Parsec.Combinator     -- derived combinators+import Text.ParserCombinators.Parsec.Char           -- character parsers+
+ Text/ParserCombinators/Parsec/Char.hs view
@@ -0,0 +1,139 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Text.ParserCombinators.Parsec.Char+-- Copyright   :  (c) Daan Leijen 1999-2001+-- License     :  BSD-style (see the file libraries/parsec/LICENSE)+-- +-- Maintainer  :  Antoine Latter <aslatter@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- Commonly used character parsers.+-- +-----------------------------------------------------------------------------++module Text.ParserCombinators.Parsec.Char+                  ( CharParser+                  , spaces, space+                  , newline, tab+                  , upper, lower, alphaNum, letter+                  , digit, hexDigit, octDigit+                  , char, string+                  , anyChar, oneOf, noneOf+                  , satisfy+                  ) where++import Prelude+import Data.Char+import Text.ParserCombinators.Parsec.Pos( updatePosChar, updatePosString )+import Text.ParserCombinators.Parsec.Prim++-----------------------------------------------------------+-- Type of character parsers+-----------------------------------------------------------+type CharParser st a    = GenParser Char st a++-----------------------------------------------------------+-- Character parsers+-----------------------------------------------------------++-- | @oneOf cs@ succeeds if the current character is in the supplied+-- list of characters @cs@. Returns the parsed character. See also+-- 'satisfy'.+--+-- >   vowel  = oneOf "aeiou"+oneOf :: [Char] -> CharParser st Char+oneOf cs            = satisfy (\c -> elem c cs)++-- | As the dual of 'oneOf', @noneOf cs@ succeeds if the current+-- character /not/ in the supplied list of characters @cs@. Returns the+-- parsed character.+--+-- >  consonant = noneOf "aeiou"+noneOf :: [Char] -> CharParser st Char+noneOf cs           = satisfy (\c -> not (elem c cs))++-- | Skips /zero/ or more white space characters. See also 'skipMany'.+spaces :: CharParser st ()+spaces              = skipMany space        <?> "white space"          ++-- | Parses a white space character (any character which satisfies 'isSpace')+-- Returns the parsed character.+space :: CharParser st Char+space               = satisfy (isSpace)     <?> "space"++-- | Parses a newline character (\'\\n\'). Returns a newline character.+newline :: CharParser st Char+newline             = char '\n'             <?> "new-line"++-- | Parses a tab character (\'\\t\'). Returns a tab character.+tab :: CharParser st Char+tab                 = char '\t'             <?> "tab"++-- | Parses an upper case letter (a character between \'A\' and \'Z\').+-- Returns the parsed character.+upper :: CharParser st Char+upper               = satisfy (isUpper)     <?> "uppercase letter"++-- | Parses a lower case character (a character between \'a\' and \'z\').+-- Returns the parsed character.+lower :: CharParser st Char+lower               = satisfy (isLower)     <?> "lowercase letter"++-- | Parses a letter or digit (a character between \'0\' and \'9\').+-- Returns the parsed character.+alphaNum :: CharParser st Char+alphaNum            = satisfy (isAlphaNum)  <?> "letter or digit"++-- | Parses a letter (an upper case or lower case character). Returns the+-- parsed character.+letter :: CharParser st Char+letter              = satisfy (isAlpha)     <?> "letter"++-- | Parses a digit. Returns the parsed character.+digit :: CharParser st Char+digit               = satisfy (isDigit)     <?> "digit"++-- | Parses a hexadecimal digit (a digit or a letter between \'a\' and+-- \'f\' or \'A\' and \'F\'). Returns the parsed character.+hexDigit :: CharParser st Char+hexDigit            = satisfy (isHexDigit)  <?> "hexadecimal digit"++-- | Parses an octal digit (a character between \'0\' and \'7\'). Returns+-- the parsed character.+octDigit :: CharParser st Char+octDigit            = satisfy (isOctDigit)  <?> "octal digit"++-- | @char c@ parses a single character @c@. Returns the parsed+-- character (i.e. @c@).+--+-- >  semiColon  = char ';'+char :: Char -> CharParser st Char+char c              = satisfy (==c)  <?> show [c]++-- | This parser succeeds for any character. Returns the parsed character.+anyChar :: CharParser st Char+anyChar             = satisfy (const True)++-----------------------------------------------------------+-- Primitive character parsers+-----------------------------------------------------------++-- | The parser @satisfy f@ succeeds for any character for which the+-- supplied function @f@ returns 'True'. Returns the character that is+-- actually parsed.+--+-- >  digit     = satisfy isDigit+-- >  oneOf cs  = satisfy (\c -> c `elem` cs)+satisfy :: (Char -> Bool) -> CharParser st Char+satisfy f           = tokenPrim (\c -> show [c]) +                                (\pos c cs -> updatePosChar pos c) +                                (\c -> if f c then Just c else Nothing)++-- | @string s@ parses a sequence of characters given by @s@. Returns+-- the parsed string (i.e. @s@).+--+-- >  divOrMod    =   string "div"+-- >              <|> string "mod"+string :: String -> CharParser st String+string s            = tokens show updatePosString s
+ Text/ParserCombinators/Parsec/Combinator.hs view
@@ -0,0 +1,267 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Text.ParserCombinators.Parsec.Combinator+-- Copyright   :  (c) Daan Leijen 1999-2001+-- License     :  BSD-style (see the file libraries/parsec/LICENSE)+-- +-- Maintainer  :  Antoine Latter <aslatter@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- Commonly used generic combinators+-- +-----------------------------------------------------------------------------++module Text.ParserCombinators.Parsec.Combinator+                        ( choice+                        , count+                        , between+                        , option, optionMaybe, optional+                        , skipMany1+                        , many1+                        , sepBy, sepBy1+                        , endBy, endBy1+                        , sepEndBy, sepEndBy1+                        , chainl, chainl1+                        , chainr, chainr1+                        , eof, notFollowedBy+                        +                        -- tricky combinators+                        , manyTill, lookAhead, anyToken+                        ) where++import Control.Monad+import Text.ParserCombinators.Parsec.Prim+++-- | @choice ps@ tries to apply the parsers in the list @ps@ in order,+-- until one of them succeeds. Returns the value of the succeeding+-- parser.+choice :: [GenParser tok st a] -> GenParser tok st a+choice ps           = foldr (<|>) mzero ps++-- | @option x p@ tries to apply parser @p@. If @p@ fails without+-- consuming input, it returns the value @x@, otherwise the value+-- returned by @p@.+--+-- >  priority  = option 0 (do{ d <- digit+-- >                          ; return (digitToInt d)+-- >                          })+option :: a -> GenParser tok st a -> GenParser tok st a+option x p          = p <|> return x++-- | @optionMaybe p@ tries to apply parser @p@.  If @p@ fails without+-- consuming input, it return 'Nothing', otherwise it returns+-- 'Just' the value returned by @p@.+optionMaybe :: GenParser tok st a -> GenParser tok st (Maybe a)+optionMaybe p       = option Nothing (liftM Just p)++-- | @optional p@ tries to apply parser @p@.  It will parse @p@ or nothing.+-- It only fails if @p@ fails after consuming input. It discards the result+-- of @p@.+optional :: GenParser tok st a -> GenParser tok st ()+optional p          = do{ p; return ()} <|> return ()++-- | @between open close p@ parses @open@, followed by @p@ and @close@.+-- Returns the value returned by @p@.+--+-- >  braces  = between (symbol "{") (symbol "}")+between :: GenParser tok st open -> GenParser tok st close +            -> GenParser tok st a -> GenParser tok st a+between open close p+                    = do{ open; x <- p; close; return x }+                +                +-- | @skipMany1 p@ applies the parser @p@ /one/ or more times, skipping+-- its result.+skipMany1 :: GenParser tok st a -> GenParser tok st ()+skipMany1 p         = do{ p; skipMany p }+{-+skipMany p          = scan+                    where+                      scan  = do{ p; scan } <|> return ()+-}++-- | @many1 p@ applies the parser @p@ /one/ or more times. Returns a+-- list of the returned values of @p@.+--+-- >  word  = many1 letter+many1 :: GenParser tok st a -> GenParser tok st [a]+many1 p             = do{ x <- p; xs <- many p; return (x:xs) }+{-+many p              = scan id+                    where+                      scan f    = do{ x <- p+                                    ; scan (\tail -> f (x:tail))+                                    }+                                <|> return (f [])+-}++-- | @sepBy p sep@ parses /zero/ or more occurrences of @p@, separated+-- by @sep@. Returns a list of values returned by @p@.+--+-- >  commaSep p  = p `sepBy` (symbol ",")+sepBy :: GenParser tok st a -> GenParser tok st sep -> GenParser tok st [a]+sepBy p sep         = sepBy1 p sep <|> return []++-- | @sepBy1 p sep@ parses /one/ or more occurrences of @p@, separated+-- by @sep@. Returns a list of values returned by @p@.+sepBy1 :: GenParser tok st a -> GenParser tok st sep -> GenParser tok st [a]+sepBy1 p sep        = do{ x <- p+                        ; xs <- many (sep >> p)+                        ; return (x:xs)+                        }++-- | @sepEndBy1 p sep@ parses /one/ or more occurrences of @p@,+-- separated and optionally ended by @sep@. Returns a list of values+-- returned by @p@.+sepEndBy1 :: GenParser tok st a -> GenParser tok st sep -> GenParser tok st [a]+sepEndBy1 p sep     = do{ x <- p+                        ; do{ sep+                            ; xs <- sepEndBy p sep+                            ; return (x:xs)+                            }+                          <|> return [x]+                        }+        +-- | @sepEndBy p sep@ parses /zero/ or more occurrences of @p@,+-- separated and optionally ended by @sep@, ie. haskell style+-- statements. Returns a list of values returned by @p@.+--+-- >  haskellStatements  = haskellStatement `sepEndBy` semi+sepEndBy :: GenParser tok st a -> GenParser tok st sep -> GenParser tok st [a]+sepEndBy p sep      = sepEndBy1 p sep <|> return []+++-- | @endBy1 p sep@ parses /one/ or more occurrences of @p@, seperated+-- and ended by @sep@. Returns a list of values returned by @p@.+endBy1 :: GenParser tok st a -> GenParser tok st sep -> GenParser tok st [a]+endBy1 p sep        = many1 (do{ x <- p; sep; return x })++-- | @endBy p sep@ parses /zero/ or more occurrences of @p@, seperated+-- and ended by @sep@. Returns a list of values returned by @p@.+--+-- >   cStatements  = cStatement `endBy` semi+endBy :: GenParser tok st a -> GenParser tok st sep -> GenParser tok st [a]+endBy p sep         = many (do{ x <- p; sep; return x })++-- | @count n p@ parses @n@ occurrences of @p@. If @n@ is smaller or+-- equal to zero, the parser equals to @return []@. Returns a list of+-- @n@ values returned by @p@.+count :: Int -> GenParser tok st a -> GenParser tok st [a]+count n p           | n <= 0    = return []+                    | otherwise = sequence (replicate n p)+++-- | @chainr p op x@ parser /zero/ or more occurrences of @p@,+-- separated by @op@ Returns a value obtained by a /right/ associative+-- application of all functions returned by @op@ to the values returned+-- by @p@. If there are no occurrences of @p@, the value @x@ is+-- returned.+chainr :: GenParser tok st a -> GenParser tok st (a -> a -> a) -> a -> GenParser tok st a+chainr p op x       = chainr1 p op <|> return x++-- | @chainl p op x@ parser /zero/ or more occurrences of @p@,+-- separated by @op@. Returns a value obtained by a /left/ associative+-- application of all functions returned by @op@ to the values returned+-- by @p@. If there are zero occurrences of @p@, the value @x@ is+-- returned.+chainl :: GenParser tok st a -> GenParser tok st (a -> a -> a) -> a -> GenParser tok st a+chainl p op x       = chainl1 p op <|> return x++-- | @chainl1 p op x@ parser /one/ or more occurrences of @p@,+-- separated by @op@ Returns a value obtained by a /left/ associative+-- application of all functions returned by @op@ to the values returned+-- by @p@. . This parser can for example be used to eliminate left+-- recursion which typically occurs in expression grammars.+--+-- >  expr    = term   `chainl1` addop+-- >  term    = factor `chainl1` mulop+-- >  factor  = parens expr <|> integer+-- >+-- >  mulop   =   do{ symbol "*"; return (*)   }+-- >          <|> do{ symbol "/"; return (div) }+-- >+-- >  addop   =   do{ symbol "+"; return (+) }+-- >          <|> do{ symbol "-"; return (-) }+chainl1 :: GenParser tok st a -> GenParser tok st (a -> a -> a) -> GenParser tok st a+chainl1 p op        = do{ x <- p; rest x }+                    where+                      rest x    = do{ f <- op+                                    ; y <- p+                                    ; rest (f x y)+                                    }+                                <|> return x+                              +-- | @chainr1 p op x@ parser /one/ or more occurrences of |p|,+-- separated by @op@ Returns a value obtained by a /right/ associative+-- application of all functions returned by @op@ to the values returned+-- by @p@.+chainr1 :: GenParser tok st a -> GenParser tok st (a -> a -> a) -> GenParser tok st a+chainr1 p op        = scan+                    where+                      scan      = do{ x <- p; rest x }+                      +                      rest x    = do{ f <- op+                                    ; y <- scan+                                    ; return (f x y)+                                    }+                                <|> return x++-----------------------------------------------------------+-- Tricky combinators+-----------------------------------------------------------++-- | The parser @anyToken@ accepts any kind of token. It is for example+-- used to implement 'eof'. Returns the accepted token.+anyToken :: Show tok => GenParser tok st tok+anyToken            = tokenPrim show (\pos tok toks -> pos) Just++-- | This parser only succeeds at the end of the input. This is not a+-- primitive parser but it is defined using 'notFollowedBy'.+--+-- >  eof  = notFollowedBy anyToken <?> "end of input"+eof :: Show tok => GenParser tok st ()+eof                 = notFollowedBy anyToken <?> "end of input"   ++-- | @notFollowedBy p@ only succeeds when parser @p@ fails. This parser+-- does not consume any input. This parser can be used to implement the+-- \'longest match\' rule. For example, when recognizing keywords (for+-- example @let@), we want to make sure that a keyword is not followed+-- by a legal identifier character, in which case the keyword is+-- actually an identifier (for example @lets@). We can program this+-- behaviour as follows:+--+-- >  keywordLet  = try (do{ string "let"+-- >                       ; notFollowedBy alphaNum+-- >                       })+notFollowedBy :: Show tok => GenParser tok st tok -> GenParser tok st ()   +notFollowedBy p     = try (do{ c <- p; unexpected (show [c]) }+                           <|> return ()+                          )++-- | @manyTill p end@ applies parser @p@ /zero/ or more times until+-- parser @end@ succeeds. Returns the list of values returned by @p@.+-- This parser can be used to scan comments:+--+-- >  simpleComment   = do{ string "<!--"+-- >                      ; manyTill anyChar (try (string "-->"))+-- >                      }+--+--    Note the overlapping parsers @anyChar@ and @string \"<!--\"@, and+--    therefore the use of the 'try' combinator.+manyTill :: GenParser tok st a -> GenParser tok st end -> GenParser tok st [a]+manyTill p end      = scan+                    where+                      scan  = do{ end; return [] }+                            <|>+                              do{ x <- p; xs <- scan; return (x:xs) }+++-- | @lookAhead p@ parses @p@ without consuming any input.+lookAhead :: GenParser tok st a -> GenParser tok st a+lookAhead p         = do{ state <- getParserState+                        ; x <- p+                        ; setParserState state+                        ; return x+                        }
+ Text/ParserCombinators/Parsec/Error.hs view
@@ -0,0 +1,192 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Text.ParserCombinators.Parsec.Error+-- Copyright   :  (c) Daan Leijen 1999-2001+-- License     :  BSD-style (see the file libraries/parsec/LICENSE)+-- +-- Maintainer  :  Antoine Latter <aslatter@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- Parse errors+-- +-----------------------------------------------------------------------------++module Text.ParserCombinators.Parsec.Error+                  ( Message(SysUnExpect,UnExpect,Expect,Message)+                  , messageString, messageCompare, messageEq+                  +                  , ParseError, errorPos, errorMessages, errorIsUnknown+                  , showErrorMessages+                  +                  , newErrorMessage, newErrorUnknown+                  , addErrorMessage, setErrorPos, setErrorMessage+                  , mergeError+                  )+                  where+++import Prelude+import Data.List (nub,sortBy)+import Text.ParserCombinators.Parsec.Pos +                          +-- | This abstract data type represents parse error messages. There are+-- four kinds of messages:+--+-- >  data Message = SysUnExpect String+-- >               | UnExpect String+-- >               | Expect String+-- >               | Message String+-- +-- The fine distinction between different kinds of parse errors allows+-- the system to generate quite good error messages for the user. It+-- also allows error messages that are formatted in different+-- languages. Each kind of message is generated by different combinators:+--+--     * A 'SysUnExpect' message is automatically generated by the+--       'Text.Parsec.Combinator.satisfy' combinator. The argument is the+--       unexpected input.+--+--     * A 'UnExpect' message is generated by the 'Text.Parsec.Prim.unexpected'+--       combinator. The argument describes the+--       unexpected item.+--+--     * A 'Expect' message is generated by the 'Text.Parsec.Prim.<?>'+--       combinator. The argument describes the expected item.+--+--     * A 'Message' message is generated by the 'fail'+--       combinator. The argument is some general parser message.+data Message        = SysUnExpect !String   --library generated unexpect            +                    | UnExpect    !String   --unexpected something     +                    | Expect      !String   --expecting something+                    | Message     !String   --raw message+                    +messageToEnum msg+    = case msg of SysUnExpect _ -> 0+                  UnExpect _    -> 1+                  Expect _      -> 2+                  Message _     -> 3                                  +                                      +messageCompare :: Message -> Message -> Ordering+messageCompare msg1 msg2+    = compare (messageToEnum msg1) (messageToEnum msg2)+  +-- | Extract the message string from an error message+messageString :: Message -> String+messageString msg+    = case msg of SysUnExpect s -> s+                  UnExpect s    -> s+                  Expect s      -> s+                  Message s     -> s                                  ++messageEq :: Message -> Message -> Bool+messageEq msg1 msg2+    = (messageCompare msg1 msg2 == EQ)+    +    +-- | The abstract data type @ParseError@ represents parse errors. It+-- provides the source position ('SourcePos') of the error+-- and a list of error messages ('Message'). A @ParseError@+-- can be returned by the function 'Text.Parsec.Prim.parse'. @ParseError@ is an+-- instance of the 'Show' class.+data ParseError     = ParseError !SourcePos [Message]++-- | Extracts the source position from the parse error+errorPos :: ParseError -> SourcePos+errorPos (ParseError pos msgs)+    = pos+                  +-- | Extracts the list of error messages from the parse error+errorMessages :: ParseError -> [Message]+errorMessages (ParseError pos msgs)+    = sortBy messageCompare msgs      +        +errorIsUnknown :: ParseError -> Bool+errorIsUnknown (ParseError pos msgs)+    = null msgs+            +            +-----------------------------------------------------------+-- Create parse errors+-----------------------------------------------------------                         +newErrorUnknown :: SourcePos -> ParseError+newErrorUnknown pos+    = ParseError pos []+    +newErrorMessage :: Message -> SourcePos -> ParseError+newErrorMessage msg pos  +    = ParseError pos [msg]++addErrorMessage :: Message -> ParseError -> ParseError+addErrorMessage msg (ParseError pos msgs)+    = ParseError pos (msg:msgs)+    +setErrorPos :: SourcePos -> ParseError -> ParseError+setErrorPos pos (ParseError _ msgs)+    = ParseError pos msgs+    +setErrorMessage :: Message -> ParseError -> ParseError+setErrorMessage msg (ParseError pos msgs)+    = ParseError pos (msg:filter (not . messageEq msg) msgs)+ +    +mergeError :: ParseError -> ParseError -> ParseError+mergeError (ParseError pos msgs1) (ParseError _ msgs2)+    = ParseError pos (msgs1 ++ msgs2)+    +++-----------------------------------------------------------+-- Show Parse Errors+-----------------------------------------------------------                         +instance Show ParseError where+  show err+    = show (errorPos err) ++ ":" ++ +      showErrorMessages "or" "unknown parse error" +                        "expecting" "unexpected" "end of input"+                       (errorMessages err)+++-- | Language independent show function+showErrorMessages ::+    String -> String -> String -> String -> String -> [Message] -> String+showErrorMessages msgOr msgUnknown msgExpecting msgUnExpected msgEndOfInput msgs+    | null msgs = msgUnknown+    | otherwise = concat $ map ("\n"++) $ clean $+                 [showSysUnExpect,showUnExpect,showExpect,showMessages]+    where+      (sysUnExpect,msgs1)   = span (messageEq (SysUnExpect "")) msgs+      (unExpect,msgs2)      = span (messageEq (UnExpect "")) msgs1+      (expect,messages)     = span (messageEq (Expect "")) msgs2+    +      showExpect        = showMany msgExpecting expect+      showUnExpect      = showMany msgUnExpected unExpect+      showSysUnExpect   | not (null unExpect) ||+                          null sysUnExpect       = ""+                        | null firstMsg          = msgUnExpected ++ " " ++ msgEndOfInput+                        | otherwise              = msgUnExpected ++ " " ++ firstMsg+                        where+                          firstMsg  = messageString (head sysUnExpect)+                        +      showMessages      = showMany "" messages++      +      --helpers                                                                                                                                        +      showMany pre msgs = case (clean (map messageString msgs)) of+                            [] -> ""+                            ms | null pre  -> commasOr ms+                               | otherwise -> pre ++ " " ++ commasOr ms+                            +      commasOr []       = ""                +      commasOr [m]      = m                +      commasOr ms       = commaSep (init ms) ++ " " ++ msgOr ++ " " ++ last ms+        +      commaSep          = seperate ", " . clean+      semiSep           = seperate "; " . clean       +        +      seperate sep []   = ""+      seperate sep [m]  = m+      seperate sep (m:ms) = m ++ sep ++ seperate sep ms                            +      +      clean             = nub . filter (not.null)                  +      
+ Text/ParserCombinators/Parsec/Pos.hs view
@@ -0,0 +1,114 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Text.ParserCombinators.Parsec.Pos+-- Copyright   :  (c) Daan Leijen 1999-2001+-- License     :  BSD-style (see the file libraries/parsec/LICENSE)+-- +-- Maintainer  :  Antoine Latter <aslatter@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- Textual source positions.+-- +-----------------------------------------------------------------------------++module Text.ParserCombinators.Parsec.Pos+                  ( SourceName, Line, Column                 +                  , SourcePos+                  , sourceLine, sourceColumn, sourceName+                  , incSourceLine, incSourceColumn+                  , setSourceLine, setSourceColumn, setSourceName+                  , newPos, initialPos+                  , updatePosChar, updatePosString+                  ) where++-----------------------------------------------------------+-- Source Positions, a file name, a line and a column.+-- upper left is (1,1)+-----------------------------------------------------------                         +type SourceName     = String+type Line           = Int+type Column         = Int++-- | The abstract data type @SourcePos@ represents source positions. It+-- contains the name of the source (i.e. file name), a line number and+-- a column number. @SourcePos@ is an instance of the 'Show', 'Eq' and+-- 'Ord' class.+data SourcePos      = SourcePos SourceName !Line !Column+		     deriving (Eq,Ord)+		+-- | Create a new 'SourcePos' with the given source name,+-- line number and column number.+newPos :: SourceName -> Line -> Column -> SourcePos+newPos sourceName line column+    = SourcePos sourceName line column++-- | Create a new 'SourcePos' with the given source name,+-- and line number and column number set to 1, the upper left.+initialPos :: SourceName -> SourcePos+initialPos sourceName+    = newPos sourceName 1 1++-- | Extracts the name of the source from a source position.+sourceName :: SourcePos -> SourceName+sourceName (SourcePos name line column) = name ++-- | Extracts the line number from a source position.+sourceLine :: SourcePos -> Line+sourceLine (SourcePos name line column) = line++-- | Extracts the column number from a source position.+sourceColumn :: SourcePos -> Column+sourceColumn (SourcePos name line column) = column++-- | Increments the line number of a source position.+incSourceLine :: SourcePos -> Line -> SourcePos+incSourceLine (SourcePos name line column) n = SourcePos name (line+n) column++-- | Increments the column number of a source position.+incSourceColumn :: SourcePos -> Column -> SourcePos+incSourceColumn (SourcePos name line column) n = SourcePos name line (column+n)++-- | Set the name of the source.+setSourceName :: SourcePos -> SourceName -> SourcePos+setSourceName (SourcePos name line column) n = SourcePos n line column++-- | Set the line number of a source position.+setSourceLine :: SourcePos -> Line -> SourcePos+setSourceLine (SourcePos name line column) n = SourcePos name n column++-- | Set the column number of a source position.+setSourceColumn :: SourcePos -> Column -> SourcePos+setSourceColumn (SourcePos name line column) n = SourcePos name line n++-- | The expression @updatePosString pos s@ updates the source position+-- @pos@ by calling 'updatePosChar' on every character in @s@, ie.+-- @foldl updatePosChar pos string@.+updatePosString :: SourcePos -> String -> SourcePos+updatePosString pos string+    = forcePos (foldl updatePosChar pos string)++updatePosChar   :: SourcePos -> Char -> SourcePos+updatePosChar pos@(SourcePos name line column) c   +    = forcePos $+      case c of+        '\n' -> SourcePos name (line+1) 1+        '\t' -> SourcePos name line (column + 8 - ((column-1) `mod` 8))+        _    -> SourcePos name line (column + 1)+        ++forcePos :: SourcePos -> SourcePos      +forcePos pos@(SourcePos name line column)+    = seq line (seq column (pos))++-----------------------------------------------------------+-- Show positions +-----------------------------------------------------------                                                 +instance Show SourcePos where+  show (SourcePos name line column)+    | null name = showLineColumn+    | otherwise = "\"" ++ name ++ "\" " ++ showLineColumn+    where+      showLineColumn    = "(line " ++ show line +++                          ", column " ++ show column +++                          ")" 
+ Text/ParserCombinators/Parsec/Prim.hs view
@@ -0,0 +1,597 @@+-----------------------------------------------------------------------------+-- |+-- Module      :  Text.ParserCombinators.Parsec.Prim+-- Copyright   :  (c) Daan Leijen 1999-2001+-- License     :  BSD-style (see the file libraries/parsec/LICENSE)+-- +-- Maintainer  :  Antoine Latter <aslatter@gmail.com>+-- Stability   :  provisional+-- Portability :  portable+--+-- The primitive parser combinators.+-- +-----------------------------------------------------------------------------++module Text.ParserCombinators.Parsec.Prim+                   ( -- operators: label a parser, alternative+                     (<?>), (<|>)++                   -- basic types+                   , Parser, GenParser+                   , runParser, parse, parseFromFile, parseTest+                   +                   -- primitive parsers:+                   -- instance Functor Parser     : fmap+                   -- instance Monad Parser       : return, >>=, fail+                   -- instance MonadPlus Parser   : mzero (pzero), mplus (<|>)+                   , token, tokens, tokenPrim, tokenPrimEx+                   , try, label, labels, unexpected, pzero++                   -- primitive because of space behaviour+                   , many, skipMany+                                +                   -- user state manipulation+                   , getState, setState, updateState++                   -- state manipulation+                   , getPosition, setPosition+                   , getInput, setInput                   +                   , State(..), getParserState, setParserState +                 ) where++import Prelude+import Text.ParserCombinators.Parsec.Pos+import Text.ParserCombinators.Parsec.Error+import Control.Monad++{-# INLINE parsecMap    #-}+{-# INLINE parsecReturn #-}+{-# INLINE parsecBind   #-}+{-# INLINE parsecZero   #-}+{-# INLINE parsecPlus   #-}+{-# INLINE token        #-}+{-# INLINE tokenPrim    #-}++-----------------------------------------------------------+-- Operators:+-- <?>  gives a name to a parser (which is used in error messages)+-- <|>  is the choice operator+-----------------------------------------------------------+infix  0 <?>+infixr 1 <|>++-- | The parser @p <?> msg@ behaves as parser @p@, but whenever the+-- parser @p@ fails /without consuming any input/, it replaces expect+-- error messages with the expect error message @msg@.+--+-- This is normally used at the end of a set alternatives where we want+-- to return an error message in terms of a higher level construct+-- rather than returning all possible characters. For example, if the+-- @expr@ parser from the 'try' example would fail, the error+-- message is: '...: expecting expression'. Without the @(\<?>)@+-- combinator, the message would be like '...: expecting \"let\" or+-- letter', which is less friendly.+(<?>) :: GenParser tok st a -> String -> GenParser tok st a+p <?> msg           = label p msg++-- | This combinator implements choice. The parser @p \<|> q@ first+-- applies @p@. If it succeeds, the value of @p@ is returned. If @p@+-- fails /without consuming any input/, parser @q@ is tried. This+-- combinator is defined equal to the 'mplus' member of the 'MonadPlus'+-- class and the ('Control.Applicative.<|>') member of 'Control.Applicative.Alternative'.+--+-- The parser is called /predictive/ since @q@ is only tried when+-- parser @p@ didn't consume any input (i.e.. the look ahead is 1).+-- This non-backtracking behaviour allows for both an efficient+-- implementation of the parser combinators and the generation of good+-- error messages.+(<|>) :: GenParser tok st a -> GenParser tok st a -> GenParser tok st a+p1 <|> p2           = mplus p1 p2+++-----------------------------------------------------------+-- User state combinators+-----------------------------------------------------------++-- | Returns the current user state.+getState :: GenParser tok st st+getState        = do{ state <- getParserState+                    ; return (stateUser state)+                    }++-- | @setState st@ set the user state to @st@.+setState :: st -> GenParser tok st ()+setState st     = do{ updateParserState (\(State input pos _) -> State input pos st)+                    ; return ()+                    }++-- | @updateState f@ applies function @f@ to the user state. Suppose+-- that we want to count identifiers in a source, we could use the user+-- state as:+--+-- >  expr  = do{ x <- identifier+-- >            ; updateState (+1)+-- >            ; return (Id x)+-- >            }+updateState :: (st -> st) -> GenParser tok st ()+updateState f   = do{ updateParserState (\(State input pos user) -> State input pos (f user))+                    ; return ()+                    }+++-----------------------------------------------------------+-- Parser state combinators+-----------------------------------------------------------++-- | Returns the current source position. See also 'SourcePos'.+getPosition :: GenParser tok st SourcePos+getPosition         = do{ state <- getParserState; return (statePos state) }++-- | Returns the current input+getInput :: GenParser tok st [tok]+getInput            = do{ state <- getParserState; return (stateInput state) }+++-- | @setPosition pos@ sets the current source position to @pos@.+setPosition :: SourcePos -> GenParser tok st ()+setPosition pos     = do{ updateParserState (\(State input _ user) -> State input pos user)+                        ; return ()+                        }+                        +-- | @setInput input@ continues parsing with @input@.+setInput :: [tok] -> GenParser tok st ()+setInput input      = do{ updateParserState (\(State _ pos user) -> State input pos user)+                        ; return ()+                        }++-- | Returns the full parser state as a 'State' record.+getParserState	    :: GenParser tok st (State tok st)+getParserState      =  updateParserState id    ++-- | @setParserState st@ set the full parser state to @st@.+setParserState	    :: State tok st -> GenParser tok st (State tok st)+setParserState st   = updateParserState (const st)+++++-----------------------------------------------------------+-- Parser definition.+-- GenParser tok st a:+--  General parser for tokens of type "tok", +--  a user state "st" and a result type "a"+-----------------------------------------------------------+type Parser a           = GenParser Char () a++newtype GenParser tok st a = Parser (State tok st -> Consumed (Reply tok st a))+runP (Parser p)            = p++data Consumed a         = Consumed a                --input is consumed+                        | Empty !a                  --no input is consumed+                    +data Reply tok st a     = Ok !a !(State tok st) ParseError    --parsing succeeded with "a"+                        | Error ParseError                    --parsing failed++data State tok st       = State { stateInput :: [tok]+                                , statePos   :: !SourcePos+                                , stateUser  :: !st+                                }+++-----------------------------------------------------------+-- run a parser+-----------------------------------------------------------+parseFromFile :: Parser a -> SourceName -> IO (Either ParseError a)+parseFromFile p fname+    = do{ input <- readFile fname+        ; return (parse p fname input)+        }++-- | The expression @parseTest p input@ applies a parser @p@ against+-- input @input@ and prints the result to stdout. Used for testing+-- parsers.+parseTest :: Show a => GenParser tok () a -> [tok] -> IO ()+parseTest p input+    = case (runParser p () "" input) of+        Left err -> do{ putStr "parse error at "+                      ; print err+                      }+        Right x  -> print x++-- | @parse p filePath input@ runs a parser @p@ without user+-- state. The @filePath@ is only used in error messages and may be the+-- empty string. Returns either a 'ParseError' ('Left')+-- or a value of type @a@ ('Right').+--+-- >  main    = case (parse numbers "" "11, 2, 43") of+-- >             Left err  -> print err+-- >             Right xs  -> print (sum xs)+-- >+-- >  numbers = commaSep integer+parse :: GenParser tok () a -> SourceName -> [tok] -> Either ParseError a+parse p name input+    = runParser p () name input++-- | The most general way to run a parser. @runParser p state filePath+-- input@ runs parser @p@ on the input list of tokens @input@,+-- obtained from source @filePath@ with the initial user state @st@.+-- The @filePath@ is only used in error messages and may be the empty+-- string. Returns either a 'ParseError' ('Left') or a+-- value of type @a@ ('Right').+--+-- >  parseFromFile p fname+-- >    = do{ input <- readFile fname+-- >        ; return (runParser p () fname input)+-- >        }+runParser :: GenParser tok st a -> st -> SourceName -> [tok] -> Either ParseError a+runParser p st name input+    = case parserReply (runP p (State input (initialPos name) st)) of+        Ok x _ _    -> Right x+        Error err   -> Left err++parserReply result     +    = case result of+        Consumed reply -> reply+        Empty reply    -> reply+++-----------------------------------------------------------+-- Functor: fmap+-----------------------------------------------------------+instance Functor (GenParser tok st) where+  fmap f p  = parsecMap f p++parsecMap :: (a -> b) -> GenParser tok st a -> GenParser tok st b+parsecMap f (Parser p)+    = Parser (\state -> +        case (p state) of+          Consumed reply -> Consumed (mapReply reply)+          Empty    reply -> Empty    (mapReply reply)+      )+    where+      mapReply reply+        = case reply of+            Ok x state err -> let fx = f x +                              in seq fx (Ok fx state err)+            Error err      -> Error err+           ++-----------------------------------------------------------+-- Monad: return, sequence (>>=) and fail+-----------------------------------------------------------    +instance Monad (GenParser tok st) where+  return x   = parsecReturn x  +  p >>= f    = parsecBind p f+  fail msg   = parsecFail msg++parsecReturn :: a -> GenParser tok st a+parsecReturn x+  = Parser (\state -> Empty (Ok x state (unknownError state)))   ++parsecBind :: GenParser tok st a -> (a -> GenParser tok st b) -> GenParser tok st b+parsecBind (Parser p) f+    = Parser (\state ->+        case (p state) of                 +          Consumed reply1 +            -> Consumed $+               case (reply1) of+                 Ok x state1 err1 -> case runP (f x) state1 of+                                       Empty reply2    -> mergeErrorReply err1 reply2+                                       Consumed reply2 -> reply2+                 Error err1       -> Error err1++          Empty reply1    +            -> case (reply1) of+                 Ok x state1 err1 -> case runP (f x) state1 of+                                       Empty reply2 -> Empty (mergeErrorReply err1 reply2)+                                       other        -> other                                                    +                 Error err1       -> Empty (Error err1)+      )                                                              ++mergeErrorReply err1 reply+  = case reply of+      Ok x state err2 -> Ok x state (mergeError err1 err2)+      Error err2      -> Error (mergeError err1 err2)+++parsecFail :: String -> GenParser tok st a+parsecFail msg+  = Parser (\state -> +      Empty (Error (newErrorMessage (Message msg) (statePos state))))+++-----------------------------------------------------------+-- MonadPlus: alternative (mplus) and mzero+-----------------------------------------------------------+instance MonadPlus (GenParser tok st) where+  mzero         = parsecZero+  mplus p1 p2   = parsecPlus p1 p2+      ++pzero :: GenParser tok st a+pzero = parsecZero++-- | @parsecZero@ always fails without consuming any input. @parsecZero@ is defined+-- equal to the 'mzero' member of the 'MonadPlus' class and to the 'Control.Applicative.empty' member+-- of the 'Control.Applicative.Applicative' class.+parsecZero :: GenParser tok st a+parsecZero+    = Parser (\state -> Empty (Error (unknownError state)))++parsecPlus :: GenParser tok st a -> GenParser tok st a -> GenParser tok st a+parsecPlus (Parser p1) (Parser p2)+    = Parser (\state ->+        case (p1 state) of        +          Empty (Error err) -> case (p2 state) of+                                 Empty reply -> Empty (mergeErrorReply err reply)+                                 consumed    -> consumed+          other             -> other+      )+++{- +-- variant that favors a consumed reply over an empty one, even it is not the first alternative.+          empty@(Empty reply) -> case reply of+                                   Error err ->+                                     case (p2 state) of+                                       Empty reply -> Empty (mergeErrorReply err reply)+                                       consumed    -> consumed+                                   ok ->+                                     case (p2 state) of+                                       Empty reply -> empty+                                       consumed    -> consumed+          consumed  -> consumed+-}+++-- | The parser @try p@ behaves like parser @p@, except that it+-- pretends that it hasn't consumed any input when an error occurs.+--+-- This combinator is used whenever arbitrary look ahead is needed.+-- Since it pretends that it hasn't consumed any input when @p@ fails,+-- the ('<|>') combinator will try its second alternative even when the+-- first parser failed while consuming input.+--+-- The @try@ combinator can for example be used to distinguish+-- identifiers and reserved words. Both reserved words and identifiers+-- are a sequence of letters. Whenever we expect a certain reserved+-- word where we can also expect an identifier we have to use the @try@+-- combinator. Suppose we write:+--+-- >  expr        = letExpr <|> identifier <?> "expression"+-- >+-- >  letExpr     = do{ string "let"; ... }+-- >  identifier  = many1 letter+--+-- If the user writes \"lexical\", the parser fails with: @unexpected+-- \'x\', expecting \'t\' in \"let\"@. Indeed, since the ('<|>') combinator+-- only tries alternatives when the first alternative hasn't consumed+-- input, the @identifier@ parser is never tried (because the prefix+-- \"le\" of the @string \"let\"@ parser is already consumed). The+-- right behaviour can be obtained by adding the @try@ combinator:+--+-- >  expr        = letExpr <|> identifier <?> "expression"+-- >+-- >  letExpr     = do{ try (string "let"); ... }+-- >  identifier  = many1 letter+try :: GenParser tok st a -> GenParser tok st a+try (Parser p)+    = Parser (\state@(State input pos user) ->     +        case (p state) of+          Consumed (Error err)  -> Empty (Error (setErrorPos pos err))+          Consumed ok           -> Consumed ok    -- was: Empty ok+          empty                 -> empty+      )++-- | The parser @token showTok posFromTok testTok@ accepts a token @t@+-- with result @x@ when the function @testTok t@ returns @'Just' x@. The+-- source position of the @t@ should be returned by @posFromTok t@ and+-- the token can be shown using @showTok t@.+--+-- This combinator is expressed in terms of 'tokenPrim'.+-- It is used to accept user defined token streams. For example,+-- suppose that we have a stream of basic tokens tupled with source+-- positions. We can than define a parser that accepts single tokens as:+--+-- >  mytoken x+-- >    = token showTok posFromTok testTok+-- >    where+-- >      showTok (pos,t)     = show t+-- >      posFromTok (pos,t)  = pos+-- >      testTok (pos,t)     = if x == t then Just t else Nothing+token :: (tok -> String) -> (tok -> SourcePos) -> (tok -> Maybe a) -> GenParser tok st a    +token show tokpos test+  = tokenPrim show nextpos test+  where+    nextpos _ _   (tok:toks)  = tokpos tok+    nextpos _ tok []          = tokpos tok++-- | The parser @token showTok nextPos testTok@ accepts a token @t@+-- with result @x@ when the function @testTok t@ returns @'Just' x@. The+-- token can be shown using @showTok t@. The position of the /next/+-- token should be returned when @nextPos@ is called with the current+-- source position @pos@, the current token @t@ and the rest of the+-- tokens @toks@, @nextPos pos t toks@.+--+-- This is the most primitive combinator for accepting tokens. For+-- example, the 'Text.Parsec.Char.char' parser could be implemented as:+--+-- >  char c+-- >    = tokenPrim showChar nextPos testChar+-- >    where+-- >      showChar x        = "'" ++ x ++ "'"+-- >      testChar x        = if x == c then Just x else Nothing+-- >      nextPos pos x xs  = updatePosChar pos x+tokenPrim :: (tok -> String) -> (SourcePos -> tok -> [tok] -> SourcePos) -> (tok -> Maybe a) -> GenParser tok st a+tokenPrim show nextpos test+    = tokenPrimEx show nextpos Nothing test++-- | The most primitive token recogniser. The expression @tokenPrimEx show nextpos mbnextstate test@,+-- recognises tokens when @test@ returns @Just x@ (and returns the value @x@). Tokens are shown in+-- error messages using @show@. The position is calculated using @nextpos@, and finally, @mbnextstate@,+-- can hold a function that updates the user state on every token recognised (nice to count tokens :-).+-- The function is packed into a 'Maybe' type for performance reasons.+tokenPrimEx :: (tok -> String) -> +               (SourcePos -> tok -> [tok] -> SourcePos) -> +               Maybe (SourcePos -> tok -> [tok] -> st -> st) ->+               (tok -> Maybe a) -> +               GenParser tok st a+tokenPrimEx show nextpos mbNextState test+    = case mbNextState of+        Nothing +          -> Parser (\state@(State input pos user) -> +              case input of+                (c:cs) -> case test c of+                            Just x  -> let newpos   = nextpos pos c cs+                                           newstate = State cs newpos user+                                       in seq newpos $ seq newstate $ +                                          Consumed (Ok x newstate (newErrorUnknown newpos))+                            Nothing -> Empty (sysUnExpectError (show c) pos)+                []     -> Empty (sysUnExpectError "" pos)+             )+        Just nextState+          -> Parser (\state@(State input pos user) -> +              case input of+                (c:cs) -> case test c of+                            Just x  -> let newpos   = nextpos pos c cs+                                           newuser  = nextState pos c cs user+                                           newstate = State cs newpos newuser+                                       in seq newpos $ seq newstate $ +                                          Consumed (Ok x newstate (newErrorUnknown newpos))+                            Nothing -> Empty (sysUnExpectError (show c) pos)+                []     -> Empty (sysUnExpectError "" pos)+             )+++label :: GenParser tok st a -> String -> GenParser tok st a    +label p msg+  = labels p [msg]++labels :: GenParser tok st a -> [String] -> GenParser tok st a+labels (Parser p) msgs+    = Parser (\state -> +        case (p state) of+          Empty reply -> Empty $ +                         case (reply) of+                           Error err        -> Error (setExpectErrors err msgs)+                           Ok x state1 err  | errorIsUnknown err -> reply+                                            | otherwise -> Ok x state1 (setExpectErrors err msgs)+          other       -> other+      )+++-- | @updateParserState f@ applies function @f@ to the parser state.+updateParserState :: (State tok st -> State tok st) -> GenParser tok st (State tok st)+updateParserState f +    = Parser (\state -> let newstate = f state+                        in Empty (Ok state newstate (unknownError newstate)))+    +-- | The parser @unexpected msg@ always fails with an unexpected error+-- message @msg@ without consuming any input.+--+-- The parsers 'fail', ('<?>') and @unexpected@ are the three parsers+-- used to generate error messages. Of these, only ('<?>') is commonly+-- used. For an example of the use of @unexpected@, see the definition+-- of 'Text.Parsec.Combinator.notFollowedBy'.+unexpected :: String -> GenParser tok st a+unexpected msg+    = Parser (\state -> Empty (Error (newErrorMessage (UnExpect msg) (statePos state))))+    ++setExpectErrors err []         = setErrorMessage (Expect "") err+setExpectErrors err [msg]      = setErrorMessage (Expect msg) err+setExpectErrors err (msg:msgs) = foldr (\msg err -> addErrorMessage (Expect msg) err) +                                       (setErrorMessage (Expect msg) err) msgs++sysUnExpectError msg pos  = Error (newErrorMessage (SysUnExpect msg) pos)+unknownError state        = newErrorUnknown (statePos state)++-----------------------------------------------------------+-- Parsers unfolded for space:+-- if many and skipMany are not defined as primitives,+-- they will overflow the stack on large inputs+-----------------------------------------------------------    ++-- | @many p@ applies the parser @p@ /zero/ or more times. Returns a+--    list of the returned values of @p@.+--+-- >  identifier  = do{ c  <- letter+-- >                  ; cs <- many (alphaNum <|> char '_')+-- >                  ; return (c:cs)+-- >                  }+many :: GenParser tok st a -> GenParser tok st [a]+many p+  = do{ xs <- manyAccum (:) p+      ; return (reverse xs)+      }++-- | @skipMany p@ applies the parser @p@ /zero/ or more times, skipping+-- its result.+--+-- >  spaces  = skipMany space+skipMany :: GenParser tok st a -> GenParser tok st ()+skipMany p+  = do{ manyAccum (\x xs -> []) p+      ; return ()+      }++manyAccum :: (a -> [a] -> [a]) -> GenParser tok st a -> GenParser tok st [a]+manyAccum accum (Parser p)+  = Parser (\state -> +    let walk xs state r = case r of+                           Empty (Error err)          -> Ok xs state err+                           Empty ok                   -> error "Text.ParserCombinators.Parsec.Prim.many: combinator 'many' is applied to a parser that accepts an empty string."+                           Consumed (Error err)       -> Error err+                           Consumed (Ok x state' err) -> let ys = accum x xs+                                                         in seq ys (walk ys state' (p state'))+    in case (p state) of+         Empty reply  -> case reply of+                           Ok x state' err -> error "Text.ParserCombinators.Parsec.Prim.many: combinator 'many' is applied to a parser that accepts an empty string."+                           Error err       -> Empty (Ok [] state err)+         consumed     -> Consumed $ walk [] state consumed)++++-----------------------------------------------------------+-- Parsers unfolded for speed: +--  tokens+-----------------------------------------------------------    ++{- specification of @tokens@:+tokens showss nextposs s+  = scan s+  where+    scan []       = return s+    scan (c:cs)   = do{ token show nextpos c <?> shows s; scan cs }                      ++    show c        = shows [c]+    nextpos pos c = nextposs pos [c]+-}++tokens :: Eq tok => ([tok] -> String) -> (SourcePos -> [tok] -> SourcePos) -> [tok] -> GenParser tok st [tok]+tokens shows nextposs s+    = Parser (\state@(State input pos user) -> +       let+        ok cs             = let newpos   = nextposs pos s+                                newstate = State cs newpos user+                            in seq newpos $ seq newstate $ +                               (Ok s newstate (newErrorUnknown newpos))+                               +        errEof            = Error (setErrorMessage (Expect (shows s))+                                     (newErrorMessage (SysUnExpect "") pos))+        errExpect c       = Error (setErrorMessage (Expect (shows s))+                                     (newErrorMessage (SysUnExpect (shows [c])) pos))++        walk [] cs        = ok cs+        walk xs []        = errEof+        walk (x:xs) (c:cs)| x == c        = walk xs cs+                          | otherwise     = errExpect c++        walk1 [] cs        = Empty (ok cs)+        walk1 xs []        = Empty (errEof)+        walk1 (x:xs) (c:cs)| x == c        = Consumed (walk xs cs)+                           | otherwise     = Empty (errExpect c)++       in walk1 s input)++
+ parsec1.cabal view
@@ -0,0 +1,31 @@+cabal-version: >= 1.2+name:		parsec1+version:	1.0.0.0+license:	BSD3+license-file:	LICENSE+author:		Daan Leijen <daan@cs.uu.nl>+maintainer:	Christian Maeder <Christian.Maeder@dfki.de>+homepage:	http://www.cs.uu.nl/~daan/parsec.html+category:	Parsing+synopsis:	Monadic parser combinators+description:+    Parsec is designed from scratch as an industrial-strength parser+    library.  It is simple, safe, well documented (on the package+    homepage), has extensive libraries and good error messages,+    and is also fast.+    .+    This package is the core haskell98 part of the parsec2+    package, intended to preserve its simplicity and portability.+build-type:     Simple+extra-source-files: CHANGELOG+cabal-version:      >= 1.6+library {+  exposed-modules:+    Text.ParserCombinators.Parsec.Error,+    Text.ParserCombinators.Parsec.Char,+    Text.ParserCombinators.Parsec.Combinator,+    Text.ParserCombinators.Parsec.Pos,+    Text.ParserCombinators.Parsec.Prim,+    Text.ParserCombinators.Parsec+  build-depends:	base < 5+}