-- | Some examples of grammars.

module Little.Earley.Examples
  ( -- * Grammars
    arithG
  , aArithG
  , lambdaG
  , mlG
  , jsonG

    -- * Symbols
  , ArithN(..)
  , LambdaN(..)
  , MlN(..)
  , JsonN(..)
  , CharT(..)
  , matchCharT
  ) where

import Data.Char (isAlpha, isDigit)

import Little.Earley (Grammar, Rule, Atom(..), mkGrammar)

-- | Grammar of arithmetic expressions.
--
-- > SUM     ::= PRODUCT | SUM [+-] PRODUCT
-- > PRODUCT ::= FACTOR | PRODUCT [*/] FACTOR
-- > FACTOR  ::= NUMBER | [(] NUMBER [)]
-- > NUMBER  ::= [0-9] | [0-9] NUMBER
--
-- === Example
--
-- @
-- 'Little.Earley.pparse' arithG SUM \"1+2*3\"
-- @
arithG :: Grammar ArithN CharT Char
arithG :: Grammar ArithN CharT Char
arithG = (ArithN -> [Rule ArithN CharT])
-> (CharT -> Char -> Bool) -> Grammar ArithN CharT Char
forall n t c.
(Ord n, Bounded n, Enum n) =>
(n -> [Rule n t]) -> (t -> c -> Bool) -> Grammar n t c
mkGrammar ArithN -> [Rule ArithN CharT]
arithRules CharT -> Char -> Bool
matchCharT

-- | Ambiguous grammar of arithmetic expressions.
--
-- > SUM     ::= PRODUCT | SUM [+-] SUM
-- > PRODUCT ::= FACTOR | PRODUCT [*/] PRODUCT
-- > FACTOR  ::= NUMBER | [(] NUMBER [)]
-- > NUMBER  ::= [0-9] | [0-9] NUMBER
--
-- === Example
--
-- @
-- 'Little.Earley.pparse' aArithG SUM \"1+2-3\"
-- @
aArithG :: Grammar ArithN CharT Char
aArithG :: Grammar ArithN CharT Char
aArithG = (ArithN -> [Rule ArithN CharT])
-> (CharT -> Char -> Bool) -> Grammar ArithN CharT Char
forall n t c.
(Ord n, Bounded n, Enum n) =>
(n -> [Rule n t]) -> (t -> c -> Bool) -> Grammar n t c
mkGrammar ArithN -> [Rule ArithN CharT]
aArithRules CharT -> Char -> Bool
matchCharT

-- | Grammar of lambda expressions.
--
-- > LAMBDA ::= VAR | [\] VAR [.] LAMBDA | [(] LAMBDA [)] LAMBDA
-- > VAR    ::= [a-z]
--
-- === Example
--
-- @
-- 'Little.Earley.pparse' lambdaG LAMBDA \"\\\\x.x\"
-- 'Little.Earley.pparse' lambdaG LAMBDA \"(\\\\x.(x)x)\\\\x.(x)x\"
-- @
lambdaG :: Grammar LambdaN CharT Char
lambdaG :: Grammar LambdaN CharT Char
lambdaG = (LambdaN -> [Rule LambdaN CharT])
-> (CharT -> Char -> Bool) -> Grammar LambdaN CharT Char
forall n t c.
(Ord n, Bounded n, Enum n) =>
(n -> [Rule n t]) -> (t -> c -> Bool) -> Grammar n t c
mkGrammar LambdaN -> [Rule LambdaN CharT]
lambdaRules CharT -> Char -> Bool
matchCharT

