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 151 152
|
-----------------------------------------------------------------------------
-- |
-- Module : Text.ParserCombinators.Parsec.Combinator
-- Copyright : (c) Daan Leijen 1999-2001
-- License : BSD-style (see the file libraries/parsec/LICENSE)
--
-- Maintainer : daan@cs.uu.nl
-- Stability : provisional
-- Portability : portable
--
-- Commonly used generic combinators
--
-----------------------------------------------------------------------------
module Text.ParserCombinators.Parsec.Combinator
( choice
, count
, between
, option, 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 :: [GenParser tok st a] -> GenParser tok st a
choice ps = foldr (<|>) mzero ps
option :: a -> GenParser tok st a -> GenParser tok st a
option x p = p <|> return x
optional :: GenParser tok st a -> GenParser tok st ()
optional p = do{ p; return ()} <|> return ()
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 :: GenParser tok st a -> GenParser tok st ()
skipMany1 p = do{ p; skipMany p }
{-
skipMany p = scan
where
scan = do{ p; scan } <|> return ()
-}
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 [])
-}
sepBy1,sepBy :: GenParser tok st a -> GenParser tok st sep -> GenParser tok st [a]
sepBy p sep = sepBy1 p sep <|> return []
sepBy1 p sep = do{ x <- p
; xs <- many (sep >> p)
; return (x:xs)
}
sepEndBy1, sepEndBy :: 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 = sepEndBy1 p sep <|> return []
endBy1,endBy :: 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 = many (do{ x <- p; sep; return x })
count :: Int -> GenParser tok st a -> GenParser tok st [a]
count n p | n <= 0 = return []
| otherwise = sequence (replicate n p)
chainr,chainl :: 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 = chainl1 p op <|> return x
chainr1,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 = scan
where
scan = do{ x <- p; rest x }
rest x = do{ f <- op
; y <- scan
; return (f x y)
}
<|> return x
-----------------------------------------------------------
-- Tricky combinators
-----------------------------------------------------------
anyToken :: Show tok => GenParser tok st tok
anyToken = tokenPrim show (\pos tok toks -> pos) Just
eof :: Show tok => GenParser tok st ()
eof = notFollowedBy anyToken <?> "end of input"
notFollowedBy :: Show tok => GenParser tok st tok -> GenParser tok st ()
notFollowedBy p = try (do{ c <- p; unexpected (show [c]) }
<|> return ()
)
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 :: GenParser tok st a -> GenParser tok st a
lookAhead p = do{ state <- getParserState
; x <- p
; setParserState state
; return x
}
|