module Text.Chatty.Parser where
import Control.Monad
import Data.Char
import Text.Chatty.Scanner
class MonadScanner m => MonadParser m where
pabort :: m a
(??) :: Eq a => m a -> m a -> m a
(???) :: m a -> m a -> m a
ptry :: MonadPlus n => m a -> m (n a)
request :: MonadScanner m => m Char
request = mscan1
match :: MonadParser m => Char -> m Char
match c = do
k <- request
if k == c then return c else pabort
matchs :: MonadParser m => String -> m String
matchs [] = return []
matchs (c:cs) = do
match c
matchs cs
return (c:cs)
white :: MonadParser m => m Char
white = do
k <- request
if isSpace k then return k else pabort
digit :: MonadParser m => m Int
digit = do
k <- request
if isDigit k then return (read [k]) else pabort
alpha :: MonadParser m => m Char
alpha = do
k <- request
if isAlpha k then return k else pabort
anum :: MonadParser m => m Char
anum = do
k <- request
if isAlphaNum k then return k else pabort
possibly :: MonadParser m => m a -> m (Maybe a)
possibly f = liftM Just f ??? return Nothing
many :: MonadParser m => m a -> m [a]
many f = do
x <- possibly f
case x of
Nothing -> return []
Just x -> do
xs <- many f
return (x : xs)
some :: MonadParser m => m a -> m [a]
some f = do
x <- f
xs <- many f
return (x : xs)
number :: MonadParser m => m Int
number = do
many white
ds <- some digit
many white
return $ foldl (\k n -> k * 10 + n) 0 ds