-- | ML-like syntax.
--
-- > TERM ::= ATOMS
-- >      | "fun" VAR "->" TERM
-- >      | "let" VAR "=" TERM "in" TERM
-- >      | "if" TERM "then" TERM
-- >      | "if" TERM "then" TERM "else" TERM
-- > ATOMS ::= ATOM | ATOMS ATOM
-- > ATOM ::= VAR
-- >      | "(" TERM ")"
-- > VAR ::= "a" | "b" | "c" | ...
--
-- === Example
--
-- Featuring the if-then-else ambiguity.
--
-- @
-- 'Little.Earley.pparse' mlG TERM (words \"if a then if b then c else d\")
-- @
mlG :: Grammar MlN String String
mlG :: Grammar MlN String String
mlG = (MlN -> [Rule MlN String])
-> (String -> String -> Bool) -> Grammar MlN String String
forall n t c.
(Ord n, Bounded n, Enum n) =>
(n -> [Rule n t]) -> (t -> c -> Bool) -> Grammar n t c
mkGrammar MlN -> [Rule MlN String]
mlRules String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==)

-- | JSON grammar.
--
-- > JSON   ::= "null" | "true" | "false" | (number) | (string) | "{" OBJECT "}" | "[" ARRAY "]"
-- > OBJECT ::= (string) ":" JSON | (string) ":" JSON "," OBJECT
-- > ARRAY ::= JSON | JSON "," ARRAY
--
-- === Example
--
-- @
-- 'Little.Earley.pparse' jsonG JSON (words \"{ \\\"key\\\" : \\\"answer\\\" , \\\"contents\\\" : 42 }\")
-- @
jsonG :: Grammar JsonN String String
jsonG :: Grammar JsonN String String
jsonG = (JsonN -> [Rule JsonN String])
-> (String -> String -> Bool) -> Grammar JsonN String String
forall n t c.
(Ord n, Bounded n, Enum n) =>
(n -> [Rule n t]) -> (t -> c -> Bool) -> Grammar n t c
mkGrammar JsonN -> [Rule JsonN String]
jsonRules String -> String -> Bool
jsonMatch

-- | Basic character classes.
data CharT
  = Digit
  | Alpha
  | OneOf [Char]
  deriving (CharT -> CharT -> Bool
(CharT -> CharT -> Bool) -> (CharT -> CharT -> Bool) -> Eq CharT
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CharT -> CharT -> Bool
$c/= :: CharT -> CharT -> Bool
== :: CharT -> CharT -> Bool
$c== :: CharT -> CharT -> Bool
Eq, Eq CharT
Eq CharT
-> (CharT -> CharT -> Ordering)
-> (CharT -> CharT -> Bool)
-> (CharT -> CharT -> Bool)
-> (CharT -> CharT -> Bool)
-> (CharT -> CharT -> Bool)
-> (CharT -> CharT -> CharT)
-> (CharT -> CharT -> CharT)
-> Ord CharT
CharT -> CharT -> Bool
CharT -> CharT -> Ordering
CharT -> CharT -> CharT
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CharT -> CharT -> CharT
$cmin :: CharT -> CharT -> CharT
max :: CharT -> CharT -> CharT
$cmax :: CharT -> CharT -> CharT
>= :: CharT -> CharT -> Bool
$c>= :: CharT -> CharT -> Bool
> :: CharT -> CharT -> Bool
$c> :: CharT -> CharT -> Bool
<= :: CharT -> CharT -> Bool
$c<= :: CharT -> CharT -> Bool
< :: CharT -> CharT -> Bool
$c< :: CharT -> CharT -> Bool
compare :: CharT -> CharT -> Ordering
$ccompare :: CharT -> CharT -> Ordering
$cp1Ord :: Eq CharT
Ord, Int -> CharT -> ShowS
[CharT] -> ShowS
CharT -> String
(Int -> CharT -> ShowS)
-> (CharT -> String) -> ([CharT] -> ShowS) -> Show CharT
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CharT] -> ShowS
$cshowList :: [CharT] -> ShowS
show :: CharT -> String
$cshow :: CharT -> String
showsPrec :: Int -> CharT -> ShowS
$cshowsPrec :: Int -> CharT -> ShowS
Show)

