-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
example.hs
75 lines (61 loc) · 1.97 KB
/
example.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
67
68
69
70
71
72
73
74
75
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE Rank2Types #-}
import Data.Foldable (for_)
import System.Environment (getArgs)
import Text.PariPari
import qualified Data.ByteString as B
type StringType = B.ByteString
type PMonad p = Parser StringType p
type P a = (forall p. PMonad p => p a)
-- {-# SPECIALISE_ALL PMonad p = p ~ Acceptor StringType #-}
-- {-# SPECIALISE_ALL PMonad p = p ~ Reporter StringType #-}
-- {-# SPECIALISE_ALL P = Acceptor StringType #-}
-- {-# SPECIALISE_ALL P = Reporter StringType #-}
data Value
= Object ![(StringType, Value)]
| Array ![Value]
| String !StringType
| Number !Integer !Integer
| Bool !Bool
| Null
deriving (Eq, Show)
json :: P Value
json = space *> (object <|> array) <?> "json"
object :: P Value
object = Object <$> (char '{' *> space *> sepBy pair (space *> char ',' *> space) <* space <* char '}') <?> "object"
pair :: P (StringType, Value)
pair = (,) <$> (text <* space) <*> (char ':' *> space *> value)
array :: P Value
array = Array <$> (char '[' *> sepBy value (space *> char ',' *> space) <* space <* char ']') <?> "array"
value :: P Value
value =
(String <$> text)
<|> object
<|> array
<|> (Bool False <$ string "false")
<|> (Bool True <$ string "true")
<|> (Null <$ string "null")
<|> number
text :: P StringType
text = char '"' *> takeCharsWhile (/= '"') <* char '"' <?> "text"
number :: P Value
number = label "number" $ do
neg <- sign
frac <- fractionDec (pure ())
pure $ case frac of
Left n -> Number (neg n) 0
Right (c, _, e) -> Number (neg c) e
space :: P ()
space = skipCharsWhile (\c -> c == ' ' || c == '\n' || c == '\t')
main :: IO ()
main = do
args <- getArgs
case args of
[file] -> do
src <- B.readFile file
let (result, reports) = runParser json file src
for_ reports $ putStrLn . showReport
print result
_ -> error "Usage: paripari-example test.json"