1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
{-# OPTIONS -fno-implicit-prelude #-}
-----------------------------------------------------------------------------
-- |
-- Module : Text.ParserCombinators.ReadPrec
-- Copyright : (c) The University of Glasgow 2002
-- License : BSD-style (see the file libraries/base/LICENSE)
--
-- Maintainer : libraries@haskell.org
-- Stability : provisional
-- Portability : non-portable (uses Text.ParserCombinators.ReadP)
--
-- This library defines parser combinators for precedence parsing.
-----------------------------------------------------------------------------
module Text.ParserCombinators.ReadPrec
(
ReadPrec, -- :: * -> *; instance Functor, Monad, MonadPlus
-- * Precedences
Prec, -- :: *; = Int
minPrec, -- :: Prec; = 0
-- * 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
(<++), -- :: ReadPrec a -> ReadPrec a -> ReadPrec a
pfail, -- :: ReadPrec a
choice, -- :: [ReadPrec a] -> ReadPrec a
-- * 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)
readS_to_Prec, -- :: (Int -> ReadS a) -> ReadPrec a
)
where
import Text.ParserCombinators.ReadP
( ReadP
, ReadS
, readP_to_S
, readS_to_P
)
import qualified Text.ParserCombinators.ReadP as ReadP
( get
, look
, (+++), (<++)
, pfail
)
import Control.Monad( MonadPlus(..) )
#ifdef __GLASGOW_HASKELL__
import GHC.Num( Num(..) )
import GHC.Base
#endif
-- ---------------------------------------------------------------------------
-- The readPrec type
newtype ReadPrec a = P { unP :: Prec -> ReadP a }
-- Functor, Monad, MonadPlus
instance Functor ReadPrec where
fmap h (P f) = P (\n -> fmap h (f n))
instance Monad ReadPrec where
return x = P (\_ -> return x)
fail s = P (\_ -> fail s)
P f >>= k = P (\n -> do a <- f n; let P f' = k a in f' n)
instance MonadPlus ReadPrec where
mzero = pfail
mplus = (+++)
-- precedences
type Prec = Int
minPrec :: Prec
minPrec = 0
-- ---------------------------------------------------------------------------
-- 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
step (P f) = P (\n -> f (n+1))
reset :: ReadPrec a -> ReadPrec a
-- ^ 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
-- less than or equal to 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)
-- ---------------------------------------------------------------------------
-- Derived operations
get :: ReadPrec Char
get = lift ReadP.get
look :: ReadPrec String
look = lift ReadP.look
(+++) :: ReadPrec a -> ReadPrec a -> ReadPrec a
P f1 +++ P f2 = P (\n -> f1 n ReadP.+++ f2 n)
(<++) :: ReadPrec a -> ReadPrec a -> ReadPrec a
P f1 <++ P f2 = P (\n -> f1 n ReadP.<++ f2 n)
pfail :: ReadPrec a
pfail = lift ReadP.pfail
choice :: [ReadPrec a] -> ReadPrec a
choice ps = foldr (+++) pfail ps
-- ---------------------------------------------------------------------------
-- Converting between ReadPrec and Read
readPrec_to_P :: ReadPrec a -> (Int -> ReadP a)
readPrec_to_P (P f) = f
readP_to_Prec :: (Int -> ReadP a) -> ReadPrec a
readP_to_Prec f = P f
readPrec_to_S :: ReadPrec a -> (Int -> ReadS a)
readPrec_to_S (P f) n = readP_to_S (f n)
readS_to_Prec :: (Int -> ReadS a) -> ReadPrec a
readS_to_Prec f = P (\n -> readS_to_P (f n))
|