-- | Membership function for character classes.
matchCharT :: CharT -> Char -> Bool
matchCharT :: CharT -> Char -> Bool
matchCharT CharT
Digit = Char -> Bool
isDigit
matchCharT CharT
Alpha = Char -> Bool
isAlpha
matchCharT (OneOf String
s) = (Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
s)

-- | Non-terminals for arithmetic expressions.
data ArithN
  = SUM
  | PRODUCT
  | FACTOR
  | NUMBER
  deriving (ArithN -> ArithN -> Bool
(ArithN -> ArithN -> Bool)
-> (ArithN -> ArithN -> Bool) -> Eq ArithN
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ArithN -> ArithN -> Bool
$c/= :: ArithN -> ArithN -> Bool
== :: ArithN -> ArithN -> Bool
$c== :: ArithN -> ArithN -> Bool
Eq, Eq ArithN
Eq ArithN
-> (ArithN -> ArithN -> Ordering)
-> (ArithN -> ArithN -> Bool)
-> (ArithN -> ArithN -> Bool)
-> (ArithN -> ArithN -> Bool)
-> (ArithN -> ArithN -> Bool)
-> (ArithN -> ArithN -> ArithN)
-> (ArithN -> ArithN -> ArithN)
-> Ord ArithN
ArithN -> ArithN -> Bool
ArithN -> ArithN -> Ordering
ArithN -> ArithN -> ArithN
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: ArithN -> ArithN -> ArithN
$cmin :: ArithN -> ArithN -> ArithN
max :: ArithN -> ArithN -> ArithN
$cmax :: ArithN -> ArithN -> ArithN
>= :: ArithN -> ArithN -> Bool
$c>= :: ArithN -> ArithN -> Bool
> :: ArithN -> ArithN -> Bool
$c> :: ArithN -> ArithN -> Bool
<= :: ArithN -> ArithN -> Bool
$c<= :: ArithN -> ArithN -> Bool
< :: ArithN -> ArithN -> Bool
$c< :: ArithN -> ArithN -> Bool
compare :: ArithN -> ArithN -> Ordering
$ccompare :: ArithN -> ArithN -> Ordering
$cp1Ord :: Eq ArithN
Ord, ArithN
ArithN -> ArithN -> Bounded ArithN
forall a. a -> a -> Bounded a
maxBound :: ArithN
$cmaxBound :: ArithN
minBound :: ArithN
$cminBound :: ArithN
Bounded, Int -> ArithN
ArithN -> Int
ArithN -> [ArithN]
ArithN -> ArithN
ArithN -> ArithN -> [ArithN]
ArithN -> ArithN -> ArithN -> [ArithN]
(ArithN -> ArithN)
-> (ArithN -> ArithN)
-> (Int -> ArithN)
-> (ArithN -> Int)
-> (ArithN -> [ArithN])
-> (ArithN -> ArithN -> [ArithN])
-> (ArithN -> ArithN -> [ArithN])
-> (ArithN -> ArithN -> ArithN -> [ArithN])
-> Enum ArithN
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: ArithN -> ArithN -> ArithN -> [ArithN]
$cenumFromThenTo :: ArithN -> ArithN -> ArithN -> [ArithN]
enumFromTo :: ArithN -> ArithN -> [ArithN]
$cenumFromTo :: ArithN -> ArithN -> [ArithN]
enumFromThen :: ArithN -> ArithN -> [ArithN]
$cenumFromThen :: ArithN -> ArithN -> [ArithN]
enumFrom :: ArithN -> [ArithN]
$cenumFrom :: ArithN -> [ArithN]
fromEnum :: ArithN -> Int
$cfromEnum :: ArithN -> Int
toEnum :: Int -> ArithN
$ctoEnum :: Int -> ArithN
pred :: ArithN -> ArithN
$cpred :: ArithN -> ArithN
succ :: ArithN -> ArithN
$csucc :: ArithN -> ArithN
Enum, Int -> ArithN -> ShowS
[ArithN] -> ShowS
ArithN -> String
(Int -> ArithN -> ShowS)
-> (ArithN -> String) -> ([ArithN] -> ShowS) -> Show ArithN
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ArithN] -> ShowS
$cshowList :: [ArithN] -> ShowS
show :: ArithN -> String
$cshow :: ArithN -> String
showsPrec :: Int -> ArithN -> ShowS
$cshowsPrec :: Int -> ArithN -> ShowS
Show)

