Last active
May 4, 2021 00:04
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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