, parens -- :: ReadPrec a -> ReadPrec a
, list -- :: ReadPrec a -> ReadPrec [a]
, choose -- :: [(String, ReadPrec a)] -> ReadPrec a
+ , readListDefault, readListPrecDefault,
-- Temporary
, readList__
)
import qualified Text.Read.Lex as L
-
-import Text.Read.Lex ( Lexeme(..) )
+-- Lex exports 'lex', which is also defined here,
+-- hence the qualified import.
+-- We can't import *anything* unqualified, because that
+-- confuses Haddock.
import Text.ParserCombinators.ReadPrec
import GHC.List
import GHC.Show -- isAlpha etc
import GHC.Base
+import GHC.Arr
ratioPrec = 7 -- Precedence of ':%' constructor
appPrec = 10 -- Precedence of applictaion
readListPrec = readS_to_Prec (\_ -> readList)
readListDefault :: Read a => ReadS [a]
+-- ^ Use this to define the 'readList' method, if you
+-- don't want a special case
readListDefault = readPrec_to_S readListPrec 0
readListPrecDefault :: Read a => ReadPrec [a]
+-- ^ Use this to define the 'readListPrec' method, if you
+-- don't want a special case
readListPrecDefault = list readPrec
------------------------------------------------------------------------
lexLitChar :: ReadS String -- As defined by H98
lexLitChar = readP_to_S (do { P.skipSpaces ;
- (s, Char _) <- P.gather L.lex ;
+ (s, L.Char _) <- P.gather L.lex ;
return s })
readLitChar :: ReadS Char -- As defined by H98
-readLitChar = readP_to_S (do { Char c <- L.lex ;
+readLitChar = readP_to_S (do { L.Char c <- L.lex ;
return c })
lexDigits :: ReadS String
------------------------------------------------------------------------
-- utility parsers
-lexP :: ReadPrec Lexeme
+lexP :: ReadPrec L.Lexeme
+-- ^ Parse a single lexeme
lexP = lift L.lex
paren :: ReadPrec a -> ReadPrec a
--- (paren p) parses (P0)
--- where p parses P0 in precedence context zero
-paren p = do Punc "(" <- lexP
- x <- reset p
- Punc ")" <- lexP
+-- ^ @(paren p)@ parses "(P0)"
+-- where @p@ parses "P0" in precedence context zero
+paren p = do L.Punc "(" <- lexP
+ x <- reset p
+ L.Punc ")" <- lexP
return x
parens :: ReadPrec a -> ReadPrec a
--- (parens p) parses P, (P0), ((P0)), etc,
--- where p parses P in the current precedence context
--- parses P0 in precedence context zero
+-- ^ @(parens p)@ parses "P", "(P0)", "((P0))", etc,
+-- where @p@ parses "P" in the current precedence context
+-- parses "P0" in precedence context zero
parens p = optional
where
optional = p +++ mandatory
mandatory = paren optional
list :: ReadPrec a -> ReadPrec [a]
+-- ^ @(list p)@ parses a list of things parsed by @p@,
+-- using the usual square-bracket syntax.
list readx =
parens
- ( do Punc "[" <- lexP
+ ( do L.Punc "[" <- lexP
(listRest False +++ listNext)
)
where
listRest started =
- do Punc c <- lexP
+ do L.Punc c <- lexP
case c of
"]" -> return []
"," | started -> listNext
return (x:xs)
choose :: [(String, ReadPrec a)] -> ReadPrec a
--- Parse the specified lexeme and continue as specified
--- Esp useful for nullary constructors
+-- ^ Parse the specified lexeme and continue as specified.
+-- Esp useful for nullary constructors; e.g.
+-- @choose [("A", return A), ("B", return B)]@
choose sps = foldr ((+++) . try_one) pfail sps
where
- try_one (s,p) = do { Ident s' <- lexP ;
+ try_one (s,p) = do { L.Ident s' <- lexP ;
if s == s' then p else pfail }
\end{code}
instance Read Char where
readPrec =
parens
- ( do Char c <- lexP
+ ( do L.Char c <- lexP
return c
)
readListPrec =
parens
- ( do String s <- lexP -- Looks for "foo"
+ ( do L.String s <- lexP -- Looks for "foo"
return s
+++
readListPrecDefault -- Looks for ['f','o','o']
instance Read Bool where
readPrec =
parens
- ( do Ident s <- lexP
+ ( do L.Ident s <- lexP
case s of
"True" -> return True
"False" -> return False
instance Read Ordering where
readPrec =
parens
- ( do Ident s <- lexP
+ ( do L.Ident s <- lexP
case s of
"LT" -> return LT
"EQ" -> return EQ
readPrec =
parens
( prec appPrec
- ( do Ident "Nothing" <- lexP
+ ( do L.Ident "Nothing" <- lexP
return Nothing
+++
- do Ident "Just" <- lexP
+ do L.Ident "Just" <- lexP
x <- step readPrec
return (Just x)
)
readPrec =
parens
( prec appPrec
- ( do Ident "Left" <- lexP
+ ( do L.Ident "Left" <- lexP
x <- step readPrec
return (Left x)
+++
- do Ident "Right" <- lexP
+ do L.Ident "Right" <- lexP
y <- step readPrec
return (Right y)
)
readListPrec = readListPrecDefault
readList = readListDefault
-instance Read Lexeme where
+instance (Ix a, Read a, Read b) => Read (Array a b) where
+ readPrec = parens $ prec appPrec $
+ do L.Ident "array" <- lexP
+ bounds <- step readPrec
+ vals <- step readPrec
+ return (array bounds vals)
+
+ readListPrec = readListPrecDefault
+ readList = readListDefault
+
+instance Read L.Lexeme where
readPrec = lexP
readListPrec = readListPrecDefault
readList = readListDefault
%*********************************************************
\begin{code}
-readNumber :: Num a => (Lexeme -> Maybe a) -> ReadPrec a
+readNumber :: Num a => (L.Lexeme -> Maybe a) -> ReadPrec a
-- Read a signed number
readNumber convert =
parens
( do x <- lexP
case x of
- Symbol "-" -> do n <- readNumber convert
- return (negate n)
+ L.Symbol "-" -> do n <- readNumber convert
+ return (negate n)
_ -> case convert x of
Just n -> return n
Nothing -> pfail
)
-convertInt :: Num a => Lexeme -> Maybe a
-convertInt (Int i) = Just (fromInteger i)
-convertInt _ = Nothing
+convertInt :: Num a => L.Lexeme -> Maybe a
+convertInt (L.Int i) = Just (fromInteger i)
+convertInt _ = Nothing
-convertFrac :: Fractional a => Lexeme -> Maybe a
-convertFrac (Int i) = Just (fromInteger i)
-convertFrac (Rat r) = Just (fromRational r)
-convertFrac _ = Nothing
+convertFrac :: Fractional a => L.Lexeme -> Maybe a
+convertFrac (L.Int i) = Just (fromInteger i)
+convertFrac (L.Rat r) = Just (fromRational r)
+convertFrac _ = Nothing
instance Read Int where
readPrec = readNumber convertInt
readPrec =
parens
( prec ratioPrec
- ( do x <- step readPrec
- Symbol "%" <- lexP
- y <- step readPrec
+ ( do x <- step readPrec
+ L.Symbol "%" <- lexP
+ y <- step readPrec
return (x % y)
)
)
parens
( paren
( do x <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
y <- readPrec
return (x,y)
)
parens
( paren
( do x <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
y <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
z <- readPrec
return (x,y,z)
)
parens
( paren
( do w <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
x <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
y <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
z <- readPrec
return (w,x,y,z)
)
parens
( paren
( do v <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
w <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
x <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
y <- readPrec
- Punc "," <- lexP
+ L.Punc "," <- lexP
z <- readPrec
return (v,w,x,y,z)
)
-- Stability : provisional
-- Portability : portable
--
+-- This library defines parser combinators for precedence parsing.
+
-----------------------------------------------------------------------------
module Text.ParserCombinators.ReadPrec
Prec, -- :: *; = Int
minPrec, -- :: Prec; = 0
- -- * Primitive operations
+ -- * Precedence operations
lift, -- :: ReadP a -> ReadPrec a
prec, -- :: Prec -> ReadPrec a -> ReadPrec a
step, -- :: ReadPrec a -> ReadPrec a
reset, -- :: ReadPrec a -> ReadPrec a
-- * Other operations
+ -- All are based directly on their similarly-naned 'ReadP' counterparts.
get, -- :: ReadPrec Char
look, -- :: ReadPrec String
(+++), -- :: ReadPrec a -> ReadPrec a -> ReadPrec a
pfail, -- :: ReadPrec a
choice, -- :: [ReadPrec a] -> ReadPrec a
- -- converters
+ -- * Converters
readPrec_to_P, -- :: ReadPrec a -> (Int -> ReadP a)
readP_to_Prec, -- :: (Int -> ReadP a) -> ReadPrec a
readPrec_to_S, -- :: ReadPrec a -> (Int -> ReadS a)
-- Operations over ReadPrec
lift :: ReadP a -> ReadPrec a
+-- ^ Lift a predence-insensitive 'ReadP' to a 'ReadPrec'
lift m = P (\_ -> m)
step :: ReadPrec a -> ReadPrec a
--- Increases the precedence context by one
+-- ^ Increases the precedence context by one
step (P f) = P (\n -> f (n+1))
reset :: ReadPrec a -> ReadPrec a
--- Resets the precedence context to zero
+-- ^ Resets the precedence context to zero
reset (P f) = P (\n -> f minPrec)
prec :: Prec -> ReadPrec a -> ReadPrec a
--- (prec n p) checks that the precedence context is
+-- ^ @(prec n p)@ checks that the precedence context is
-- less than or equal to n,
--- if not, fails
--- if so, parses p in context n
+-- * if not, fails
+-- * if so, parses p in context n
prec n (P f) = P (\c -> if c <= n then f n else ReadP.pfail)
-- ---------------------------------------------------------------------------
-- Stability : provisional
-- Portability : portable
--
--- Exiting the program.
+-- The "Text.Read" library is the canonical library to import for
+-- 'Read'-class facilities. It offers an extended and much improved
+-- 'Read' class, which constitutes a proposed alternative to the
+-- Haskell98 'Read'. In particular, writing parsers is easier, and
+-- the parsers are much more efficient.
--
-----------------------------------------------------------------------------
module Text.Read (
+ -- * The 'Read' class
+ Read(..), -- The Read class
ReadS, -- String -> Maybe (a,String)
- Read(
- readsPrec, -- :: Int -> ReadS a
- readList -- :: ReadS [a]
- ),
+
+ -- * Haskell 98 functions
reads, -- :: (Read a) => ReadS a
read, -- :: (Read a) => String -> a
readParen, -- :: Bool -> ReadS a -> ReadS a
lex, -- :: ReadS String
+
+ -- * New parsing functions
+ module Text.ParserCombinators.ReadPrec,
+ L.Lexeme(..),
+ lexP, -- :: ReadPrec Lexeme
+ readListDefault, -- :: Read a => ReadS [a]
+ readListPrecDefault, -- :: Read a => ReadPrec [a]
+
) where
#ifdef __GLASGOW_HASKELL__
import GHC.Read
+import Text.ParserCombinators.ReadPrec
+import qualified Text.Read.Lex as L
#endif