Skip to content

Commit 866e8f2

Browse files
author
matteB10
committed
added parsing.hs
1 parent 726a2da commit 866e8f2

File tree

2 files changed

+166
-25
lines changed

2 files changed

+166
-25
lines changed

Labb4MB.hs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,7 @@ showExpr (BinOp name _ expr1 expr2) = case name of
2626
showFactor (BinOp "+" _ expr1 expr2) = "(" ++ showExpr (add expr1 expr2) ++ ")"
2727
showFactor expr = showExpr expr
2828

29-
30-
{-}
31-
add -> case expr2 of
32-
mul -> "(" ++ showExpr expr1 ++ ") " ++ name ++ " " ++ showExpr expr2
33-
mul -> case expr2 of
34-
add -> showExpr expr1 ++ " " ++ name ++ " (" ++ showExpr expr2 ++ ")"
35-
-}
36-
37-
38-
39-
----------- TEST DATA ---------------------------
40-
41-
test = BinOp "+" (+) (Num 1) (Num 2)
42-
testf = MonoOp "sin" Prelude.sin (Num 0)
43-
test2 = MonoOp "sin" Prelude.sin test
44-
45-
test3 = mul (add (Num 1) (Num 2)) (add (Num 3) (Num 5))
46-
test4 = add (add (Num 1) (Num 2)) (add (Num 3) (Num 5))
47-
test5 = mul (mul (Num 1) (Num 2)) (mul (Num 3) (Num 5))
48-
49-
--------------------------------------------------
29+
--------------------------------------------------------
5030

5131
x :: Expr
5232
x = Var
@@ -62,7 +42,27 @@ sin,cos :: Expr -> Expr
6242
sin x = MonoOp "sin" Prelude.sin x
6343
cos x = MonoOp "cos" Prelude.cos x
6444

65-
eval :: Expr -> Double
66-
eval (Num x) = x
67-
eval (BinOp _ o x y) = (eval x) `o` (eval y)
68-
eval (MonoOp _ o x) = o (eval x)
45+
----------- TEST DATA ---------------------------
46+
47+
test = BinOp "+" (+) (Num 1) (Num 2) -- = 3
48+
testf = MonoOp "sin" Prelude.sin (Num 0) -- = 0
49+
test2 = MonoOp "sin" Prelude.sin test -- = sin(3) ca 0.14
50+
51+
test3 = mul (add (Num 1) (Num 2)) (add (Num 3) (Num 5)) -- = 3 * 8 = 24
52+
test4 = add (add (Num 1) (Num 2)) (add (Num 3) (Num 5)) -- = 3 + 8 = 11
53+
test5 = mul (mul (Num 1) (Num 2)) (mul (Num 3) (Num 5)) -- = 1*2 * 3*5 = 2 * 15 = 30
54+
55+
test6 = mul (mul (Var) (Num 2)) (mul (Num 3) (Num 5)) -- = 1*2 * 3*5 = 2 * 15 = 30
56+
57+
--------------------------------------------------
58+
59+
-- | Evaluates a given expression, where the second argument is the value of x
60+
eval :: Expr -> Double -> Double
61+
eval (Var) x = x
62+
eval (Num n) _ = n
63+
eval (BinOp _ op i j) x = (eval i x) `op` (eval j x)
64+
eval (MonoOp _ op i) x = op (eval i x)
65+
66+
-- | Tries to read a expression from a string
67+
readExpr :: String -> Maybe Expr
68+
readExpr = undefined

