From 88481dd285ccbc7324b390dde9d6c55da1c9a212 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Wed, 3 Nov 2021 10:24:39 +0100 Subject: [PATCH] Creating a lisp parser --- src/BasicParser.hs | 13 +++++++------ src/LispParser.hs | 15 ++++++++++----- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/BasicParser.hs b/src/BasicParser.hs index b1bcfd7..a2dfb24 100644 --- a/src/BasicParser.hs +++ b/src/BasicParser.hs @@ -54,14 +54,17 @@ pCharIf predicate = Parser subParse | otherwise = (Nothing, c:cs) pUntil :: (Char -> Bool) -> Parser String -pUntil predicate = many $ pCharIf (not . predicate) +pUntil predicate = some $ pCharIf (not . predicate) + +pToken :: Parser String +pToken = pUntil $ \x -> isSpace x || x == ')' || x == '(' pDigit :: Parser Char pDigit = pCharIf isDigit pInt :: Parser Int -pInt = (pCharIf (== '-') >> (negate . read <$> some pDigit)) - <|> read <$> some pDigit +pInt = (pCharIf (== '-') >> negate <$> unMaybe (readMaybe <$> pToken)) + <|> unMaybe (readMaybe <$> pToken) unMaybe :: Parser (Maybe a) -> Parser a unMaybe p = Parser $ \x -> case parse p x of @@ -76,9 +79,7 @@ pFloat = <|> unMaybe floating where floating :: Parser (Maybe Float) - floating = do - value <- many $ pCharIf (\x -> isNumber x || x == '.') - return $ readMaybe value + floating = readMaybe <$> pToken tokenify :: Parser a -> Parser a tokenify input = diff --git a/src/LispParser.hs b/src/LispParser.hs index 1f64f10..8581eaa 100644 --- a/src/LispParser.hs +++ b/src/LispParser.hs @@ -1,14 +1,19 @@ +module LispParser where + import BasicParser -import Expressions -import Control.Applicative -import Data.Char + ( Parser, pCharIf, pUntil, pInt, pFloat, tokenify, pToken ) +import Expressions ( SExpr(..), Atom(..) ) +import Control.Applicative ( Alternative(some, (<|>)) ) pAtom :: Parser Atom pAtom = AInt <$> pInt <|> AFloat <$> pFloat <|> pCharIf (== '"') *> (AString <$> pUntil (== '"')) <* pCharIf (== '"') <|> - ASymbol <$> pUntil isSpace + ASymbol <$> pToken pSExpr :: Parser SExpr -pSExpr = pCharIf (== '(') *> (SExpr <$> some (tokenify pAtom)) <* pCharIf (== ')') \ No newline at end of file +pSExpr = pCharIf (== '(') *> (SExpr <$> some (tokenify pAtom)) <* pCharIf (== ')') + +pLisp :: Parser [SExpr] +pLisp = some $ tokenify pSExpr \ No newline at end of file