arithRules :: ArithN -> [Rule ArithN CharT]
arithRules :: ArithN -> [Rule ArithN CharT]
arithRules ArithN
n = case ArithN
n of
  ArithN
SUM ->
    [ [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
PRODUCT ]
    , [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
SUM, CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'+', Char
'-']), ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
PRODUCT ] ]
  ArithN
PRODUCT ->
    [ [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
FACTOR ]
    , [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
PRODUCT, CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'*', Char
'/']), ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
FACTOR ] ]
  ArithN
FACTOR ->
    [ [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
NUMBER ]
    , [ CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'(']), ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
SUM, CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
')']) ] ]
  ArithN
NUMBER ->
    [ [ CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T CharT
Digit ]
    , [ CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T CharT
Digit, ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
NUMBER ] ]

aArithRules :: ArithN -> [Rule ArithN CharT]
aArithRules :: ArithN -> [Rule ArithN CharT]
aArithRules ArithN
n = case ArithN
n of
  ArithN
SUM ->
    [ [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
PRODUCT ]
    , [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
SUM, CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'+', Char
'-']), ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
SUM ] ]
  ArithN
PRODUCT ->
    [ [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
FACTOR ]
    , [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
PRODUCT, CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'*', Char
'/']), ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
FACTOR ] ]
  ArithN
FACTOR ->
    [ [ ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
NUMBER ]
    , [ CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'(']), ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
SUM, CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
')']) ] ]
  ArithN
NUMBER ->
    [ [ CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T CharT
Digit ]
    , [ CharT -> Atom ArithN CharT
forall n t. t -> Atom n t
T CharT
Digit, ArithN -> Atom ArithN CharT
forall n t. n -> Atom n t
N ArithN
NUMBER ] ]

