mirror of
https://github.com/zoriya/HAL.git
synced 2026-05-31 13:03:05 +00:00
Creating a lisp parser
This commit is contained in:
+7
-6
@@ -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
@@ -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
|
||||
Reference in New Issue
Block a user