2021-02-24 17:50:53 +00:00
|
|
|
module Parser where
|
|
|
|
|
|
|
|
import Text.ParserCombinators.Parsec
|
|
|
|
|
|
|
|
import Expression
|
|
|
|
|
|
|
|
-- Receives a string, parses it, and returns an expression
|
|
|
|
parseExpression :: String -> Either ParseError Expression
|
|
|
|
parseExpression s = do
|
|
|
|
e <- parse anyExpressionParser "" s
|
|
|
|
return e
|
|
|
|
|
2021-02-27 23:20:42 +00:00
|
|
|
-- Parser for any possible expression
|
2021-02-24 17:50:53 +00:00
|
|
|
anyExpressionParser :: GenParser Char st Expression
|
|
|
|
anyExpressionParser = numberParser <|> symbolParser <|> sexprParser
|
|
|
|
|
2021-02-27 23:20:42 +00:00
|
|
|
-- Parser for an S-expr
|
2021-02-24 17:50:53 +00:00
|
|
|
sexprParser :: GenParser Char st Expression
|
|
|
|
sexprParser = do
|
|
|
|
_ <- spaces
|
|
|
|
_ <- char '('
|
|
|
|
es <- many1 (try $ spaces >> anyExpressionParser)
|
|
|
|
_ <- spaces
|
|
|
|
_ <- char ')' >> spaces
|
|
|
|
return $ SExpr es
|
|
|
|
|
2021-02-27 23:20:42 +00:00
|
|
|
-- Parser for a symbol
|
2021-02-24 17:50:53 +00:00
|
|
|
symbolParser :: GenParser Char st Expression
|
|
|
|
symbolParser = Symbol <$> do
|
|
|
|
c <- symbolChar
|
|
|
|
cs <- many (symbolChar <|> digit)
|
|
|
|
return $ c:cs
|
|
|
|
where symbolChar = letter <|> oneOf "!#$%&*+-/:<=>?@\\^_`~"
|
|
|
|
|
2021-02-27 23:20:42 +00:00
|
|
|
-- Parser for a number
|
2021-02-24 17:50:53 +00:00
|
|
|
numberParser :: GenParser Char st Expression
|
|
|
|
numberParser = do
|
2021-03-01 11:06:07 +00:00
|
|
|
intPart <- many1 digit
|
|
|
|
decPart <- option "" parseDecPart
|
|
|
|
return $ Number $ read (intPart ++ decPart)
|
|
|
|
where parseDecPart = do
|
|
|
|
p <- char '.'
|
|
|
|
dec <- many digit
|
|
|
|
return $ p:dec
|