module ParsingBasics where
import Data.Char
infixr 5 >*>
type Var = Char
data Expr = Lit Int | Var Var | Op Op Expr Expr
data Op = Add | Sub | Mul | Div | Mod
type Parse a b = [a] -> [(b,[a])]
none :: Parse a b
none :: forall a b. Parse a b
none [a]
inp = []
succeed :: b -> Parse a b
succeed :: forall b a. b -> Parse a b
succeed b
val [a]
inp = [(b
val,[a]
inp)]
token :: Eq a => a -> Parse a a
token :: forall a. Eq a => a -> Parse a a
token a
t (a
x:[a]
xs)
| a
ta -> a -> Bool
forall a. Eq a => a -> a -> Bool
==a
x = [(a
t,[a]
xs)]
| Bool
otherwise = []
token a
t [] = []
spot :: (a -> Bool) -> Parse a a
spot :: forall a. (a -> Bool) -> Parse a a
spot a -> Bool
p (a
x:[a]
xs)
| a -> Bool
p a
x = [(a
x,[a]
xs)]
| Bool
otherwise = []
spot a -> Bool
p [] = []
bracket :: Parse Char Char
bracket = Char -> Parse Char Char
forall a. Eq a => a -> Parse a a
token Char
'('
dig :: Parse Char Char
dig = (Char -> Bool) -> Parse Char Char
forall a. (a -> Bool) -> Parse a a
spot Char -> Bool
isDigit
alt :: Parse a b -> Parse a b -> Parse a b
alt :: forall a b. Parse a b -> Parse a b -> Parse a b
alt Parse a b
p1 Parse a b
p2 [a]
inp = Parse a b
p1 [a]
inp [(b, [a])] -> [(b, [a])] -> [(b, [a])]
forall a. [a] -> [a] -> [a]
++ Parse a b
p2 [a]
inp
exam1 :: [(Char, [Char])]
exam1 = (Parse Char Char
bracket Parse Char Char -> Parse Char Char -> Parse Char Char
forall a b. Parse a b -> Parse a b -> Parse a b
`alt` Parse Char Char
dig) [Char]
"234"
(>*>) :: Parse a b -> Parse a c -> Parse a (b,c)
>*> :: forall a b c. Parse a b -> Parse a c -> Parse a (b, c)
(>*>) Parse a b
p1 Parse a c
p2 [a]
inp
= [((b
y,c
z),[a]
rem2) | (b
y,[a]
rem1) <- Parse a b
p1 [a]
inp , (c
z,[a]
rem2) <- Parse a c
p2 [a]
rem1 ]
build :: Parse a b -> (b -> c) -> Parse a c
build :: forall a b c. Parse a b -> (b -> c) -> Parse a c
build Parse a b
p b -> c
f [a]
inp = [ (b -> c
f b
x,[a]
rem) | (b
x,[a]
rem) <- Parse a b
p [a]
inp ]
list :: Parse a b -> Parse a [b]
list :: forall a b. Parse a b -> Parse a [b]
list Parse a b
p = ([b] -> Parse a [b]
forall b a. b -> Parse a b
succeed []) Parse a [b] -> Parse a [b] -> Parse a [b]
forall a b. Parse a b -> Parse a b -> Parse a b
`alt`
((Parse a b
p Parse a b -> Parse a [b] -> Parse a (b, [b])
forall a b c. Parse a b -> Parse a c -> Parse a (b, c)
>*> Parse a b -> Parse a [b]
forall a b. Parse a b -> Parse a [b]
list Parse a b
p) Parse a (b, [b]) -> ((b, [b]) -> [b]) -> Parse a [b]
forall a b c. Parse a b -> (b -> c) -> Parse a c
`build` (b, [b]) -> [b]
forall {a}. (a, [a]) -> [a]
convert)
where
convert :: (a, [a]) -> [a]
convert = (a -> [a] -> [a]) -> (a, [a]) -> [a]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry (:)
neList :: Parse a b -> Parse a [b]
neList :: forall a b. Parse a b -> Parse a [b]
neList = Parse a b -> Parse a [b]
forall a b. Parse a b -> Parse a [b]
neList
optional :: Parse a b -> Parse a [b]
optional :: forall a b. Parse a b -> Parse a [b]
optional = Parse a b -> Parse a [b]
forall a b. Parse a b -> Parse a [b]
optional
nTimes :: Int -> Parse a b -> Parse a [b]
nTimes :: forall a b. Int -> Parse a b -> Parse a [b]
nTimes = Int -> Parse a b -> Parse a [b]
forall a b. Int -> Parse a b -> Parse a [b]
nTimes
parser :: Parse Char Expr
parser :: Parse Char Expr
parser = (Parse Char Expr
litParse Parse Char Expr -> Parse Char Expr -> Parse Char Expr
forall a b. Parse a b -> Parse a b -> Parse a b
`alt` Parse Char Expr
varParse) Parse Char Expr -> Parse Char Expr -> Parse Char Expr
forall a b. Parse a b -> Parse a b -> Parse a b
`alt` Parse Char Expr
opExpParse
varParse :: Parse Char Expr
varParse :: Parse Char Expr
varParse = (Char -> Bool) -> Parse Char Char
forall a. (a -> Bool) -> Parse a a
spot Char -> Bool
isVar Parse Char Char -> (Char -> Expr) -> Parse Char Expr
forall a b c. Parse a b -> (b -> c) -> Parse a c
`build` Char -> Expr
Var
isVar :: Char -> Bool
isVar :: Char -> Bool
isVar Char
x = (Char
'a' Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
x Bool -> Bool -> Bool
&& Char
x Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
<= Char
'z')
opExpParse :: Parse Char Expr
opExpParse
= (Char -> Parse Char Char
forall a. Eq a => a -> Parse a a
token Char
'(' Parse Char Char
-> Parse Char (Expr, (Char, (Expr, Char)))
-> Parse Char (Char, (Expr, (Char, (Expr, Char))))
forall a b c. Parse a b -> Parse a c -> Parse a (b, c)
>*>
Parse Char Expr
parser Parse Char Expr
-> Parse Char (Char, (Expr, Char))
-> Parse Char (Expr, (Char, (Expr, Char)))
forall a b c. Parse a b -> Parse a c -> Parse a (b, c)
>*>
(Char -> Bool) -> Parse Char Char
forall a. (a -> Bool) -> Parse a a
spot Char -> Bool
isOp Parse Char Char
-> Parse Char (Expr, Char) -> Parse Char (Char, (Expr, Char))
forall a b c. Parse a b -> Parse a c -> Parse a (b, c)
>*>
Parse Char Expr
parser Parse Char Expr -> Parse Char Char -> Parse Char (Expr, Char)
forall a b c. Parse a b -> Parse a c -> Parse a (b, c)
>*>
Char -> Parse Char Char
forall a. Eq a => a -> Parse a a
token Char
')')
Parse Char (Char, (Expr, (Char, (Expr, Char))))
-> ((Char, (Expr, (Char, (Expr, Char)))) -> Expr)
-> Parse Char Expr
forall a b c. Parse a b -> (b -> c) -> Parse a c
`build` (Char, (Expr, (Char, (Expr, Char)))) -> Expr
forall {a} {b}. (a, (Expr, (Char, (Expr, b)))) -> Expr
makeExpr
makeExpr :: (a, (Expr, (Char, (Expr, b)))) -> Expr
makeExpr (a
_,(Expr
e1,(Char
bop,(Expr
e2,b
_)))) = Op -> Expr -> Expr -> Expr
Op (Char -> Op
charToOp Char
bop) Expr
e1 Expr
e2
isOp :: Char -> Bool
isOp :: Char -> Bool
isOp = Char -> Bool
isOp
charToOp :: Char -> Op
charToOp :: Char -> Op
charToOp = Char -> Op
charToOp
litParse :: Parse Char Expr
litParse
= ((Parse Char Char -> Parse Char [Char]
forall a b. Parse a b -> Parse a [b]
optional (Char -> Parse Char Char
forall a. Eq a => a -> Parse a a
token Char
'~')) Parse Char [Char]
-> Parse Char [Char] -> Parse Char ([Char], [Char])
forall a b c. Parse a b -> Parse a c -> Parse a (b, c)
>*>
(Parse Char Char -> Parse Char [Char]
forall a b. Parse a b -> Parse a [b]
neList ((Char -> Bool) -> Parse Char Char
forall a. (a -> Bool) -> Parse a a
spot Char -> Bool
isDigit)))
Parse Char ([Char], [Char])
-> (([Char], [Char]) -> Expr) -> Parse Char Expr
forall a b c. Parse a b -> (b -> c) -> Parse a c
`build` ([Char] -> Expr
charlistToExpr([Char] -> Expr)
-> (([Char], [Char]) -> [Char]) -> ([Char], [Char]) -> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([Char], [Char]) -> [Char]
forall {a}. ([a], [a]) -> [a]
join)
where
join :: ([a], [a]) -> [a]
join = ([a] -> [a] -> [a]) -> ([a], [a]) -> [a]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++)
charlistToExpr :: [Char] -> Expr
charlistToExpr :: [Char] -> Expr
charlistToExpr = [Char] -> Expr
charlistToExpr
topLevel :: Parse a b -> [a] -> b
topLevel :: forall a b. Parse a b -> [a] -> b
topLevel Parse a b
p [a]
inp
= case [b]
results of
[] -> [Char] -> b
forall a. HasCallStack => [Char] -> a
error [Char]
"parse unsuccessful"
[b]
_ -> [b] -> b
forall a. HasCallStack => [a] -> a
head [b]
results
where
results :: [b]
results = [ b
found | (b
found,[]) <- Parse a b
p [a]
inp ]
data Command = Eval Expr | Assign Var Expr | Null
commandParse :: Parse Char Command
commandParse :: Parse Char Command
commandParse = Parse Char Command
commandParse