4 -- Author: Yoshikuni Jujo <PAF01143@nifty.ne.jp>
6 -- This file is part of mtlparse library
8 -- mtlparse is free software: you can redistribute it and/or modify
9 -- it under the terms of the GNU Lesser General Public License as
10 -- published by the Free Software Foundation, either version 3 of the
11 -- License, or any later version.
13 -- mtlparse is distributed in the hope that it will be useful,
14 -- but WITHOUT ANY WARRANGY; without even the implied warranty of
15 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 -- GNU Lesser General Public License for more details.
18 -- You should have received a copy of the GNU Lesser General Public
19 -- License along with this program. If not, see
20 -- <http://www.gnu.org/licenses/>.
22 {-# LANGUAGE MultiParamTypeClasses #-}
23 {-# LANGUAGE FunctionalDependencies #-}
24 {-# LANGUAGE FlexibleInstances #-}
25 {-# LANGUAGE UndecidableInstances #-}
27 module Text
.ParserCombinators
.MTLParse
.MTLParseCore
(
30 MonadParse
( spot
, spotBack
, still
, parseNot
, getHere
, putHere
,
63 , module Control
.Monad
64 , module Control
.Monad
.Trans
68 import Control
.Applicative
( Applicative
(..), Alternative
(..) )
69 import Control
.Monad
( MonadPlus
, mplus
, mzero
, liftM, ap )
70 import Control
.Monad
.Trans
( MonadTrans
( lift
),
72 import Control
.Monad
.Reader
( MonadReader
( ask
, local
),
73 ReaderT
( ReaderT
, runReaderT
),
75 import Control
.Monad
.Writer
( MonadWriter
( tell
, listen
, pass
),
76 WriterT
( WriterT
, runWriterT
),
78 import Control
.Monad
.State
( MonadState
( get
, put
),
79 StateT
( StateT
, runStateT
),
81 import Control
.Arrow
( first
, second
)
82 import Data
.Monoid
( Monoid
( mempty
) )
84 class Monad m
=> MonadParse a m | m
-> a
where
85 spot
:: ( a
-> Bool ) -> m a
86 spotBack
:: ( a
-> Bool ) -> m a
88 parseNot
:: c
-> m b
-> m c
89 getHere
:: m
( [a
], [a
] )
90 putHere
:: ( [a
], [a
] ) -> m
()
91 noBacktrack
:: m b
-> m b
93 token
, tokenBack
:: ( Eq a
, MonadParse a m
) => a
-> m a
95 tokenBack x
= spotBack
(==x
)
97 getsHere
:: MonadParse a m
=> ( ([a
], [a
]) -> b
) -> m b
98 modifyHere
:: MonadParse a m
=> ( ([a
], [a
]) -> ([a
], [a
]) ) -> m
()
99 getsHere f
= liftM f getHere
100 modifyHere f
= getHere
>>= putHere
. f
102 getBack
, getForward
:: MonadParse a m
=> m
[ a
]
103 getsBack
, getsForward
:: MonadParse a m
=> ( [a
] -> [a
] ) -> m
[ a
]
104 getBack
= getsHere
fst
105 getForward
= getsHere
snd
106 getsBack f
= getsHere
( f
.fst )
107 getsForward f
= getsHere
( f
.snd )
109 putBack
, putForward
:: MonadParse a m
=> [ a
] -> m
()
110 modifyBack
, modifyForward
:: MonadParse a m
=> ( [a
] -> [a
] ) -> m
()
111 putBack b
= getsHere
snd >>= putHere
. (,) b
112 putForward f
= getsHere
fst >>= putHere
. flip (,) f
113 modifyBack
= modifyHere
. first
114 modifyForward
= modifyHere
. second
116 -- | A parse monad where /a/ is the type of the token to parse
117 -- and /b/ is the type of the /return value/.
120 = Parse
{ runParse
:: ( [a
], [a
] ) -> [ ( b
, ([a
], [a
]) ) ] }
122 -- Parse is instance of Functor Monad MonadPlus MonadReader MonadParse
124 instance Functor
( Parse p
) where
125 fmap f m
= Parse
$ liftM ( first f
) . runParse m
127 instance Applicative
( Parse p
) where
128 pure
= return; (<*>) = ap
130 instance Alternative
(Parse p
) where
134 instance Monad
( Parse a
) where
135 return = Parse
. \val inp
-> [ (val
, inp
) ]
137 = Parse
( \st
-> concat
138 [ runParse
( f a
) rest |
( a
, rest
) <- pr st
] )
140 instance MonadPlus
( Parse a
) where
141 mzero
= Parse
$ const []
142 Parse p1 `mplus` Parse p2
= Parse
$ \inp
-> p1 inp
++ p2 inp
144 instance MonadReader
( [a
], [a
] ) ( Parse a
) where
145 ask
= Parse
$ \inp
-> [ (inp
, inp
) ]
146 local f m
= Parse
$ runParse m
. f
148 instance MonadState
( [a
], [a
] ) ( Parse a
) where
149 get
= Parse
$ \inp
-> [ (inp
, inp
) ]
150 put inp
= Parse
$ const [ ((), inp
) ]
152 instance MonadParse a
( Parse a
) where
156 | p x
= [ ( x
, (x
:pre
, xs
) ) ]
159 spotBack
= Parse
. sptbck
161 sptbck p
( x
:xs
, post
)
162 | p x
= [ ( x
, (xs
, x
:post
) ) ]
164 sptbck _
( [], _
) = []
165 still p
= Parse
$ \inp
-> do ( ret
, _
) <- runParse p inp
167 parseNot x
( Parse p
) = Parse
$ \inp
-> case p inp
of
172 noBacktrack p
= Parse
$ (:[]) . head . runParse p
174 evalParse
:: Parse a b
-> ( [a
], [a
] ) -> [ b
]
175 evalParse m
= map fst . runParse m
177 execParse
:: Parse a b
-> ( [a
], [a
] ) -> [ ([a
], [a
]) ]
178 execParse m
= map snd . runParse m
180 mapParse
:: ( ( b
, ([a
], [a
]) ) -> ( c
, ([a
], [a
]) ) ) -> Parse a b
182 mapParse f m
= Parse
$ map f
. runParse m
184 withParse
:: ( ([a
], [a
]) -> ([a
], [a
]) ) -> Parse a b
-> Parse a b
185 withParse f m
= Parse
$ runParse m
. f
187 -- | A parse monad for encaplulating an inner monad.
190 = ParseT
{ runParseT
:: ( [a
], [a
] ) -> m
[ ( b
, ([a
], [a
]) ) ] }
192 instance Monad m
=> Functor
( ParseT a m
) where
193 fmap f m
= ParseT
$ \a -> do
194 rets
<- runParseT m a
195 return [ ( f a
', rst
) |
( a
', rst
) <- rets
]
197 instance Monad m
=> Applicative
( ParseT a m
) where
198 pure
= return; (<*>) = ap
200 instance Monad m
=> Alternative
(ParseT a m
) where
204 instance Monad m
=> Monad
( ParseT a m
) where
205 return b
= ParseT
$ \a -> return [ (b
, a
) ]
209 liftM concat . mapM ( \(a
', rest
) -> runParseT
(f a
') rest
)
211 instance Monad m
=> MonadPlus
( ParseT a m
) where
212 mzero
= ParseT
$ const $ return []
213 ParseT p1 `mplus` ParseT p2
= ParseT
$ \inp
-> do ret1
<- p1 inp
215 return $ ret1
++ ret2
217 instance Monad m
=> MonadParse a
( ParseT a m
) where
221 | p x
= return [ ( x
, (x
:pre
, xs
) ) ]
222 |
otherwise = return []
223 spt _
( _
, [] ) = return []
224 spotBack
= ParseT
. sptbck
226 sptbck p
( x
:xs
, post
)
227 | p x
= return [ ( x
, (xs
, x
:post
) ) ]
228 |
otherwise = return []
229 sptbck _
( [], _
) = return []
230 still p
= ParseT
$ \inp
-> do
231 rets
<- runParseT p inp
232 return [ ( ret
, inp
) |
( ret
, _
) <- rets
]
233 parseNot x
( ParseT p
) = ParseT
$ \inp
-> do
236 [] -> return [ (x
, inp
) ]
240 noBacktrack p
= ParseT
$ \inp
-> do ret
<- runParseT p inp
243 instance Monad m
=> MonadReader
( [a
], [a
] ) ( ParseT a m
) where
244 ask
= ParseT
$ \inp
-> return [ (inp
, inp
) ]
245 local f m
= ParseT
$ runParseT m
. f
247 instance Monad m
=> MonadState
( [a
], [a
] ) ( ParseT a m
) where
248 get
= ParseT
$ \inp
-> return [ (inp
, inp
) ]
249 put inp
= ParseT
$ \_
-> return [ ((), inp
) ]
251 instance MonadTrans
( ParseT a
) where
252 lift m
= ParseT
$ \a -> do
256 instance MonadIO m
=> MonadIO
( ParseT a m
) where
257 liftIO
= lift
. liftIO
259 instance MonadWriter w m
=> MonadWriter w
( ParseT a m
) where
261 listen m
= ParseT
$ \inp
-> do
262 ( al
, w
) <- listen
( runParseT m inp
)
263 return [ ( (ret
, w
), inp
' ) |
( ret
, inp
' ) <- al
]
264 pass m
= ParseT
$ \inp
-> pass
$ do
265 al
<- runParseT m inp
267 ( [ ( ret
, inp
' ) |
( (ret
, _
), inp
' ) <- al
] ,
268 snd . fst $ head al
)
270 evalParseT
:: ( Monad m
) => ParseT a m b
-> ( [a
], [a
] ) -> m
[ b
]
271 evalParseT m inp
= do
272 al
<- runParseT m inp
276 :: ( Monad m
) => ParseT a m b
-> ( [a
], [a
] ) -> m
[ ([a
], [a
]) ]
277 execParseT m inp
= do
278 al
<- runParseT m inp
282 :: ( m
[ ( b
, ([a
], [a
]) ) ] -> n
[ (c
, ( [a
], [a
]) ) ] )
283 -> ParseT a m b
-> ParseT a n c
284 mapParseT f m
= ParseT
$ f
. runParseT m
286 withParseT
:: ( ([a
], [a
]) -> ([a
], [a
]) ) -> ParseT a m b
288 withParseT f m
= ParseT
$ runParseT m
. f
290 -- MonadParse instance for other monad transformers
292 instance ( MonadParse a m
) => MonadParse a
( ReaderT s m
) where
294 spotBack
= lift
. spotBack
295 still
= mapReaderT still
296 parseNot x p
= ReaderT
$ \r -> parseNot x
( runReaderT p r
)
297 getHere
= lift getHere
298 putHere
= lift
. putHere
299 noBacktrack
= mapReaderT noBacktrack
301 instance ( MonadParse a m
, Monoid w
) => MonadParse a
( WriterT w m
)
304 spotBack
= lift
. spotBack
305 still
= mapWriterT still
306 parseNot x
= WriterT
. parseNot
(x
, mempty
) . runWriterT
307 getHere
= lift getHere
308 putHere
= lift
. putHere
309 noBacktrack
= mapWriterT noBacktrack
311 instance ( MonadParse a m
) => MonadParse a
( StateT r m
) where
313 spotBack
= lift
. spotBack
314 still
= mapStateT still
315 parseNot x p
= StateT
$ \s
-> parseNot
( x
, s
) ( runStateT p s
)
316 getHere
= lift getHere
317 putHere
= lift
. putHere
318 noBacktrack
= mapStateT noBacktrack