-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExprParser.hs
39 lines (31 loc) · 976 Bytes
/
ExprParser.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
module ExprParser
( Expr(..)
, parseExpr
) where
import Control.Applicative
import Control.Monad
import Data.Char
import Expressions
import qualified Parser as P
import Parser hiding ( Parser )
type Parser a = P.Parser Char a
w :: Parser ()
w = void $ while isSpace
int :: Parser Expr
int = ExNum . read <$> while1 (\s -> isDigit s || s == '.')
var :: Parser Expr
var = ExVar <$> satisfy isAlpha
parseExpr :: String -> Maybe Expr
parseExpr = fmap fst . runParser (expr <* eoi)
expr :: Parser Expr
expr = chainl1 term (addP <|> subP)
where
addP = ExAdd <$ (w *> char '+' <* w)
subP = ExSub <$ (w *> char '-' <* w)
term :: Parser Expr
term = frac <|> chainl1 factor multP
where
multP = ExMult <$ (w *> char '*' <* w)
frac = ExFrac <$> factor <*> (w *> char '/' *> w *> factor)
factor :: Parser Expr
factor = int <|> var <|> char '(' *> w *> expr <* w <* char ')'