-- | Non-terminals for lambda expressions.
data LambdaN = LAMBDA | VAR deriving (LambdaN -> LambdaN -> Bool
(LambdaN -> LambdaN -> Bool)
-> (LambdaN -> LambdaN -> Bool) -> Eq LambdaN
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LambdaN -> LambdaN -> Bool
$c/= :: LambdaN -> LambdaN -> Bool
== :: LambdaN -> LambdaN -> Bool
$c== :: LambdaN -> LambdaN -> Bool
Eq, Eq LambdaN
Eq LambdaN
-> (LambdaN -> LambdaN -> Ordering)
-> (LambdaN -> LambdaN -> Bool)
-> (LambdaN -> LambdaN -> Bool)
-> (LambdaN -> LambdaN -> Bool)
-> (LambdaN -> LambdaN -> Bool)
-> (LambdaN -> LambdaN -> LambdaN)
-> (LambdaN -> LambdaN -> LambdaN)
-> Ord LambdaN
LambdaN -> LambdaN -> Bool
LambdaN -> LambdaN -> Ordering
LambdaN -> LambdaN -> LambdaN
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: LambdaN -> LambdaN -> LambdaN
$cmin :: LambdaN -> LambdaN -> LambdaN
max :: LambdaN -> LambdaN -> LambdaN
$cmax :: LambdaN -> LambdaN -> LambdaN
>= :: LambdaN -> LambdaN -> Bool
$c>= :: LambdaN -> LambdaN -> Bool
> :: LambdaN -> LambdaN -> Bool
$c> :: LambdaN -> LambdaN -> Bool
<= :: LambdaN -> LambdaN -> Bool
$c<= :: LambdaN -> LambdaN -> Bool
< :: LambdaN -> LambdaN -> Bool
$c< :: LambdaN -> LambdaN -> Bool
compare :: LambdaN -> LambdaN -> Ordering
$ccompare :: LambdaN -> LambdaN -> Ordering
$cp1Ord :: Eq LambdaN
Ord, LambdaN
LambdaN -> LambdaN -> Bounded LambdaN
forall a. a -> a -> Bounded a
maxBound :: LambdaN
$cmaxBound :: LambdaN
minBound :: LambdaN
$cminBound :: LambdaN
Bounded, Int -> LambdaN
LambdaN -> Int
LambdaN -> [LambdaN]
LambdaN -> LambdaN
LambdaN -> LambdaN -> [LambdaN]
LambdaN -> LambdaN -> LambdaN -> [LambdaN]
(LambdaN -> LambdaN)
-> (LambdaN -> LambdaN)
-> (Int -> LambdaN)
-> (LambdaN -> Int)
-> (LambdaN -> [LambdaN])
-> (LambdaN -> LambdaN -> [LambdaN])
-> (LambdaN -> LambdaN -> [LambdaN])
-> (LambdaN -> LambdaN -> LambdaN -> [LambdaN])
-> Enum LambdaN
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: LambdaN -> LambdaN -> LambdaN -> [LambdaN]
$cenumFromThenTo :: LambdaN -> LambdaN -> LambdaN -> [LambdaN]
enumFromTo :: LambdaN -> LambdaN -> [LambdaN]
$cenumFromTo :: LambdaN -> LambdaN -> [LambdaN]
enumFromThen :: LambdaN -> LambdaN -> [LambdaN]
$cenumFromThen :: LambdaN -> LambdaN -> [LambdaN]
enumFrom :: LambdaN -> [LambdaN]
$cenumFrom :: LambdaN -> [LambdaN]
fromEnum :: LambdaN -> Int
$cfromEnum :: LambdaN -> Int
toEnum :: Int -> LambdaN
$ctoEnum :: Int -> LambdaN
pred :: LambdaN -> LambdaN
$cpred :: LambdaN -> LambdaN
succ :: LambdaN -> LambdaN
$csucc :: LambdaN -> LambdaN
Enum, Int -> LambdaN -> ShowS
[LambdaN] -> ShowS
LambdaN -> String
(Int -> LambdaN -> ShowS)
-> (LambdaN -> String) -> ([LambdaN] -> ShowS) -> Show LambdaN
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LambdaN] -> ShowS
$cshowList :: [LambdaN] -> ShowS
show :: LambdaN -> String
$cshow :: LambdaN -> String
showsPrec :: Int -> LambdaN -> ShowS
$cshowsPrec :: Int -> LambdaN -> ShowS
Show)

lambdaRules :: LambdaN -> [Rule LambdaN CharT]
lambdaRules :: LambdaN -> [Rule LambdaN CharT]
lambdaRules LambdaN
n = case LambdaN
n of
  LambdaN
LAMBDA ->
    [ [ LambdaN -> Atom LambdaN CharT
forall n t. n -> Atom n t
N LambdaN
VAR ]
    , [ CharT -> Atom LambdaN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'\\']), LambdaN -> Atom LambdaN CharT
forall n t. n -> Atom n t
N LambdaN
VAR, CharT -> Atom LambdaN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'.']), LambdaN -> Atom LambdaN CharT
forall n t. n -> Atom n t
N LambdaN
LAMBDA ]
    , [ CharT -> Atom LambdaN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
'(']), LambdaN -> Atom LambdaN CharT
forall n t. n -> Atom n t
N LambdaN
LAMBDA, CharT -> Atom LambdaN CharT
forall n t. t -> Atom n t
T (String -> CharT
OneOf [Char
')']), LambdaN -> Atom LambdaN CharT
forall n t. n -> Atom n t
N LambdaN
LAMBDA ] ]
  LambdaN
