Skip to content

Instantly share code, notes, and snippets.

@maciejsmolinski
Last active May 4, 2021 00:04
Show Gist options
  • Save maciejsmolinski/3c206085822dc0cac0f92fac586bdfea to your computer and use it in GitHub Desktop.
Save maciejsmolinski/3c206085822dc0cac0f92fac586bdfea to your computer and use it in GitHub Desktop.
Putting into practice lessons learned from "Write Yourself a Scheme in 48 hours" book https://en.wikibooks.org/wiki/Write_Yourself_a_Scheme_in_48_Hours/Parsing
module Main (main) where
import Prelude
import System.Environment
import Control.Monad
import Text.ParserCombinators.Parsec
main :: IO ()
main = do
(text:_) <- getArgs
putStrLn $ show $ parseExpr text
data BinOp
= Add Lang Lang
deriving (Show)
data Lang
= BinOp BinOp
| Val Int
deriving (Show)
numeric :: Parser Int
numeric = liftM (read) $ many1 digit
addOp :: Parser BinOp
addOp = do
a <- numeric
_ <- char '+'
b <- numeric
return $ Add (Val a) (Val b)
parseBinOp :: Parser Lang
parseBinOp = liftM BinOp addOp
parseNumeric :: Parser Lang
parseNumeric = liftM Val numeric
parser :: Parser Lang
parser = try parseBinOp <|> parseNumeric
parseExpr :: String -> Either ParseError Lang
parseExpr text = parse parser "Lang" text
eval :: Lang -> Int
eval (BinOp (Add a b)) = (eval a) + (eval b)
eval (Val a) = a
-- >>> parseExpr "123"
-- Right (Val 123)
-- >>> parseExpr "a12"
-- Left "Lang" (line 1, column 1):
-- unexpected "a"
-- expecting digit
-- >>> parseExpr "2+2"
-- Right (BinOp (Add (Val 2) (Val 2)))
-- >>> fmap eval $ parseExpr "2+2"-- <interactive>:1286:9: error:
-- Right 4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment