-- | 'QuasiQuoter' for BNF source.
module Data.Cfg.Bnf.QQ
  ( bnf
  ) where

import Data.Cfg.Bnf.Parser
import Language.Haskell.TH.Quote

-- | 'QuasiQuoter' for BNF source.  Generates a value of type
-- 'Grammar'.  Not usable in pattern, type or declaration positions.
bnf :: QuasiQuoter
bnf :: QuasiQuoter
bnf =
  QuasiQuoter :: (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter
    { quoteExp :: String -> Q Exp
quoteExp = (forall b. Data b => b -> Maybe (Q Exp))
-> Grammar String String -> Q Exp
forall a.
Data a =>
(forall b. Data b => b -> Maybe (Q Exp)) -> a -> Q Exp
dataToExpQ (Maybe (Q Exp) -> b -> Maybe (Q Exp)
forall a b. a -> b -> a
const Maybe (Q Exp)
forall a. Maybe a
Nothing) (Grammar String String -> Q Exp)
-> (String -> Grammar String String) -> String -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Grammar String String
parse
    , quotePat :: String -> Q Pat
quotePat = String -> Q Pat
forall p a. p -> a
err
    , quoteType :: String -> Q Type
quoteType = String -> Q Type
forall p a. p -> a
err
    , quoteDec :: String -> Q [Dec]
quoteDec = String -> Q [Dec]
forall p a. p -> a
err
    }
  where
    err :: p -> a
err p
_ = String -> a
forall a. HasCallStack => String -> a
error String
"The bnf quasiquoter is only allowed in Exp position."