| 1 | module Practicum2 where |
|---|
| 2 | import ParseLib |
|---|
| 3 | import Data.Char |
|---|
| 4 | |
|---|
| 5 | -------------------------------------------------- |
|---|
| 6 | -- Naam: |
|---|
| 7 | -- Studentnummer: |
|---|
| 8 | -- Versie van de opdracht: |
|---|
| 9 | -- Datum: |
|---|
| 10 | -------------------------------------------------- |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | data Token = LParen |
|---|
| 14 | | RParen |
|---|
| 15 | | LBrack |
|---|
| 16 | | RBrack |
|---|
| 17 | | Arrow |
|---|
| 18 | | Comma |
|---|
| 19 | | Equals |
|---|
| 20 | | Bar |
|---|
| 21 | | Data |
|---|
| 22 | | Const String |
|---|
| 23 | | Varia String |
|---|
| 24 | | Error |
|---|
| 25 | deriving (Show, Eq) |
|---|
| 26 | |
|---|
| 27 | terminals :: [(Token, String)] |
|---|
| 28 | terminals = |
|---|
| 29 | [ (LParen, "(" ) |
|---|
| 30 | , (RParen, ")" ) |
|---|
| 31 | , (LBrack, "[" ) |
|---|
| 32 | , (RBrack, "]" ) |
|---|
| 33 | , (Arrow, "->" ) |
|---|
| 34 | , (Comma, "," ) |
|---|
| 35 | , (Equals, "=" ) |
|---|
| 36 | , (Bar, "|" ) |
|---|
| 37 | , (Data, "data") |
|---|
| 38 | ] |
|---|
| 39 | |
|---|
| 40 | -- test hoofdletter |
|---|
| 41 | capital :: Parser Char Char |
|---|
| 42 | capital = satisfy isUpper |
|---|
| 43 | -- test kleine letter |
|---|
| 44 | lower :: Parser Char Char |
|---|
| 45 | lower = satisfy isLower |
|---|
| 46 | -- test cijfer (in ParseLib gedefinieerd) |
|---|
| 47 | --digit :: Parser Char Char |
|---|
| 48 | --digit = satisfy isDigit |
|---|
| 49 | |
|---|
| 50 | -------------------------------------------------- |
|---|
| 51 | ------------------ opdracht 1 -------------------- |
|---|
| 52 | -------------------------------------------------- |
|---|
| 53 | input :: Parser Char Char |
|---|
| 54 | input = satisfy isUpper <|> satisfy isLower |
|---|
| 55 | lowerIdent, upperIdent :: Parser Char String |
|---|
| 56 | lowerIdent = (:) <$> lower <*> greedy input |
|---|
| 57 | upperIdent = (:) <$> capital <*> greedy input |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | -------------------------------------------------- |
|---|
| 61 | ------------------ opdracht 2 -------------------- |
|---|
| 62 | -------------------------------------------------- |
|---|
| 63 | parserToken :: Parser Char Token |
|---|
| 64 | |
|---|
| 65 | token1 k xs | k == take n xs = k |
|---|
| 66 | | otherwise = [] |
|---|
| 67 | where n = length k |
|---|
| 68 | |
|---|
| 69 | |
|---|
| 70 | parserToken xs | foldl1 (||) (map (== (token1 n xs)) (map snd terminals)) = [(head [a | (a,b) <- terminals, b == (token1 n xs)], drop 2 xs)] |
|---|
| 71 | | foldl1 (||) (map (== (token1 m xs)) (map snd terminals)) = [(head [a | (a,b) <- terminals, b == (token1 m xs)], drop 4 xs)] |
|---|
| 72 | | foldl1 (||) ((map (== head xs)) (map head (map snd terminals))) = [(head [a | (a,b) <- terminals, b == [head xs]], tail xs)] |
|---|
| 73 | | isUpper (head xs) = let [(a,b)] = upperIdent xs in [(Const a, b)] |
|---|
| 74 | | isLower (head xs) = let [(a,b)] = lowerIdent xs in [(Varia a, b)] |
|---|
| 75 | where n = "->" |
|---|
| 76 | m = "data" |
|---|
| 77 | |
|---|
| 78 | --------------------------------------------- |
|---|
| 79 | ------------------ opdracht 3 -------------------- |
|---|
| 80 | -------------------------------------------------- |
|---|
| 81 | --separatorParser :: Parser Char Token |
|---|
| 82 | separatorParser xs | let (f == "\n") in token1 f xs = [(Error, drop (length f) xs)] |
|---|
| 83 | |
|---|
| 84 | |
|---|
| 85 | |
|---|
| 86 | -- functie solution levert de eerste complete oplossing op van de parser |
|---|
| 87 | solution :: Parser a b -> [a] -> b |
|---|
| 88 | solution parser xs = fst (head (parser xs)) |
|---|
| 89 | |
|---|
| 90 | -- Functie main voor het testen van de lexical scanner |
|---|
| 91 | -- Voeg indien nodig een padaanduiding toe aan de naam van het testbestand |
|---|
| 92 | --main :: IO () |
|---|
| 93 | --main = do { xs <- readFile "test.hs" |
|---|
| 94 | -- ; putStr (show (solution lexicalScanner xs)) |
|---|
| 95 | -- } |
|---|
| 96 | |
|---|
| 97 | -------------------------------------------------- |
|---|
| 98 | |
|---|
| 99 | ------------------ opdracht 4 -------------------- |
|---|
| 100 | -------------------------------------------------- |
|---|
| 101 | |
|---|
| 102 | data HaskellType = HT TypeName [TypeVar] Type |
|---|
| 103 | deriving Show |
|---|
| 104 | |
|---|
| 105 | type TypeName = String |
|---|
| 106 | type TypeVar = String |
|---|
| 107 | |
|---|
| 108 | data Type = Choice [Type] -- lijst van verschillende typen |
|---|
| 109 | | Constructor String -- constructornaam (begint met hoofdletter) |
|---|
| 110 | | App Type Type -- compositie van twee typen (binaire applicatie) |
|---|
| 111 | | Var String -- typevariabele (begint met een kleine letter) |
|---|
| 112 | | ConstType String -- typenaam zoals Int (begint met hoofdletter) |
|---|
| 113 | | List Type -- lijsttype |
|---|
| 114 | | Arr Type Type -- functietype |
|---|
| 115 | | Tuple [Type] -- tupletype |
|---|
| 116 | deriving Show |
|---|
| 117 | |
|---|
| 118 | --------------- hulpfuncties ------------------ |
|---|
| 119 | |
|---|
| 120 | isConst :: Token -> Bool |
|---|
| 121 | isConst (Const _) = True |
|---|
| 122 | isConst _ = False |
|---|
| 123 | |
|---|
| 124 | isVaria :: Token -> Bool |
|---|
| 125 | isVaria (Varia _) = True |
|---|
| 126 | isVaria _ = False |
|---|
| 127 | |
|---|
| 128 | unConst :: Token -> String |
|---|
| 129 | unConst (Const x) = x |
|---|
| 130 | |
|---|
| 131 | unVaria :: Token -> String |
|---|
| 132 | unVaria (Varia x) = x |
|---|
| 133 | |
|---|
| 134 | -- maakt van een lijst elementen een type App (binaire applicatie) |
|---|
| 135 | makeApp :: [Type] -> Type |
|---|
| 136 | makeApp = \x -> if null x |
|---|
| 137 | then error "makeApp: type expected" |
|---|
| 138 | else foldl App (head x) (tail x) |
|---|
| 139 | |
|---|
| 140 | -- maakt van een lijst elementen en een los element een type App (binaire applicatie) |
|---|
| 141 | makeAppAlt :: Type -> [Type] -> Type |
|---|
| 142 | makeAppAlt x y = makeApp (x:y) |
|---|
| 143 | |
|---|
| 144 | -- maakt van een lijst elementen een type Arr (arrow, functie) |
|---|
| 145 | |
|---|
| 146 | makeArr :: Type -> [Type] -> Type |
|---|
| 147 | makeArr = \x y -> if null y then x |
|---|
| 148 | else foldl Arr x y |
|---|
| 149 | |
|---|
| 150 | -------------------------------------------------- |
|---|
| 151 | ------------ opdracht 5, 6, 7 -------------------- |
|---|
| 152 | -------------------------------------------------- |
|---|
| 153 | |
|---|
| 154 | |
|---|