parsley-2.0.0.0: test/Parsley/Precedence/Parsers.hs
{-# LANGUAGE TemplateHaskellQuotes, MultiParamTypeClasses #-}
module Parsley.Precedence.Parsers where
import Prelude hiding (pure, (<*>), (*>), (<*), (<$>), ($>), pred)
import Parsley
import Parsley.Precedence
import Parsley.Fold (somel)
import Parsley.Char (oneOf)
import Data.Char (digitToInt)
data Expr = Add Expr Expr | Mul Expr Expr | Negate Expr | Num Int deriving (Eq, Show)
number :: Parser Int
number = somel [| \x d -> x * 10 + digitToInt d |] [|0|] (oneOf ['0'..'9'])
expr :: Parser Expr
expr = precHomo ([|Num|] <$> number)
[ ops Prefix [string "negate" $> [|Negate|]]
, ops InfixL [char '*' $> [|Mul|]]
, ops InfixR [char '+' $> [|Add|]]
]
data Pred = Or Term Pred | OfTerm Term deriving (Eq, Show)
data Term = And Not Term | OfNot Not deriving (Eq, Show)
data Not = Not Not | OfAtom Atom deriving (Eq, Show)
data Atom = T | F | Parens Pred deriving (Eq, Show)
instance Subtype Atom Not where
upcast = OfAtom
downcast (OfAtom x) = Just x
downcast _ = Nothing
instance Subtype Not Term where
upcast = OfNot
downcast (OfNot x) = Just x
downcast _ = Nothing
pred = precedence $
gops InfixR [char '|' $> [|Or|]] [|OfTerm|] +<
sops InfixR [char '&' $> [|And|]] +<
sops Prefix [char '!' $> [|Not|]] +<
Atom (char 'T' $> [|T|] <|> char 'F' $> [|F|] <|> char '(' *> ([|Parens|] <$> pred) <* char ')')