Skip to content

Instantly share code, notes, and snippets.

@zporter
Created December 3, 2015 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zporter/adc5a347a8a12b4d6082 to your computer and use it in GitHub Desktop.
Save zporter/adc5a347a8a12b4d6082 to your computer and use it in GitHub Desktop.
EDX: FP 101 Parser
> module Parsing where
>
>
> import Data.Char
> import Control.Monad
> import Control.Applicative
>
> infixr 5 +++
The monad of parsers
--------------------
> newtype Parser a = P (String -> [(a,String)])
> instance Functor Parser where
> fmap = liftM
> instance Applicative Parser where
> pure v = P (\inp -> [(v, inp)])
> (<*>) = ap
>
> instance Monad Parser where
> return v = pure v
> p >>= f = P (\ inp ->
> case parse p inp of
> [(v, out)] -> parse (f v) out
> [] -> [])
>
> instance Alternative Parser where
> empty = P (\inp -> [])
> (<|>) p q = P (\inp -> case parse p inp of
> [] -> parse q inp
> [(v, out)] -> [(v, out)])
>
> instance MonadPlus Parser where
Basic parsers
-------------
> failure :: Parser a
> failure = mzero
>
> item :: Parser Char
> item = P (\inp -> case inp of
> [] -> []
> (x:xs) -> [(x,xs)])
>
> parse :: Parser a -> String -> [(a,String)]
> parse (P p) inp = p inp
Choice
------
> (+++) :: Parser a -> Parser a -> Parser a
> p +++ q = p `mplus` q
Derived primitives
------------------
> sat :: (Char -> Bool) -> Parser Char
> sat p = do x <- item
> if p x then return x else failure
>
> digit :: Parser Char
> digit = sat isDigit
>
> lower :: Parser Char
> lower = sat isLower
>
> upper :: Parser Char
> upper = sat isUpper
>
> letter :: Parser Char
> letter = sat isAlpha
>
> alphanum :: Parser Char
> alphanum = sat isAlphaNum
>
> char :: Char -> Parser Char
> char x = sat (== x)
>
> string :: String -> Parser String
> string [] = return []
> string (x:xs) = do char x
> string xs
> return (x:xs)
>
> many' :: Parser a -> Parser [a]
> many' p = many1 p +++ return []
>
> many1 :: Parser a -> Parser [a]
> many1 p = do v <- p
> vs <- many' p
> return (v:vs)
>
> ident :: Parser String
> ident = do x <- lower
> xs <- many' alphanum
> return (x:xs)
>
> nat :: Parser Int
> nat = do xs <- many1 digit
> return (read xs)
>
> int :: Parser Int
> int = error "You must implement int"
>
> space :: Parser ()
> space = do many' (sat isSpace)
> return ()
>
> comment :: Parser ()
> comment = error "You must implement comment"
>
> expr :: Parser Int
> expr = error "You must implement expr"
Ignoring spacing
----------------
> token :: Parser a -> Parser a
> token p = do space
> v <- p
> space
> return v
>
> identifier :: Parser String
> identifier = token ident
>
> natural :: Parser Int
> natural = token nat
>
> integer :: Parser Int
> integer = token int
>
> symbol :: String -> Parser String
> symbol xs = token (string xs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment