Repository navigation
Expand file tree
/
Copy pathParserCombinators.hs
More file actions
75 lines (64 loc) · 2.83 KB
/
Copy pathParserCombinators.hs
File metadata and controls
75 lines (64 loc) · 2.83 KB
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
67
68
69
70
71
72
73
74
75
{-# LANGUAGE OverloadedStrings #-}
module ParserCombinators (tests) where
import Test.Hspec (Spec, describe, it)
import Test.HUnit (assertBool, assertEqual, Assertion)
import qualified Data.Attoparsec.Text as P
import Data.Text (Text)
tests :: Spec
tests = describe "ParserCombinators" $ do
testDigitParser
testDigitsParser
testSymbolParser
testAtomParser
testListParser
failParser :: String -> P.Parser a
failParser parserName =
fail $ "\n\n\t\x1B[32;1mCheck documentation\x1B[0m of \x1B[33;1m"
++ parserName
++ "\x1B[0m on:\n\t"
++ "http://hackage.haskell.org/packages/archive/attoparsec/latest/doc/html/Data-Attoparsec-Text.html"
++ "\n\tand http://hackage.haskell.org/packages/archive/attoparsec/latest/doc/html/Data-Attoparsec-Combinator.html"
assertParse :: (Eq a, Show a) => a -> Either String a -> Assertion
assertParse _ (Left e) = assertBool e False
assertParse expected (Right answer) =
assertEqual "wrong parser" expected answer
testDigitParser :: Spec
testDigitParser = it "digit parser" $ do
-- Change parser with the correct parser to use
let parser = failParser "digit parser" :: P.Parser Char
let result = P.parseOnly parser "5"
assertParse '5' result
testDigitsParser :: Spec
testDigitsParser = it "sequence of digits parser" $ do
-- Change parser with the correct parser to use
let parser = failParser "sequence of digits parser" :: P.Parser String
let result = P.parseOnly parser "54321"
assertParse "54321" result
testSymbolParser :: Spec
testSymbolParser = it "symbol parser" $ do
-- Change parser with the correct parser to use
--
-- Here we say symbol is a sequence of characters that doesn't have
-- parenthes or spaces.
let parser = failParser "symbol parser" :: P.Parser String
assertParse "ab" $ P.parseOnly parser "ab"
assertParse "a/b" $ P.parseOnly parser "a/b"
assertParse "a/b" $ P.parseOnly parser "a/b c"
data Atom = AInt Int | ASym Text deriving (Eq, Show)
testAtomParser :: Spec
testAtomParser = it "atom parser" $ do
-- Change parser with the correct parser to use
--
let parser = failParser "atom parser" :: P.Parser Atom
assertParse (ASym "ab") $ P.parseOnly parser "ab"
assertParse (ASym "a/b") $ P.parseOnly parser "a/b"
assertParse (ASym "a/b") $ P.parseOnly parser "a/b c"
assertParse (AInt 54321) $ P.parseOnly parser "54321"
data List = Nil | LAtom Atom | Cons List List deriving (Eq, Show)
testListParser :: Spec
testListParser = it "list parser" $ do
-- Change parser with the correct parser to use
let parser = failParser "list parser" :: P.Parser List
assertParse Nil $ P.parseOnly parser "()"
assertParse (Cons (LAtom (AInt 12)) Nil) $ P.parseOnly parser "(12)"
assertParse (Cons (LAtom (ASym "a")) (Cons (LAtom (ASym "b")) Nil)) $ P.parseOnly parser "(a (b))"