module Language.Parser.Ptera.Syntax.Grammar ( T, GrammarT, Context (..), fixGrammarT, FixedGrammar (..), Action (..), RuleExpr (..), Alt (..), Expr, Unit (..), initialT, ruleT, ) where import Language.Parser.Ptera.Prelude import qualified Data.EnumMap.Strict as EnumMap import qualified Language.Parser.Ptera.Data.HFList as HFList type T start nonTerminal terminal elem varDoc altDoc action = GrammarT start nonTerminal terminal elem varDoc altDoc action type GrammarT start nonTerminal terminal elem varDoc altDoc action = StateT (Context start nonTerminal terminal elem varDoc altDoc action) data Context start nonTerminal terminal elem varDoc altDoc action = Context { forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal ctxStarts :: EnumMap.EnumMap start nonTerminal , forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) ctxRules :: EnumMap.EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) , forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal varDoc ctxDisplayNonTerminals :: EnumMap.EnumMap nonTerminal varDoc } fixGrammarT :: Monad m => GrammarT start nonTerminal terminal elem varDoc altDoc action m () -> m (FixedGrammar start nonTerminal terminal elem varDoc altDoc action) fixGrammarT :: forall {k} {k} (m :: * -> *) start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Monad m => GrammarT start nonTerminal terminal elem varDoc altDoc action m () -> m (FixedGrammar start nonTerminal terminal elem varDoc altDoc action) fixGrammarT GrammarT start nonTerminal terminal elem varDoc altDoc action m () builder = do Context start nonTerminal terminal elem varDoc altDoc action finalCtx <- forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s execStateT GrammarT start nonTerminal terminal elem varDoc altDoc action m () builder forall {k} {k} {start} {nonTerminal} {terminal} {elem :: k} {varDoc} {altDoc} {action :: [k] -> k -> *}. Context start nonTerminal terminal elem varDoc altDoc action initialCtx forall (f :: * -> *) a. Applicative f => a -> f a pure do forall {k} {k} {start} {nonTerminal} {terminal} {elem :: k} {varDoc} {altDoc} {action :: [k] -> k -> *}. Context start nonTerminal terminal elem varDoc altDoc action -> FixedGrammar start nonTerminal terminal elem varDoc altDoc action fromCtx Context start nonTerminal terminal elem varDoc altDoc action finalCtx where initialCtx :: Context start nonTerminal terminal elem varDoc altDoc action initialCtx = Context { $sel:ctxStarts:Context :: EnumMap start nonTerminal ctxStarts = forall k a. EnumMap k a EnumMap.empty , $sel:ctxRules:Context :: EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) ctxRules = forall k a. EnumMap k a EnumMap.empty , $sel:ctxDisplayNonTerminals:Context :: EnumMap nonTerminal varDoc ctxDisplayNonTerminals = forall k a. EnumMap k a EnumMap.empty } fromCtx :: Context start nonTerminal terminal elem varDoc altDoc action -> FixedGrammar start nonTerminal terminal elem varDoc altDoc action fromCtx Context start nonTerminal terminal elem varDoc altDoc action ctx = FixedGrammar { $sel:grammarStarts:FixedGrammar :: EnumMap start nonTerminal grammarStarts = forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal ctxStarts Context start nonTerminal terminal elem varDoc altDoc action ctx , $sel:grammarRules:FixedGrammar :: EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) grammarRules = forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) ctxRules Context start nonTerminal terminal elem varDoc altDoc action ctx , $sel:grammarDisplayNonTerminals:FixedGrammar :: EnumMap nonTerminal varDoc grammarDisplayNonTerminals = forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal varDoc ctxDisplayNonTerminals Context start nonTerminal terminal elem varDoc altDoc action ctx } data FixedGrammar start nonTerminal terminal elem varDoc altDoc action = FixedGrammar { forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). FixedGrammar start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal grammarStarts :: EnumMap.EnumMap start nonTerminal , forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). FixedGrammar start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) grammarRules :: EnumMap.EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) , forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). FixedGrammar start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal varDoc grammarDisplayNonTerminals :: EnumMap.EnumMap nonTerminal varDoc } data Action (action :: [Type] -> Type -> Type) where Action :: action us a -> Action action data RuleExpr nonTerminal terminal elem altDoc action where RuleExpr :: [Alt nonTerminal terminal elem altDoc action a] -> RuleExpr nonTerminal terminal elem altDoc action data Alt nonTerminal terminal elem altDoc action a where Alt :: Expr nonTerminal terminal elem us -> altDoc -> action us a -> Alt nonTerminal terminal elem altDoc action a type Expr nonTerminal terminal elem = HFList.T (Unit nonTerminal terminal elem) data Unit nonTerminal terminal elem u where UnitToken :: terminal -> Unit nonTerminal terminal elem elem UnitVar :: nonTerminal -> Unit nonTerminal terminal elem u initialT :: Enum start => Monad m => start -> nonTerminal -> GrammarT start nonTerminal terminal elem varDoc altDoc action m () initialT :: forall {k} {k} start (m :: * -> *) nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). (Enum start, Monad m) => start -> nonTerminal -> GrammarT start nonTerminal terminal elem varDoc altDoc action m () initialT start s nonTerminal v = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m () modify' \Context start nonTerminal terminal elem varDoc altDoc action ctx -> Context start nonTerminal terminal elem varDoc altDoc action ctx { $sel:ctxStarts:Context :: EnumMap start nonTerminal ctxStarts = forall k a. Enum k => k -> a -> EnumMap k a -> EnumMap k a EnumMap.insert start s nonTerminal v do forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal ctxStarts Context start nonTerminal terminal elem varDoc altDoc action ctx } ruleT :: Enum nonTerminal => Monad m => nonTerminal -> varDoc -> RuleExpr nonTerminal terminal elem altDoc action -> GrammarT start nonTerminal terminal elem varDoc altDoc action m () ruleT :: forall {k} {k} nonTerminal (m :: * -> *) varDoc terminal (elem :: k) altDoc (action :: [k] -> k -> *) start. (Enum nonTerminal, Monad m) => nonTerminal -> varDoc -> RuleExpr nonTerminal terminal elem altDoc action -> GrammarT start nonTerminal terminal elem varDoc altDoc action m () ruleT nonTerminal v varDoc d RuleExpr nonTerminal terminal elem altDoc action e = forall (m :: * -> *) s. Monad m => (s -> s) -> StateT s m () modify' \Context start nonTerminal terminal elem varDoc altDoc action ctx -> Context start nonTerminal terminal elem varDoc altDoc action ctx { $sel:ctxRules:Context :: EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) ctxRules = forall k a. Enum k => k -> a -> EnumMap k a -> EnumMap k a EnumMap.insert nonTerminal v RuleExpr nonTerminal terminal elem altDoc action e do forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) ctxRules Context start nonTerminal terminal elem varDoc altDoc action ctx , $sel:ctxDisplayNonTerminals:Context :: EnumMap nonTerminal varDoc ctxDisplayNonTerminals = forall k a. Enum k => k -> a -> EnumMap k a -> EnumMap k a EnumMap.insert nonTerminal v varDoc d do forall {k} {k} start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal varDoc ctxDisplayNonTerminals Context start nonTerminal terminal elem varDoc altDoc action ctx }