Skip to content

Instantly share code, notes, and snippets.

@jeremysinger
Last active October 30, 2023 00:07
Show Gist options
  • Save jeremysinger/ca2a5e9a2671c856f3fcaf5ebe57dd3d to your computer and use it in GitHub Desktop.
Save jeremysinger/ca2a5e9a2671c856f3fcaf5ebe57dd3d to your computer and use it in GitHub Desktop.
import Text.Parsec
-- simple datatype for expressions
data BinOp = Add | Sub | Mul | Div deriving (Show,Eq)
data ArithExpr =
Compound ArithExpr BinOp ArithExpr
| Value Int
deriving Show
numberParser:: Parsec String st ArithExpr
numberParser = do
digs <- many1 digit
let num = read digs
return $ Value num
operatorParser:: Parsec String st BinOp
operatorParser = do
op <- (oneOf "+-*/")
return (selectOp op)
where selectOp '+' = Add
selectOp '-' = Sub
selectOp '*' = Mul
selectOp '/' = Div
expressionParser:: Parsec String st ArithExpr
expressionParser = (between (char '(') (char ')') binaryExpressionParser) <|>
numberParser
binaryExpressionParser:: Parsec String st ArithExpr
binaryExpressionParser = do
e1 <- expressionParser
op <- operatorParser
e2 <- expressionParser
return (Compound e1 op e2)
-- now parseTest expressionParser "(1+1)"
-- or parse expressionParser "error" "(1+(2*3))"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment