packages feed

AspectAG-0.5.0.0: examples/RepminTH.lhs




To use AspectAG in a module, some extensions must be enabled,
otherwise type errors we won't have readable type errors.


> {-# LANGUAGE TemplateHaskell #-}
> {-# LANGUAGE FlexibleContexts  #-}
> {-# LANGUAGE GADTs #-}
> {-# LANGUAGE TypeFamilies #-}

> {-# LANGUAGE AllowAmbiguousTypes #-}
> {-# LANGUAGE NoMonomorphismRestriction #-}
> {-# LANGUAGE DataKinds #-}

> {-# LANGUAGE FlexibleInstances #-}
> {-# LANGUAGE MultiParamTypeClasses #-}
> {-# LANGUAGE TypeApplications #-}


> module RepminTH where

> import Language.Grammars.AspectAG
> import Language.Grammars.AspectAG.TH


To add a nonterminal we can use the TH function |addNont|:

> $(addNont "Root")
> $(addNont "Tree")

The produce the following code:

< type Nt_Root = NT "Root"
< nt_Root = Label :: Label Nt_Root

< type Nt_Tree = NT "Tree"
< nt_Tree = Label :: Label (Nt_Tree)


After, we generate productions:


> $(addProd "Leaf" ''Nt_Tree [("val", Ter ''Int)])
> $(addProd "Node" ''Nt_Tree [("l", NonTer ''Nt_Tree),("r", NonTer ''Nt_Tree)])
> $(addProd "Root" ''Nt_Root [("tree",NonTer ''Nt_Tree)])


Semantic functions and a datatype by hand (for now)

> data Root = Root Tree deriving Show
> data Tree = Leaf Int | Node Tree Tree deriving Show


> sem_Root asp (Root t)
>  = knitAspect p_Root asp $ ch_tree .=. sem_Tree asp t .*. EmptyRec

> sem_Tree asp (Leaf i)
>  = knitAspect p_Leaf asp $ ch_val .=. sem_Lit i .*. EmptyRec
> sem_Tree asp (Node l r)
>  = knitAspect p_Node asp
>  $   ch_l .=. sem_Tree asp l
>  .*. ch_r .=. sem_Tree asp r
>  .*. EmptyRec


> $(attLabels [("sres", ''Tree), ("smin", ''Int), ("ival", ''Int)])

> asp_smin
>  =   syn smin p_Node (min @ Int <$> at ch_l smin <*> at ch_r smin)
>  .+: syn smin p_Leaf (ter ch_val)
>  .+: emptyAspect

> asp_sres
>  =    syn sres p_Node (Node <$> at ch_l sres <*> at ch_r sres)
>  .+:  syn sres p_Leaf (Leaf <$> at lhs ival)
>  .+:  syn sres p_Root (at ch_tree sres)
>  .+:  emptyAspect

> asp_ival
>  =    inh ival p_Root ch_tree (at ch_tree smin)
>  .+:  inh ival p_Node ch_l (at lhs ival)
>  .+:  inh ival p_Node ch_r (at lhs ival)
>  .+:  emptyAspect

> asp_repmin
>   = asp_smin .:+: asp_sres .:+: asp_ival

> repmin t
>   = sem_Root asp_repmin (Root t)
>          emptyAtt #. sres


Another way to build  semantic functions:

> semRoot_Root asp tree
>  = knitAspect p_Root asp
>  $ ch_tree .=. tree .*. EmptyRec

> semTree_Node asp l r
>  = knitAspect p_Node asp
>  $    ch_l .=. l
>  .*.  ch_r .=. r
>  .*.  EmptyRec

> semTree_Leaf asp i
>  = knitAspect p_Leaf asp
>  $ ch_val .=. i .*. EmptyRec

> semR asp (Root t)    = semRoot_Root asp (semT asp t)
> semT asp (Node l r)  = semTree_Node asp (semT asp l) (semT asp r)
> semT asp (Leaf i)    = semTree_Leaf asp (sem_Lit i)


> repmin' t = semR asp_repmin (Root t) emptyAtt #. sres