VAR -> [ [ CharT -> Atom LambdaN CharT
forall n t. t -> Atom n t
T CharT
Alpha ] ]

-- | Non-terminals for an ML-like language.
data MlN
  = TERM
  | ATOMS
  | ATOM
  | VAR'
  deriving (MlN -> MlN -> Bool
(MlN -> MlN -> Bool) -> (MlN -> MlN -> Bool) -> Eq MlN
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: MlN -> MlN -> Bool
$c/= :: MlN -> MlN -> Bool
== :: MlN -> MlN -> Bool
$c== :: MlN -> MlN -> Bool
Eq, Eq MlN
Eq MlN
-> (MlN -> MlN -> Ordering)
-> (MlN -> MlN -> Bool)
-> (MlN -> MlN -> Bool)
-> (MlN -> MlN -> Bool)
-> (MlN -> MlN -> Bool)
-> (MlN -> MlN -> MlN)
-> (MlN -> MlN -> MlN)
-> Ord MlN
MlN -> MlN -> Bool
MlN -> MlN -> Ordering
MlN -> MlN -> MlN
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: MlN -> MlN -> MlN
$cmin :: MlN -> MlN -> MlN
max :: MlN -> MlN -> MlN
$cmax :: MlN -> MlN -> MlN
>= :: MlN -> MlN -> Bool
$c>= :: MlN -> MlN -> Bool
> :: MlN -> MlN -> Bool
$c> :: MlN -> MlN -> Bool
<= :: MlN -> MlN -> Bool
$c<= :: MlN -> MlN -> Bool
< :: MlN -> MlN -> Bool
$c< :: MlN -> MlN -> Bool
compare :: MlN -> MlN -> Ordering
$ccompare :: MlN -> MlN -> Ordering
$cp1Ord :: Eq MlN
Ord, MlN
MlN -> MlN -> Bounded MlN
forall a. a -> a -> Bounded a
maxBound :: MlN
$cmaxBound :: MlN
minBound :: MlN
$cminBound :: MlN
Bounded, Int -> MlN
MlN -> Int
MlN -> [MlN]
MlN -> MlN
MlN -> MlN -> [MlN]
MlN -> MlN -> MlN -> [MlN]
(MlN -> MlN)
-> (MlN -> MlN)
-> (Int -> MlN)
-> (MlN -> Int)
-> (MlN -> [MlN])
-> (MlN -> MlN -> [MlN])
-> (MlN -> MlN -> [MlN])
-> (MlN -> MlN -> MlN -> [MlN])
-> Enum MlN
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: MlN -> MlN -> MlN -> [MlN]
$cenumFromThenTo :: MlN -> MlN -> MlN -> [MlN]
enumFromTo :: MlN -> MlN -> [MlN]
$cenumFromTo :: MlN -> MlN -> [MlN]
enumFromThen :: MlN -> MlN -> [MlN]
$cenumFromThen :: MlN -> MlN -> [MlN]
enumFrom :: MlN -> [MlN]
$cenumFrom :: MlN -> [MlN]
fromEnum :: MlN -> Int
$cfromEnum :: MlN -> Int
toEnum :: Int -> MlN
$ctoEnum :: Int -> MlN
pred :: MlN -> MlN
$cpred :: MlN -> MlN
succ :: MlN -> MlN
$csucc :: MlN -> MlN
Enum, Int -> MlN -> ShowS
[MlN] -> ShowS
MlN -> String
(Int -> MlN -> ShowS)
-> (MlN -> String) -> ([MlN] -> ShowS) -> Show MlN
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MlN] -> ShowS
$cshowList :: [MlN] -> ShowS
show :: MlN -> String
$cshow :: MlN -> String
showsPrec :: Int -> MlN -> ShowS
$cshowsPrec :: Int -> MlN -> ShowS
Show)

