-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParsing.hs
66 lines (56 loc) · 1.55 KB
/
Parsing.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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
{-|
Module : ADT.Parsing
Description : "Text.Megaparsec" parser for 'ADT.Internal.Expr' expressions
Copyright : (c) Carsten König, 2019
License : GPL-3
Maintainer : Carsten.Koenig@hotmail.de
Stability : experimental
Portability : POSIX
-}
module ADT.Parsing
( exprP
) where
import Control.Applicative ((<|>))
import qualified Text.Megaparsec as P
import qualified Text.Megaparsec.Char as PC
import CommonParsers
import ADT.Internal
-- | defines a Megaparsec-Parser for 'Expr'
--
-- >>> import qualified Text.Megaparsec as P
-- >>> P.parse exprP "" "3+4"
-- Right (AddE (IntE 3) (IntE 4))
exprP :: Parser Expr
exprP = ifExprP <|> termExprP
ifExprP :: Parser Expr
ifExprP = do
_ <- PC.string "if" <* P.hidden PC.space
b <- termExprP
_ <- PC.string "then" <* P.hidden PC.space
t <- termExprP
_ <- PC.string "else" <* P.hidden PC.space
e <- termExprP
pure $ IfE b t e
termExprP :: Parser Expr
termExprP = addExprP <|> valueExprP
addExprP :: Parser Expr
addExprP = chainL1 opAddP valueExprP
where
opAddP = const AddE <$> (PC.char '+' <* P.hidden PC.space)
valueExprP :: Parser Expr
valueExprP = isNullP valueExprP' <|> valueExprP'
where
valueExprP' = P.choice
[ brace exprP
, intExprP
, boolExprP
]
isNullP :: Parser Expr -> Parser Expr
isNullP valP = do
_ <- P.label "isNull" $ P.hidden $ PC.string "isNull" <* PC.space
v <- valP
pure $ IsNullE v
intExprP :: Parser Expr
intExprP = IntE <$> numberP <* P.hidden PC.space
boolExprP :: Parser Expr
boolExprP = BoolE <$> boolP <* P.hidden PC.space