Created
December 3, 2015 19:57
-
-
Save zporter/adc5a347a8a12b4d6082 to your computer and use it in GitHub Desktop.
EDX: FP 101 Parser
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
> 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