packages feed

uu-parsinglib 2.4.0 → 2.4.1

raw patch · 8 files changed

+332/−147 lines, 8 files

Files

src/Text/ParserCombinators/UU.hs view
@@ -1,6 +1,24 @@+-- | The non-exported module "Text.ParserCombinators.UU.Examples" contains a list of examples of how to use the main functionality of this library: it demonstrates:+--+-- * how to write basic parsers+--+-- * how to to write ambiguous parsers+--+-- * how the error correction works+--+-- * how to fine tune your parsers to get rid of ambiguities+--+-- * how to use the monadic interface+--+-- * what kind of error messages you can get if you write erroneous parsers+--+ module Text.ParserCombinators.UU ( module Text.ParserCombinators.UU.Core                                  , module Text.ParserCombinators.UU.BasicInstances-                                 , module Text.ParserCombinators.UU.Derived) where+                                 , module Text.ParserCombinators.UU.Derived+                                 , module Text.ParserCombinators.UU.Merge) where import Text.ParserCombinators.UU.Core import Text.ParserCombinators.UU.BasicInstances import Text.ParserCombinators.UU.Derived+import Text.ParserCombinators.UU.Merge+
src/Text/ParserCombinators/UU/BasicInstances.hs view
@@ -20,9 +20,9 @@                    | DeletedAtEnd String  instance (Show pos) => Show (Error  pos) where - show (Inserted s pos expecting) = "--     Inserted " ++  s ++ " at position " ++ show pos ++  show_expecting  expecting - show (Deleted  t pos expecting) = "--     Deleted  " ++  t ++ " at position " ++ show pos ++  show_expecting  expecting - show (DeletedAtEnd t)           = "--     The token " ++ t ++ " was not consumed by the parsing process."+ show (Inserted s pos expecting) = "-- >    Inserted " ++  s ++ " at position " ++ show pos ++  show_expecting  expecting + show (Deleted  t pos expecting) = "-- >    Deleted  " ++  t ++ " at position " ++ show pos ++  show_expecting  expecting + show (DeletedAtEnd t)           = "-- >    The token " ++ t ++ " was not consumed by the parsing process."  show_errors = sequence_ . (map (putStrLn . show)) 
+ src/Text/ParserCombinators/UU/CHANGELOG.hs view
@@ -0,0 +1,53 @@+-- | This module just contains the CHANGELOG+--+--  Version 2.4.1+--+--       * added the module Text.ParserCombinators.Merge for recognizing alternating sequences+--+--       * made @P st@ an instance of @`MonadPlus`@+--+--       * beautified Haddock documentation+--+-- | Version 2.4.0+--+--       * contains abstract interpretation for minimal lenth, in order to avoid recursive correction process+--+--       * idem for checking that no repeating combinators like pList are parameterised with possibly empty parsers+--+--       * lots of Haddcock doumentation in "Text.ParserCombinators.UU.Examples"+--+-- Version 2.3.4+--+--       * removed dependecies on impredictaive types, preparing for next GHC version+--+-- Version 2.3.3+--+--       * added `pMunch` which takes a Boolean function, and recognises the longest prefix for which the symbols match the predicate+-- +--       * added the infix operator with piority 2 @\<?> :: P state a -> String -> P state a@ which replaces the list of expected symbols+--         in error message by its right argument String+--+-- Version 2.3.2+--+--       * added microsteps, which can be used to disambiguate+--+-- Version 2.3.1+--+--       * fix for GHC 6.12, because of change in GADT definition handling+--+-- Versions above 2.2:+--+--       *  make use of type families+--   +--       *  contain a module with many list-based derived combinators+--+-- Versions above 2.1: +--       * based on Control.Applicative+--+--    Note that the basic parser interface will probably not change much when we add more features, but the calling conventions+--    of the outer parser and the class structure upon which the parametrisation is based may change slightly++module Text.ParserCombinators.UU.CHANGELOG () where+++dummy = undefined
src/Text/ParserCombinators/UU/Derived.hs view
@@ -9,6 +9,7 @@  module Text.ParserCombinators.UU.Derived where import Text.ParserCombinators.UU.Core+import Control.Monad  -- | This module contains a large variety of combinators for list-lile structures. the extension @_ng@ indiactes that that varinat is the non-greedy variant. --   See the "Text.ParserCombinators.UU.Examples" module for some exmaples of their use.@@ -27,10 +28,10 @@ -- recognise the empty string, since this would make your parser ambiguous!!  opt ::  P st a -> a -> P st a-p `opt` v       =  p <<|> pure v +p `opt` v       = must_be_non_empty "opt" p (p <<|> pure v)   pMaybe :: P st a -> P st (Maybe a)-pMaybe p = Just <$> p `opt` Nothing +pMaybe p = must_be_non_empty "pMaybe" p (Just <$> p `opt` Nothing)   pEither p q = Left <$> p <|> Right <$> q                                                 @@ -125,4 +126,9 @@ -- | Parses any of the symbols in 'l'. pAnySym :: Provides st s s => [s] -> P st s pAnySym = pAny pSym ++instance MonadPlus (P st) where+  mzero = pFail+  mplus = (<|>)+ 
src/Text/ParserCombinators/UU/Examples.hs view
@@ -1,14 +1,11 @@-{-# LANGUAGE  RankNTypes #-}---              GADTs,---              MultiParamTypeClasses,---              FunctionalDependencies, ---              FlexibleInstances, ---              FlexibleContexts, ---              UndecidableInstances,---              NoMonomorphismRestriction+{-# OPTIONS_HADDOCK  ignore-exports #-} module Text.ParserCombinators.UU.Examples where import Char-import Text.ParserCombinators.UU+import Text.ParserCombinators.UU.Core+import Text.ParserCombinators.UU.Derived+import Text.ParserCombinators.UU.BasicInstances+import Text.ParserCombinators.UU.Merge+import Control.Monad  -- |We start out by defining the type of parser we want; by specifying the type of the state we resolve a lot of overloading @@ -18,12 +15,11 @@ run :: Show t =>  P (Str Char) t -> String -> IO () run p inp = do  let r@(a, errors) =  parse ( (,) <$> p <*> pEnd) (listToStr inp)                 putStrLn "--"-                putStrLn "-- @"-                putStrLn ("-- Result: " ++ show a)+                putStrLn ("-- > Result: " ++ show a)                 if null errors then  return ()-                               else  do putStr ("-- Correcting steps: \n")+                               else  do putStr ("-- > Correcting steps: \n")                                         show_errors errors-                putStrLn "-- @"+                putStrLn "-- "   -- | Our first two parsers are simple; one recognises a single 'a' character and the other one a single 'b'. Since we will use them later we @@ -34,42 +30,48 @@ pb = lift <$> pSym 'b' lift a = [a] --- | We can now run the parser @`pa`@ on input \"a\", which succeeds: +-- | We can now run the parser @`pa`@ on input \"a\", which succeeds: ----- @ ---   Result: \"a\"--- @+-- > run pa "a" +--+-- > Result: "a"+--  test1 = run pa "a" --- | If we   run the parser @`pa`@ on the empty input \"\", the expected symbol in inserted, that the position where it was inserted is reported, and---   we get information about what was expected at that position:  @run pa \"\"@ +-- | If we   run the parser @`pa`@ on the empty input \"\", the expected symbol in inserted, +--   that the position where it was inserted is reported, and+--   we get information about what was expected at that position:  ----- @--- Result: \"a\"--- Correcting steps: ---     Inserted 'a' at position 0 expecting 'a'--- @+-- > run pa ""+--+-- > Result: "a"+-- > Correcting steps: +-- >    Inserted 'a' at position 0 expecting 'a'+--   test2 = run pa "" --- | Now let's see what happens if we encounter an unexpected symbol, as in @run pa \"b\"@:+-- | Now let's see what happens if we encounter an unexpected symbol, as in: ----- @--- Result: \"a\"--- Correcting steps: ---     Deleted  'b' at position 0 expecting 'a'---     Inserted 'a' at position 1 expecting 'a'--- @+-- > run pa "b"+--+-- > Result: "a"+-- > Correcting steps: +-- >    Deleted  'b' at position 0 expecting 'a'+-- >    Inserted 'a' at position 1 expecting 'a'+--   test3 = run pa "b" --- | The combinator @\<++>@ applies two parsers sequentially to the input and concatenates their results: @run (pa <++> pa) \"aa\"@:+-- | The combinator @`<++>`@ applies two parsers sequentially to the input and concatenates their results: ----- @--- Result: \"aa\"--- @+-- > run (pa <++> pa) "aa"@:+--+-- > Result: "aa"+--  + (<++>) :: Parser String -> Parser String -> Parser String p <++> q = (++) <$> p <*> q pa2 =   pa <++> pa@@ -78,150 +80,164 @@ test4 = run pa2 "aa"  -- | The function @`pSym`@ is overloaded. The type of its argument determines how to interpret the argument. Thus far we have seen single characters, ---   but we may pass ranges as well as argument: @\run (pList (pSym ('a','z'))) \"doaitse\"@+--   but we may pass ranges as well as argument:  ----- @--- Result: "doaitse"--- @+-- > run (pList (pSym ('a','z'))) "doaitse"+--+--+-- > Result: "doaitse"+--   test5 =  run  (pList (pSym ('a','z'))) "doaitse" paz = pList (pSym ('a', 'z')) --- | An even more general instance of @`pSym`@ takes a triple as argument: a predicate, a string  indicating what is expected, ---   and the value to insert if nothing can be recognised: @run (pSym (\t -> 'a' <= t && t <= 'z', \"'a'..'z'\", 'k')) \"v\"@+-- | An even more general instance of @`pSym`@ takes a triple as argument: a predicate, +--   a string indicating what is expected, +--   and the value to insert if nothing can be recognised: +-- +-- > run (pSym (\t -> 'a' <= t && t <= 'z', "'a'..'z'", 'k')) "1" ----- @--- Result: 'k'--- Correcting steps: ---     Deleted  '1' at position 0 expecting 'a'..'z'---     Inserted 'k' at position 1 expecting 'a'..'z'--- @+--+-- > Result: 'k'+-- > Correcting steps: +-- >    Deleted  '1' at position 0 expecting 'a'..'z'+-- >    Inserted 'k' at position 1 expecting 'a'..'z'+--  + test6 = run  paz' "1" paz' = pSym (\t -> 'a' <= t && t <= 'z', "'a'..'z'", 'k')  -- | The parser `pCount` recognises a sequence of elements, throws away the results of the recognition process (@ \<$ @), and just returns the number of returned elements.---   The choice combinator @\<\<|>@ indicates that prefernce is to be given to the left alternative if it can make progress. This enables us to specify greedy strategies:---   @ run (pCount pa) \"aaaaa\"@+--   The choice combinator @\<\<|>@ indicates that preference is to be given to the left alternative if it can make progress. This enables us to specify greedy strategies: ----- @--- Result: 5--- @+-- > run (pCount pa) "aaaaa"+--+-- > Result: 5+--   pCount p = (+1) <$ p <*> pCount p <<|> pReturn 0  test7 = run (pCount pa) "aaaaa" --- | The parsers are instance of the class Monad and hence we can use the result of a previous parser to construct a following one:  @run (do  {l <- pCount pa; pExact l pb}) \"aaacabbb\"@+-- | The parsers are instance of the class Monad and hence we can use the +--   result of a previous parser to construct a following one:   ----- @--- Result: [\"b\",\"b\",\"b\",\"b\"]--- Correcting steps: ---     Deleted  'c' at position 3 expecting one of ['a', 'b']---     Inserted 'b' at position 8 expecting 'b'--- @+-- > run (do  {l <- pCount pa; pExact l pb}) "aaacabbb"+--+-- > Result: ["b","b","b","b"]+-- > Correcting steps: +-- >    Deleted  'c' at position 3 expecting one of ['a', 'b']+-- >    Inserted 'b' at position 8 expecting 'b'+--    test8 = run (do  {l <- pCount pa; pExact l pb}) "aaacabbb" pExact 0 p = pReturn [] pExact n p = (:) <$> p <*> pExact (n-1) p --- | The function @`amb`@ converts an ambigous parser into one which returns all possible parses: @run (amb ( (++) <$> pa2 <*> pa3 <|> (++) <$> pa3 <*> pa2))  \"aaaaa\"@+-- | The function @`amb`@ converts an ambigous parser into one which returns all possible parses:  ----- @--- Result: [\"aaaaa\",\"aaaaa\"]--- @+-- > run (amb ( (++) <$> pa2 <*> pa3 <|> (++) <$> pa3 <*> pa2))  "aaaaa"+--+-- > Result: ["aaaaa","aaaaa"]+--   test9 = run (amb ( (++) <$> pa2 <*> pa3 <|> (++) <$> pa3 <*> pa2))  "aaaaa" --- | The applicative style makes it very easy to merge recognsition and computing a result. As an example we parse a sequence of nested well formed parentheses pairs a,d---   compute the maximum nesting depth: @run ( max <$> pParens ((+1) <$> wfp) <*> wfp `opt` 0) \"((()))()(())\" @+-- | The applicative style makes it very easy to merge recognsition and computing a result. +--   As an example we parse a sequence of nested well formed parentheses pairs and+--   compute the maximum nesting depth with @`wfp`@:  ----- @--- Result: 3--- @+-- > run wfp "((()))()(())" +--+-- > Result: 3+--   test10 = run wfp "((()))()(())"+wfp :: Parser Int wfp =  max <$> pParens ((+1) <$> wfp) <*> wfp `opt` 0  -- | It is very easy to recognise infix expressions with any number of priorities and operators: ----- @ --- pOp (c, op) = op <$ pSym c--- sepBy p op = pChainl op p--- expr    = foldr sepBy factor [(pOp ('+', (+)) <|> pOp ('-', (-))),  pOp ('*' , (*))] --- factor  = pNatural <|> pParens expr--- @--- --- | which we can call:  @run expr \"15-3*5\"@+-- > operators       = [[('+', (+)), ('-', (-))],  [('*' , (*))], [('^', (^))]]+-- > same_prio  ops  = msum [ op <$ pSym c | (c, op) <- ops]+-- > expr            = foldr pChainl ( pNatural <|> pParens expr) (map same_prio operators) --  ----- @--- Result: 0--- @+-- which we can call:   ----- | Note that also here correction takes place: @run expr \"2 + + 3 5\"@+-- > run expr "15-3*5+2^5" ----- @--- Result: 37--- Correcting steps: ---     Deleted  ' ' at position 1 expecting one of ['0'..'9', '*', '-', '+']---     Inserted '0' at position 3 expecting one of ['(', '0'..'9']---     Deleted  ' ' at position 4 expecting one of ['(', '0'..'9']---     Deleted  ' ' at position 6 expecting one of ['0'..'9', '*', '-', '+']--- @+-- > Result: 32+--+-- Note that also here correction takes place: +--+-- > run expr "2 + + 3 5"+--+-- > Result: 37+-- > Correcting steps: +-- >    Deleted  ' ' at position 1 expecting one of ['0'..'9', '^', '*', '-', '+']+-- >    Deleted  ' ' at position 3 expecting one of ['(', '0'..'9']+-- >    Inserted '0' at position 4 expecting '0'..'9'+-- >    Deleted  ' ' at position 5 expecting one of ['(', '0'..'9']+-- >    Deleted  ' ' at position 7 expecting one of ['0'..'9', '^', '*', '-', '+']+--    test11 = run expr "15-3*5"+expr :: Parser Int+operators       = [[('+', (+)), ('-', (-))],  [('*' , (*))], [('^', (^))]]+same_prio  ops  = msum [ op <$ pSym c | (c, op) <- ops]+expr            = foldr pChainl ( pNatural <|> pParens expr) (map same_prio operators)  --- parsing expressions-pOp (c, op) = op <$ pSym c-expr    = foldr pChainl factor [(pOp ('+', (+)) <|> pOp ('-', (-))),  pOp ('*' , (*))] -factor  = pNatural <|> pParens expr--- parsing numbers-pDigit :: Parser Char-pDigit = pSym ('0', '9')-pDigitAsInt = digit2Int <$> pDigit -pNatural = foldl (\a b -> a * 10 + b ) 0 <$> pList1 pDigitAsInt-digit2Int a =  ord a - ord '0' --- | A common case where ambiguity arises is when we e.g. want to recognise identifiers, but only those which are not keywords. ---   The combinator `micro` inserts steps with a specfied cost in the result of the parser which can be used to disambiguate:+-- | A common case where ambiguity arises is when we e.g. want to recognise identifiers, +--   but only those which are not keywords. +--   The combinator `micro` inserts steps with a specfied cost in the result +--   of the parser which can be used to disambiguate: ----- @--- ident ::  Parser String--- ident = ((:) <$> pSym ('a','z') <*> pMunch (\x -> 'a' <= x && x <= 'z') `micro` 2) <* spaces--- idents = pList1 ident--- pKey keyw = pToken keyw `micro` 1 <* spaces--- spaces :: Parser String--- spaces = pMunch (==' ')--- takes_second_alt =   pList ident ---                \<|> (\ c t e -> [\"IfThenElse\"] ++  c   ++  t  ++  e) ---                    \<$ pKey \"if\"   \<*> pList_ng ident ---                    \<* pKey \"then\" \<*> pList_ng ident---                    \<* pKey \"else\" \<*> pList_ng ident  --- @+-- > +-- > ident ::  Parser String+-- > ident = ((:) <$> pSym ('a','z') <*> pMunch (\x -> 'a' <= x && x <= 'z') `micro` 2) <* spaces+-- > idents = pList1 ident+-- > pKey keyw = pToken keyw `micro` 1 <* spaces+-- > spaces :: Parser String+-- > spaces = pMunch (==' ')+-- > takes_second_alt =   pList ident +-- >                \<|> (\ c t e -> ["IfThenElse"] ++  c   ++  t  ++  e) +-- >                    \<$ pKey "if"   <*> pList_ng ident +-- >                    \<* pKey "then" <*> pList_ng ident+-- >                    \<* pKey "else" <*> pList_ng ident   ------ | A keyword is followed by a small cost @1@, which makes sure that identifiers which have a keyword as a prefix win over the keyword. Identifiers are however+--  A keyword is followed by a small cost @1@, which makes sure that +--  identifiers which have a keyword as a prefix win over the keyword. Identifiers are however --   followed by a cost @2@, with as result that in this case the keyword wins.  --   Note that a limitation of this approach is that keywords are only recognised as such when expected! -- --- @--- test13 = run takes_second_alt \"if a then if else c\"--- test14 = run takes_second_alt \"ifx a then if else c\"--- @+-- > test13 = run takes_second_alt "if a then if else c"+-- > test14 = run takes_second_alt "ifx a then if else c" -- --- with results:+-- with results for @test13@ and @test14@: ----- @--- Text.ParserCombinators.UU.Examples> test14--- Result: [\"IfThenElse\",\"a\",\"if\",\"c\"]--- Text.ParserCombinators.UU.Examples> test14--- Result: [\"ifx\",\"a\",\"then\",\"if\",\"else\",\"c\"]--- @+-- > Result: ["IfThenElse","a","if","c"]+-- > Result: ["ifx","a","then","if", "else","c"]+--  +-- | A mistake which is made quite often is to construct  a parser which can recognise a sequence of elements using one of the +--  derived combinators (say @`pList`@), but where the argument parser can recognise the empty string. +--  The derived combinators check whether this is the case and terminate the parsing process with an error message:+--+-- > run (pList spaces) ""+-- > Result: *** Exception: The combinator pList+-- >  requires that it's argument cannot recognise the empty string+--+-- > run (pMaybe spaces) " "+-- > Result: *** Exception: The combinator pMaybe+-- > requires that it's argument cannot recognise the empty string -ident ::  Parser String++test16 = run (pList spaces) "  "+ ident = ((:) <$> pSym ('a','z') <*> pMunch (\x -> 'a' <= x && x <= 'z') `micro` 2) <* spaces idents = pList1 ident @@ -237,17 +253,49 @@ test13 = run takes_second_alt "if a then if else c" test14 = run takes_second_alt "ifx a then if else c" +-- | For documentation of @`pMerged`@ and @`<||>`@ see the module "Text.ParserCombinators.UU.Merge":+--+-- > run  (,,) `pMerged` (list_of pDigit <||> list_of pLower <||> list_of pUpper) "1AabCD2D3d"+--+-- results in+-- +-- > Result: ("123","abd","ACDD")+--  +test15 = run ((,,) `pMerged` (list_of pDigit <||> list_of pLower <||> list_of pUpper)) "1AabCD2D3d" -munch = (,,) <$> pa <*> pMunch ( `elem` "^=*") <*> pb+-- | The function+--+-- > munch =  pMunch ( `elem` "^=*") +--+--  returns  the longest prefix of the input obeying the predicate:+--+-- > run munch "==^^**rest" +--+-- > Result: "==^^**"+-- > Correcting steps: +-- >    The token 'r' was not consumed by the parsing process.+-- >    The token 'e' was not consumed by the parsing process.+-- >    The token 's' was not consumed by the parsing process.+-- >    The token 't' was not consumed by the parsing process.+--  +munch :: Parser String+munch =  pMunch ( `elem` "^=*") + -- bracketing expressions-pParens :: Parser a -> Parser a pParens p =  pSym '(' *> p <* pSym ')' pBracks p =  pSym '[' *> p <* pSym ']' pCurlys p =  pSym '{' *> p <* pSym '}' +-- parsing numbers++pDigitAsInt = digit2Int <$> pDigit +pNatural = foldl (\a b -> a * 10 + b ) 0 <$> pList1 pDigitAsInt+digit2Int a =  ord a - ord '0'+ -- parsing letters and identifiers+pDigit = pSym ('0', '9') pLower  = pSym ('a','z') pUpper  = pSym ('A','Z') pLetter = pUpper <|> pLower@@ -259,15 +307,11 @@ pAnyToken = pAny pToken  -- parsing two alternatives and returning both rsults-pAscii = pSym ('\000', '\254')-pIntList       ::Parser [Int] +pIntList :: Parser [Int] pIntList       =  pParens ((pSym ';') `pListSep` (read <$> pList (pSym ('0', '9'))))-parseIntString :: Parser String-parseIntString = pList (pAscii)--parseBoth = pPair pIntList parseIntString+parseIntString =  pList ( pSym ('\000', '\254')) -pPair p q =  amb (Left <$> p <|> Right <$> q)+parseBoth =  amb (Left <$> pIntList <|> Right <$> parseIntString)  main :: IO () main = do test1
+ src/Text/ParserCombinators/UU/Merge.hs view
@@ -0,0 +1,38 @@+module Text.ParserCombinators.UU.Merge((<||>), pMerged, list_of) where++import Text.ParserCombinators.UU.Core+import Text.ParserCombinators.UU.Derived+import Text.ParserCombinators.UU.BasicInstances++-- | Often one wants to read a sequence of elements of different types, +--   where the actual order doe not matter. For the semantic processing however+--   it would be nice to get the elemnts of each type collected together: +-- +-- >    chars_digs = cat3 `pMerged` (list_of pDig <||> list_of pL <||> list_of pU)+-- +--  parsing \"12abCD1aV\" now returns \"121abaCDV\"; so the sequence of+--  recognised elements is stored in three lists, which are then passed +--  to @cat3 :: [a] -> [a] -> [a] -> [a]@ which concatenates the lists again++(<||>) ::  (c,     P st (d     -> d),     e -> f     -> g) +        -> (h,     P st (i     -> i),     g -> j     -> k) +        -> ((c,h), P st ((d,i) -> (d,i)), e -> (f,j) -> k)++(pe, pp, punp) <||> (qe, qp, qunp)+ =( (pe, qe)+  , mapFst <$> pp <|>  mapSnd <$> qp+  , \f (x, y) -> qunp (punp f x) y+  )++pMerged ::  c -> (d, P st (d -> d), c -> d -> e) -> P st e+sem `pMerged` (units, alts, unp)+ = let pres = alts <*> pres `opt` units in unp sem <$> pres++list_of :: P st c -> ([d], P st ([c] -> [c]),e -> e)+list_of p = ([], (:) <$> p, id)++mapFst f (a, b) = (f a, b)+mapSnd f (a, b) = (a, f b)+++
+ src/Text/ParserCombinators/UU/README.hs view
@@ -0,0 +1,22 @@+-- | Tis module contains some background information about a completely new version of the Utrecht parser combinator library.+--+--   Background material+--+--   The library is based on ideas described in the paper:+--+--   \@inproceedings{uuparsing:piriapolis, Author = {Swierstra, S.~Doaitse},  Booktitle = {Language Engineering and Rigorous Software Development}, Editor = {Bove, A. and Barbosa, L. and Pardo, A. and and Sousa Pinto, J.}, Pages = {252-300}, Place = {Piriapolis},  Publisher = {Spinger}, Series = {LNCS}, Title = {Combinator Parsers: a short tutorial},  Volume = {5520}, Year = {2009}}+--+--   which is also available as a technical report from <http://www.cs.uu.nl/research/techreps/repo/CS-2008/2008-044.pdf>+--+--   The first part of this report is a general introduction into parser combinators, whereas the second part contains the +--   motivation for and documentation of the current package.+--+--   We appreciate if you include a reference to the above documentation in any publication describing software in which you have used the library succesfully.+--+--   Any feedback on particular use of the library, and suggestions for extensions, are welcome at mailto:doaitse\@swierstra.net+--++module Text.ParserCombinators.UU.README () where+++dummy = undefined
uu-parsinglib.cabal view
@@ -1,5 +1,5 @@ Name:                uu-parsinglib-Version:             2.4.0+Version:             2.4.1 Build-Type:          Simple License:             MIT Copyright:           S Doaitse Swierstra @@ -16,14 +16,14 @@                      annotation free, applicative style parser combinators. In addition to this we even  provide a monadic interface.                      Parsers do analyse themselves to avoid commonly made errors                      .-                     The file Text.ParserCombinators.UU.Examples contains a ready-made main function,+                     The file "Text.ParserCombinators.UU.Examples" contains a ready-made main function,                      which can be called to see the error correction at work. It contains extensive haddock documentation;                       try all the small tests for yourself to see the correction process at work, and to get a                       feeling for how to use the various combinators.                      .-                     The file CHANGELOG which is distributed with the pacakge describes the list of changes and additions+                     The file "Text.ParserCombinators.UU.Changelog" contains a log of the most recent changes and additions                      .-                     The file README contains some references to background information+                     The file "Text.ParserCombinators.UU.README" contains some references to background information                      . Category:            Parsing @@ -32,8 +32,12 @@    Build-Depends:     base >= 4 && <5, haskell98   Exposed-modules:   Text.ParserCombinators.UU+                     Text.ParserCombinators.UU.CHANGELOG+                     Text.ParserCombinators.UU.README                      Text.ParserCombinators.UU.Core                        Text.ParserCombinators.UU.BasicInstances-                     Text.ParserCombinators.UU.Derived +                     Text.ParserCombinators.UU.Derived+                     Text.ParserCombinators.UU.Merge                       Text.ParserCombinators.UU.Examples                      Text.ParserCombinators.UU.Parsing+