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 { Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal ctxStarts :: EnumMap.EnumMap start nonTerminal , 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) , 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 :: 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 <- GrammarT start nonTerminal terminal elem varDoc altDoc action m () -> Context start nonTerminal terminal elem varDoc altDoc action -> m (Context start nonTerminal terminal elem varDoc altDoc action) forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s execStateT GrammarT start nonTerminal terminal elem varDoc altDoc action m () builder Context start nonTerminal terminal elem varDoc altDoc action forall k k start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action initialCtx FixedGrammar start nonTerminal terminal elem varDoc altDoc action -> m (FixedGrammar start nonTerminal terminal elem varDoc altDoc action) forall (f :: * -> *) a. Applicative f => a -> f a pure do Context start nonTerminal terminal elem varDoc altDoc action -> FixedGrammar start nonTerminal terminal elem varDoc altDoc action 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 :: forall k k start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). EnumMap start nonTerminal -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) -> EnumMap nonTerminal varDoc -> Context start nonTerminal terminal elem varDoc altDoc action Context { $sel:ctxStarts:Context :: EnumMap start nonTerminal ctxStarts = EnumMap start nonTerminal forall k a. EnumMap k a EnumMap.empty , $sel:ctxRules:Context :: EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) ctxRules = EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) forall k a. EnumMap k a EnumMap.empty , $sel:ctxDisplayNonTerminals:Context :: EnumMap nonTerminal varDoc ctxDisplayNonTerminals = EnumMap nonTerminal varDoc 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 :: forall k k start nonTerminal terminal (elem :: k) varDoc altDoc (action :: [k] -> k -> *). EnumMap start nonTerminal -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) -> EnumMap nonTerminal varDoc -> FixedGrammar start nonTerminal terminal elem varDoc altDoc action FixedGrammar { $sel:grammarStarts:FixedGrammar :: EnumMap start nonTerminal grammarStarts = Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal forall start nonTerminal terminal k (elem :: k) varDoc altDoc k (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 = Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) forall start nonTerminal terminal k (elem :: k) varDoc altDoc k (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 = Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal varDoc forall start nonTerminal terminal k (elem :: k) varDoc altDoc k (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 { FixedGrammar start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal grammarStarts :: EnumMap.EnumMap start nonTerminal , 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) , 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 :: start -> nonTerminal -> GrammarT start nonTerminal terminal elem varDoc altDoc action m () initialT start s nonTerminal v = (Context start nonTerminal terminal elem varDoc altDoc action -> Context start nonTerminal terminal elem varDoc altDoc action) -> GrammarT start nonTerminal terminal elem varDoc altDoc action m () 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 = start -> nonTerminal -> EnumMap start nonTerminal -> EnumMap start nonTerminal forall k a. Enum k => k -> a -> EnumMap k a -> EnumMap k a EnumMap.insert start s nonTerminal v do Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap start nonTerminal forall start nonTerminal terminal k (elem :: k) varDoc altDoc k (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 :: 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 = (Context start nonTerminal terminal elem varDoc altDoc action -> Context start nonTerminal terminal elem varDoc altDoc action) -> GrammarT start nonTerminal terminal elem varDoc altDoc action m () 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 = nonTerminal -> RuleExpr nonTerminal terminal elem altDoc action -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) 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 Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal (RuleExpr nonTerminal terminal elem altDoc action) forall start nonTerminal terminal k (elem :: k) varDoc altDoc k (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 = nonTerminal -> varDoc -> EnumMap nonTerminal varDoc -> EnumMap nonTerminal varDoc forall k a. Enum k => k -> a -> EnumMap k a -> EnumMap k a EnumMap.insert nonTerminal v varDoc d do Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal varDoc forall start nonTerminal terminal k (elem :: k) varDoc altDoc k (action :: [k] -> k -> *). Context start nonTerminal terminal elem varDoc altDoc action -> EnumMap nonTerminal varDoc ctxDisplayNonTerminals Context start nonTerminal terminal elem varDoc altDoc action ctx }