This starts off with defining not the AST, but just what expressions we
want to be able to parse.
So far we just handle numbers, and addition involving 2 numbers.
We use the built-in ReadPrec parser combinators, which allow us to
recursively parse the binary op of addition, and even allow us to reuse
the Read instance on Int!
prec and step are needed since without them, parseAdd will just get
stuck repeatedly trying to parse the left expression (a).
--- /dev/null
+module AST where
+
+import Text.Read
+import Text.ParserCombinators.ReadP hiding ((+++))
+
+data Expr = Num Float
+ | Add Expr Expr
+ deriving Show
+
+instance Read Expr where
+ readPrec = parseNum +++ parseAdd
+ where parseNum = Num <$> readPrec
+ -- use 'prec 1' and 'step' so that parsing 'a'
+ -- can only go one step deep, to prevent ininfite
+ -- recursion
+ parseAdd = prec 1 $ do
+ a <- step readPrec
+ lift $ do
+ skipSpaces
+ char '+'
+ skipSpaces
+ b <- readPrec
+ return (Add a b)