Creating a lisp parser

This commit is contained in:
Zoe Roux
2021-11-03 10:24:39 +01:00
parent 18c035b217
commit 88481dd285
2 changed files with 17 additions and 11 deletions
+7 -6
View File
@@ -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 =
+10 -5
View File
@@ -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 (== ')')
pSExpr = pCharIf (== '(') *> (SExpr <$> some (tokenify pAtom)) <* pCharIf (== ')')
pLisp :: Parser [SExpr]
pLisp = some $ tokenify pSExpr