Parsing.hs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
{-|
2+
Module : Parsing
3+
Description : Simple Monadic Parsing Library
4+
Maintainer : Thomas Hallgren
5+
A Simple Monadic Parsing Library
6+
Used in the course Functional Programming GU/Chalmers.
7+
Original author: David Sands.
8+
9+
---------------------
10+
Aim: reusable Parser combinators including
11+
a new type for the Parser,
12+
but no export of the constructor
13+
Changes (v3 2016) Thomas Hallgren
14+
Export <* and *> from class Applicative instead of the combinators <-< and >->
15+
Export <|> from class Alternative instead of +++
16+
Changes (v2 2015)
17+
For compatibility with GHC>=7.10 Parser
18+
is now also instance Applicative
19+
Removal: Class Functor, Applicative and Monad provide a number of
20+
functions that were previously exported explicitly, in particular
21+
(>*>) is available as the bind operation (>>=),
22+
success is return, pmap is fmap.
23+
Additional function:
24+
readsP :: Read a => Parser a
25+
-- satisfies
26+
-- parse readsP s == listToMaybe (reads s)
27+
---------------------
28+
-}
29+
module Parsing
30+
( -- * The Parser type
31+
Parser -- exports the type name but not the constructors
32+
,parse
33+
-- * Basic parsers
34+
,sat,item,digit
35+
,readsP -- behaves as reads :: Read a => [(a,String)]
36+
, char, failure
37+
-- * Combining parsers
38+
,oneOrMore,zeroOrMore,chain,(<:>)
39+
-- * More general operators useful in parser construction
40+
-- ** Try two alternatives
41+
,(<|>)
42+
-- ** Apply a function to the result of a parser
43+
,(<$>),(<*>)
44+
-- ** Parse two things, return only the first
45+
,(<*)
46+
-- ** Parse two things, return only the second
47+
,(*>)
48+
-- ** Return a result without consuming any input
49+
, return
50+
)
51+
where
52+
import Data.Char
53+
import Data.Maybe(listToMaybe)
54+
-- boilerplate for GHC 10.7 compatibility:
55+
import Control.Applicative (Applicative(..),Alternative(..))
56+
import Control.Monad (liftM, ap)
57+
------------------
58+
59+
-- | The abstract data type representing a Parser
60+
newtype Parser a = P (String -> Maybe (a,String))
61+
-- | Runs the parser on the given string
62+
-- to return maybe a thing and a string
63+
parse :: Parser a -> String -> Maybe(a,String)
64+
parse (P f ) s = f s
65+
-- | A parser for anything in the Read class,
66+
-- satisfying
67+
--
68+
-- prop> parse readsP s == listToMaybe (reads s)
69+
readsP :: Read a => Parser a
70+
readsP = P $ listToMaybe . reads
71+
-------------------
72+
-- | Parser than can never succeed
73+
failure :: Parser a -- always fails
74+
failure = P $ \s ->
75+
Nothing
76+
-- | Parser that succeeds without looking at the String
77+
success :: a -> Parser a
78+
success a = P $ \s ->
79+
Just (a,s)
80+
-- | Parse any single character
81+
item = P $ \s ->
82+
case s of
83+
(c:s') -> Just (c,s')
84+
"" -> Nothing
85+
infixr 3 +++
86+
-- | Try the first parser and if it fails try the second
87+
(+++) :: Parser a -> Parser a -> Parser a
88+
p +++ q = P $ \s ->
89+
case parse p s of
90+
Nothing -> parse q s
91+
r -> r
92+
-- (p >*> f) parse using p to produce a.
93+
-- Then parse using f a
94+
infixl 1 >*>
95+
(>*>) :: Parser a -> (a -> Parser b) -> Parser b
96+
p >*> f = P $ \s ->
97+
case parse p s of
98+
Just (a,s') -> parse (f a) s'
99+
Nothing -> Nothing
100+
-----------------------------------------------
101+
-- Parsers below do not depend on the internal
102+
-- representation of Parser
103+
-- | parse a single character satisfying property p
104+
sat :: (Char -> Bool) -> Parser Char
105+
sat p = item >*> \a -> if p a then success a else failure
106+
-- | parse a digit character
107+
digit :: Parser Char
108+
digit = sat isDigit
109+
-- | Parse a specific character
110+
char c = sat (==c)
111+
-- example: parse any lowercase letter
112+
-- followed by its uppercase equivalent aA or bB etc.
113+
ex1 = sat isAsciiLower >*> char . toUpper
114+
-- pmap modifies the result of a parser
115+
-- | Parse a thing, then parse a list of things, and
116+
-- return the first thing followed by the list of things
117+
(<:>):: Parser a -> Parser [a] -> Parser [a]
118+
p <:> q = p >*> \a -> fmap (a:) q
119+
-- | Parse zero or more things
120+
zeroOrMore :: Parser a -> Parser [a]
121+
zeroOrMore p = oneOrMore p +++ success []
122+
-- | Parse one or more things
123+
oneOrMore :: Parser a -> Parser [a]
124+
oneOrMore p = p <:> zeroOrMore p
125+
-- | Parse a list of as, separated by bs
126+
chain :: Parser a -> Parser b -> Parser [a]
127+
chain p q = p <:> zeroOrMore (q *> p)
128+
-- example: comma separated digits "1,2,3"
129+
-- Standard definition for Functor and Applicative for
130+
-- GHC>=7.10 compatibility
131+
instance Functor Parser where
132+
fmap = liftM
133+
instance Applicative Parser where
134+
pure = success
135+
(<*>) = ap
136+
instance Monad Parser where
137+
(>>=) = (>*>)
138+
return = pure
139+
instance Alternative Parser where
140+
empty = failure
141+
(<|>) = (+++)

0 commit comments

Comments
 (0)