module Language.Grammars.Transformations.RemoveFix (removeFix) where
import Language.AbstractSyntax.TTTAS
import Language.Grammars.Grammar
import Language.Grammars.Transformations.GramTrafo
import Control.Arrow
removeFix :: forall a . Grammar a -> Grammar a
removeFix (Grammar start productions)
= case runTrafo (remfixtrafo productions) Unit () of
Result _ (T tt) gram ->
Grammar (tt start) gram
remfixtrafo :: GramEnv env env
-> Trafo Unit (Productions TL) s () (T env s)
remfixtrafo productions = proc _ ->
do rec let tenv_s = map2trans menv_s
menv_s <- (remfixProds productions) -< tenv_s
returnA -< tenv_s
remfixProds :: GramEnv env env'
-> Trafo Unit (Productions TL) s (T env s)
(Mapping env' s)
remfixProds Empty
= proc _ ->
returnA -< Mapping Empty
remfixProds (Ext p (PS prods))
= proc tenv_s ->
do ps <- sequenceA (map remfixProd prods) -< tenv_s
r <- newSRef -< PS ps
Mapping e <- remfixProds p -< tenv_s
returnA -< Mapping (Ext e r)
remfixProd :: Prod l a env
-> Trafo Unit (Productions TL) s (T env s) (Prod l a s)
remfixProd (Fix (PS ps))
= proc tenv_s ->
do rec ps' <- sequenceA (map remfixProd ps) -< tenv_s
r <- newSRef -< PS (map (remVar r) ps')
returnA -< (Sym $ Nont r)
remfixProd (Star f g)
= proc tenv_s ->
do f' <- remfixProd f -< tenv_s
g' <- remfixProd g -< tenv_s
returnA -< Star f' g'
remfixProd (FlipStar f g)
= proc tenv_s ->
do f' <- remfixProd f -< tenv_s
g' <- remfixProd g -< tenv_s
returnA -< FlipStar f' g'
remfixProd p
= proc tenv_s ->
do returnA -< mapProd tenv_s p
remVar :: Ref b env -> Prod (FL b) a env -> Prod TL a env
remVar _ (Sym s) = Sym s
remVar _ (Pure x) = Pure x
remVar r (Star f g) = Star (remVar r f) (remVar r g)
remVar r (FlipStar f g) = FlipStar (remVar r f) (remVar r g)
remVar r Var = Sym (Nont r)
remVar _ (Fix _) = error "RemoveFix(1): error in the transformation!!!"