mlRules :: MlN -> [Rule MlN String]
mlRules :: MlN -> [Rule MlN String]
mlRules MlN
n = case MlN
n of
  MlN
TERM ->
    [ [ MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
ATOMS ]
    , [ String -> Atom MlN String
forall n t. t -> Atom n t
T String
"fun", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
VAR', String -> Atom MlN String
forall n t. t -> Atom n t
T String
"->", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM ]
    , [ String -> Atom MlN String
forall n t. t -> Atom n t
T String
"let", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
VAR', String -> Atom MlN String
forall n t. t -> Atom n t
T String
"=", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM, String -> Atom MlN String
forall n t. t -> Atom n t
T String
"in", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM ]
    , [ String -> Atom MlN String
forall n t. t -> Atom n t
T String
"if", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM, String -> Atom MlN String
forall n t. t -> Atom n t
T String
"then", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM ]
    , [ String -> Atom MlN String
forall n t. t -> Atom n t
T String
"if", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM, String -> Atom MlN String
forall n t. t -> Atom n t
T String
"then", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM, String -> Atom MlN String
forall n t. t -> Atom n t
T String
"else", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM ] ]
  MlN
ATOMS ->
    [ [ MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
ATOM ]
    , [ MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
ATOMS, MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
ATOM ] ]
  MlN
ATOM ->
    [ [ MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
VAR' ]
    , [ String -> Atom MlN String
forall n t. t -> Atom n t
T String
"(", MlN -> Atom MlN String
forall n t. n -> Atom n t
N MlN
TERM, String -> Atom MlN String
forall n t. t -> Atom n t
T String
")" ] ]
  MlN
VAR' -> [ [ String -> Atom MlN String
forall n t. t -> Atom n t
T [Char
x] ] | Char
x <- [Char
'a' .. Char
'z'] ]

