1 % ----------------------------------------------------------------
4 % (c) The University of Glasgow, 1994-2000
8 {-# OPTIONS -fno-implicit-prelude #-}
10 module Text.ParserCombinators.ReadPrec
11 ( ReadPrec -- :: * -> *; instance Functor, Monad, MonadPlus
15 , minPrec -- :: Prec; = 0
17 -- primitive operations
18 , lift -- :: ReadP a -> ReadPrec a
19 , prec -- :: Prec -> ReadPrec a -> ReadPrec a
20 , step -- :: ReadPrec a -> ReadPrec a
21 , reset -- :: ReadPrec a -> ReadPrec a
24 , get -- :: ReadPrec Char
25 , look -- :: ReadPrec String
26 , (+++) -- :: ReadPrec a -> ReadPrec a -> ReadPrec a
27 , pfail -- :: ReadPrec a
28 , choice -- :: [ReadPrec a] -> ReadPrec a
31 , readPrec_to_P -- :: ReadPrec a -> (Int -> ReadP a)
32 , readP_to_Prec -- :: (Int -> ReadP a) -> ReadPrec a
33 , readPrec_to_S -- :: ReadPrec a -> (Int -> ReadS a)
34 , readS_to_Prec -- :: (Int -> ReadS a) -> ReadPrec a
39 import Text.ParserCombinators.ReadP
45 import qualified Text.ParserCombinators.ReadP as ReadP
53 import Control.Monad( MonadPlus(..) )
54 import GHC.Num( Num(..) )
59 %*********************************************************
61 \subsection{The readPrec type}
63 %*********************************************************
66 newtype ReadPrec a = P { unP :: Prec -> ReadP a }
68 -- Functor, Monad, MonadPlus
70 instance Functor ReadPrec where
71 fmap h (P f) = P (\n -> fmap h (f n))
73 instance Monad ReadPrec where
74 return x = P (\_ -> return x)
75 fail s = P (\_ -> fail s)
76 P f >>= k = P (\n -> do a <- f n; let P f' = k a in f' n)
78 instance MonadPlus ReadPrec where
91 %*********************************************************
93 \subsection{Operations over ReadPrec
95 %*********************************************************
98 lift :: ReadP a -> ReadPrec a
101 step :: ReadPrec a -> ReadPrec a
102 -- Increases the precedence context by one
103 step (P f) = P (\n -> f (n+1))
105 reset :: ReadPrec a -> ReadPrec a
106 -- Resets the precedence context to zero
107 reset (P f) = P (\n -> f minPrec)
109 prec :: Prec -> ReadPrec a -> ReadPrec a
110 -- (prec n p) checks that the precedence context is
111 -- less than or equal to n,
113 -- if so, parses p in context n
114 prec n (P f) = P (\c -> if c <= n then f n else ReadP.pfail)
117 %*********************************************************
119 \subsection{Derived operations}
121 %*********************************************************
127 look :: ReadPrec String
128 look = lift ReadP.look
130 (+++) :: ReadPrec a -> ReadPrec a -> ReadPrec a
131 P f1 +++ P f2 = P (\n -> f1 n ReadP.+++ f2 n)
134 pfail = lift ReadP.pfail
136 choice :: [ReadPrec a] -> ReadPrec a
137 choice ps = foldr (+++) pfail ps
141 %*********************************************************
143 \subsection{Converting between ReadPrec and ReadS
145 %*********************************************************
148 -- We define a local version of ReadS here,
149 -- because its "real" definition site is in GHC.Read
150 type ReadS a = String -> [(a,String)]
152 readPrec_to_P :: ReadPrec a -> (Int -> ReadP a)
153 readPrec_to_P (P f) = f
155 readP_to_Prec :: (Int -> ReadP a) -> ReadPrec a
156 readP_to_Prec f = P f
158 readPrec_to_S :: ReadPrec a -> (Int -> ReadS a)
159 readPrec_to_S (P f) n = readP_to_S (f n)
161 readS_to_Prec :: (Int -> ReadS a) -> ReadPrec a
162 readS_to_Prec f = P (\n -> readS_to_P (f n))