{-# LANGUAGE DeriveLift, DeriveAnyClass, DeriveGeneric, OverloadedStrings #-}
module Language.ANTLR4.Boot.Syntax
( G4(..), PRHS(..), ProdElem(..), GAnnot(..)
, Directive(..)
, LRHS(..), Regex(..), isGTerm, isGNonTerm
, TermAnnot(..), isMaybeAnnot, isNoAnnot, annot
, prodElemSymbol
) where
import Text.ANTLR.Grammar ()
import Language.Haskell.TH.Lift (Lift(..))
import Language.Haskell.TH.Syntax (Exp)
import qualified Language.Haskell.TH.Syntax as S
import Text.ANTLR.Set ( Hashable(..), Generic(..) )
import Text.ANTLR.Pretty
data G4 =
Grammar { gName :: String
}
| Prod { pName :: String
, patterns :: [PRHS]
}
| Lex { annotation :: Maybe GAnnot
, lName :: String
, pattern :: LRHS
}
deriving (Show, Eq, Lift, Generic, Hashable)
instance Prettify G4 where
prettify (Grammar gn) = do
pStr "grammar "
pStr' gn
prettify (Prod n ps) = do
pStr' n
pStr " -> "
incrIndent $ length n + 4
pListLines ps
incrIndent $ 0 - (length n + 4)
prettify (Lex annot ln (LRHS regex dir)) = do
pStr' ln
pStr " -> "
incrIndent $ length ln + 4
prettify regex
incrIndent $ 0 - (length ln + 4)
pStr "("
prettify dir
pStr ")"
instance Lift Exp
data PRHS = PRHS
{ alphas :: [ProdElem]
, pred :: Maybe Exp
, mutator :: Maybe Exp
, pDirective :: Maybe Directive
} deriving (Show, Eq, Lift, Generic)
instance Prettify PRHS where
prettify (PRHS as pred mut pDir) = do
prettify as
pStr "("
pStr' $ show pred; pStr ","
pStr' $ show mut; pStr ","
prettify pDir; pStr ")"
data Directive =
UpperD String
| LowerD String
| HaskellD String
deriving (Show, Eq, Ord, Lift, Generic, Hashable)
instance Prettify Directive where prettify = rshow
instance Hashable PRHS where
hashWithSalt salt prhs = salt `hashWithSalt` alphas prhs
data TermAnnot =
Regular Char
| NoAnnot
deriving (Show, Eq, Ord, Lift, Generic, Hashable)
instance Prettify TermAnnot where
prettify NoAnnot = return ()
prettify (Regular c) = pStr' [c]
annot :: ProdElem -> TermAnnot
annot (GTerm a _) = a
annot (GNonTerm a _) = a
isMaybeAnnot :: TermAnnot -> Bool
isMaybeAnnot (Regular '?') = True
isMaybeAnnot _ = False
isNoAnnot :: TermAnnot -> Bool
isNoAnnot NoAnnot = True
isNoAnnot _ = False
data ProdElem =
GTerm TermAnnot String
| GNonTerm TermAnnot String
deriving (Show, Eq, Ord, Lift, Generic, Hashable)
instance Prettify ProdElem where
prettify (GTerm annot s) = do
pStr' s
prettify annot
prettify (GNonTerm annot s) = do
pStr' s
prettify annot
prodElemSymbol (GTerm _ s) = s
prodElemSymbol (GNonTerm _ s) = s
isGTerm (GTerm _ _) = True
isGTerm _ = False
isGNonTerm (GNonTerm _ _) = True
isGNonTerm _ = False
data GAnnot = Fragment
deriving (Show, Eq, Lift, Generic, Hashable)
data LRHS = LRHS
{ regex :: Regex Char
, directive :: Maybe Directive
}
deriving (Show, Eq, Lift, Generic, Hashable)
data Regex s =
Epsilon
| Literal [s]
| Union [Regex s]
| Concat [Regex s]
| Kleene (Regex s)
| PosClos (Regex s)
| Question (Regex s)
| CharSet [s]
| Negation (Regex s)
| Named String
deriving (Lift, Eq, Show, Generic, Hashable)
instance (Show s, Prettify s) => Prettify (Regex s) where
prettify Epsilon = pStr "ε"
prettify (Literal ss) = do
pStr "\""
mapM prettify ss
pStr "\""
prettify rest = pStr' $ show rest