-- | Non-terminals for JSON.
data JsonN
  = JSON
  | OBJECT
  | ARRAY
  deriving (JsonN -> JsonN -> Bool
(JsonN -> JsonN -> Bool) -> (JsonN -> JsonN -> Bool) -> Eq JsonN
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: JsonN -> JsonN -> Bool
$c/= :: JsonN -> JsonN -> Bool
== :: JsonN -> JsonN -> Bool
$c== :: JsonN -> JsonN -> Bool
Eq, Eq JsonN
Eq JsonN
-> (JsonN -> JsonN -> Ordering)
-> (JsonN -> JsonN -> Bool)
-> (JsonN -> JsonN -> Bool)
-> (JsonN -> JsonN -> Bool)
-> (JsonN -> JsonN -> Bool)
-> (JsonN -> JsonN -> JsonN)
-> (JsonN -> JsonN -> JsonN)
-> Ord JsonN
JsonN -> JsonN -> Bool
JsonN -> JsonN -> Ordering
JsonN -> JsonN -> JsonN
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: JsonN -> JsonN -> JsonN
$cmin :: JsonN -> JsonN -> JsonN
max :: JsonN -> JsonN -> JsonN
$cmax :: JsonN -> JsonN -> JsonN
>= :: JsonN -> JsonN -> Bool
$c>= :: JsonN -> JsonN -> Bool
> :: JsonN -> JsonN -> Bool
$c> :: JsonN -> JsonN -> Bool
<= :: JsonN -> JsonN -> Bool
$c<= :: JsonN -> JsonN -> Bool
< :: JsonN -> JsonN -> Bool
$c< :: JsonN -> JsonN -> Bool
compare :: JsonN -> JsonN -> Ordering
$ccompare :: JsonN -> JsonN -> Ordering
$cp1Ord :: Eq JsonN
Ord, JsonN
JsonN -> JsonN -> Bounded JsonN
forall a. a -> a -> Bounded a
maxBound :: JsonN
$cmaxBound :: JsonN
minBound :: JsonN
$cminBound :: JsonN
Bounded, Int -> JsonN
JsonN -> Int
JsonN -> [JsonN]
JsonN -> JsonN
JsonN -> JsonN -> [JsonN]
JsonN -> JsonN -> JsonN -> [JsonN]
(JsonN -> JsonN)
-> (JsonN -> JsonN)
-> (Int -> JsonN)
-> (JsonN -> Int)
-> (JsonN -> [JsonN])
-> (JsonN -> JsonN -> [JsonN])
-> (JsonN -> JsonN -> [JsonN])
-> (JsonN -> JsonN -> JsonN -> [JsonN])
-> Enum JsonN
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: JsonN -> JsonN -> JsonN -> [JsonN]
$cenumFromThenTo :: JsonN -> JsonN -> JsonN -> [JsonN]
enumFromTo :: JsonN -> JsonN -> [JsonN]
$cenumFromTo :: JsonN -> JsonN -> [JsonN]
enumFromThen :: JsonN -> JsonN -> [JsonN]
$cenumFromThen :: JsonN -> JsonN -> [JsonN]
enumFrom :: JsonN -> [JsonN]
$cenumFrom :: JsonN -> [JsonN]
fromEnum :: JsonN -> Int
$cfromEnum :: JsonN -> Int
toEnum :: Int -> JsonN
$ctoEnum :: Int -> JsonN
pred :: JsonN -> JsonN
$cpred :: JsonN -> JsonN
succ :: JsonN -> JsonN
$csucc :: JsonN -> JsonN
Enum, Int -> JsonN -> ShowS
[JsonN] -> ShowS
JsonN -> String
(Int -> JsonN -> ShowS)
-> (JsonN -> String) -> ([JsonN] -> ShowS) -> Show JsonN
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [JsonN] -> ShowS
$cshowList :: [JsonN] -> ShowS
show :: JsonN -> String
$cshow :: JsonN -> String
showsPrec :: Int -> JsonN -> ShowS
$cshowsPrec :: Int -> JsonN -> ShowS
Show)

jsonRules :: JsonN -> [Rule JsonN String]
jsonRules :: JsonN -> [Rule JsonN String]
jsonRules JsonN
n = case JsonN
n of
  JsonN
JSON ->
    [ [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"null" ]
    , [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"true" ]
    , [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"false" ]
    , [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"NUMBER" ]
    , [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"STRING" ]
    , [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"{", JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
OBJECT, String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"}" ]
    , [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"[", JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
ARRAY, String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"]" ] ]
  JsonN
OBJECT ->
    [ [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"STRING", String -> Atom JsonN String
forall n t. t -> Atom n t
T String
":", JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
JSON ]
    , [ String -> Atom JsonN String
forall n t. t -> Atom n t
T String
"STRING", String -> Atom JsonN String
forall n t. t -> Atom n t
T String
":", JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
JSON, String -> Atom JsonN String
forall n t. t -> Atom n t
T String
",", JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
OBJECT ] ]
  JsonN
ARRAY ->
    [ [ JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
JSON ]
    , [ JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
JSON, String -> Atom JsonN String
forall n t. t -> Atom n t
T String
",", JsonN -> Atom JsonN String
forall n t. n -> Atom n t
N JsonN
ARRAY ] ]

jsonMatch :: String -> String -> Bool
jsonMatch :: String -> String -> Bool
jsonMatch String
"NUMBER" = (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit  -- Only integers for simplicity.
jsonMatch String
"STRING" = \String
s -> String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 Bool -> Bool -> Bool
&& String -> Char
forall a. [a] -> a
head String
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"' Bool -> Bool -> Bool
&& String -> Char
forall a. [a] -> a
last String
s Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'"'
jsonMatch String
s0 = String -> String -> Bool
forall a. Eq a => a -> a -> Bool
(==) String
s0