uuagc-0.9.53: src-ag/LOAG/Prepare.ag
INCLUDE "AbstractSyntax.ag"
INCLUDE "Patterns.ag"
INCLUDE "CodeSyntax.ag"
INCLUDE "Expression.ag"
INCLUDE "HsToken.ag"
INCLUDE "LOAG/Rep"
INCLUDE "ExecutionPlanPre"
MODULE {LOAG.Prepare}
{}
{}
{
-- | Translating UUAGC types to MyTypes
drhs f | f == _LHS = Inh
| f == _LOC = AnyDir
| f == _INST = AnyDir
| otherwise = Syn
dlhs f | f == _LHS = Syn
| f == _LOC = AnyDir
| f == _INST = AnyDir
| otherwise = Inh
depToEdge :: PMP_R -> PLabel -> Dependency -> Edge
depToEdge pmpr p e =
(findWithErr pmpr "depToEdge" $ MyOccurrence (p,getName f1) (getName i1, drhs f1),
findWithErr pmpr "depToEdge" $ MyOccurrence (p,getName f2) (getName i2, dlhs f2))
where Dependency (OccAttr f1 i1) (OccAttr f2 i2) = e
vertexToAttr :: NMP -> Vertex -> Attributes
vertexToAttr nmp v = Map.singleton (identifier a) (fromMyTy ty)
where (MyAttribute ty (a,_)) = findWithErr nmp "vertexToAttr" v
}
SEM Grammar | Grammar
inst.smf : LOAGRep
loc.initO= if Map.null @nonts.pmp then 1 else fst $ Map.findMin @nonts.pmp
inst.smf =
LOAGRep @nonts.ps @nonts.ap @loc.an
@loc.ain @loc.asn @loc.sfp
@nonts.pmp @nonts.pmpr @loc.nmp @loc.nmpr
(A.array (@loc.initO, @loc.initO + Map.size @nonts.gen) $
Map.toList $ @nonts.gen)
(A.array (1,Map.size @nonts.inss) $
Map.toList $ @nonts.inss)
(A.array (@loc.initO, @loc.initO + length @nonts.ofld) $
@nonts.ofld) @nonts.fty @nonts.fieldMap @nonts.fsInP
loc.nmp = Map.fromList $ zip [1..] @loc.atts
loc.nmpr = Map.fromList $ zip @loc.atts [1..]
loc.an = Map.unionWith (++) @loc.ain @loc.asn
loc.ain = @nonts.inhs
loc.asn = @nonts.syns
loc.atts = concat $ Map.elems @loc.an
loc.occs = concat $ Map.elems @nonts.ap
nonts.augM = @manualAttrOrderMap
-- Collecting the attributes
ATTR Nonterminals Nonterminal [
augM : {Map.Map Identifier (Map.Map Identifier (Set.Set Dependency))} ||
inhs USE {Map.union} {Map.empty} : AI_N
syns USE {Map.union} {Map.empty} : AS_N ]
SEM Nonterminal | Nonterminal
lhs.inhs = let dty = TyData (getName @nt)
in Map.singleton dty (toMyAttr Inh dty @inh)
lhs.syns = let dty = TyData (getName @nt)
in Map.singleton dty (toMyAttr Syn dty @syn)
prods.augM = case Map.lookup @nt @lhs.augM of
Nothing -> Map.empty
Just a -> a
-- Adding all attribute sets to the AG type
-- and sending it all down the abstract tree
ATTR Nonterminals Nonterminal Productions Production Children Child
MySegments MySegment [
ain : {MyType -> MyAttributes}
asn : {MyType -> MyAttributes}
pmpf : PMP
pmprf : PMP_R
lfpf : SF_P
hoMapf: HOMap
fty : FTY
nmp : NMP || ]
SEM Grammar | Grammar
nonts.ain = map2F @loc.ain
nonts.asn = map2F @loc.asn
nonts.pmpf = @nonts.pmp
nonts.pmprf = @nonts.pmpr
nonts.lfpf = @nonts.lfp
nonts.hoMapf= @nonts.hoMap
nonts.ftyf = @nonts.fty
nonts.fty = @nonts.fty
-- Make sure TDP AND LFPRF are passed around correctly to code-generation
ATTR Nonterminals Nonterminal Productions Production [
ftyf: FTY ||]
-- Calculate the set of production labels
SEM Grammar | Grammar
loc.ps = @nonts.ps
ATTR Nonterminals Nonterminal Productions Production [ ||
ads USE {(++)} {[]} : {[Edge]}
fieldMap USE {(Map.union)} {Map.empty} : FMap
hoMap USE {(Map.union)} {Map.empty} : HOMap
fsInP USE {(Map.union)} {Map.empty} : FsInP]
SEM Nonterminals Nonterminal [ ||
ps USE {(++)} {([])} : {[PLabel]} ]
SEM Productions [ ||
ps USE {:} {([])} : {[PLabel]} ]
SEM Production [ || ps : PLabel ] | Production
loc.ps = (@lhs.dty,getName @con)
lhs.ads =
case Map.lookup @con @lhs.augM of
Nothing -> []
Just a -> Set.toList $ Set.map (depToEdge @children.pmpr @loc.pll) a
children.dty = @lhs.dty
ATTR Productions Production [
augM : {Map.Map Identifier (Set.Set Dependency)} || ]
-- We didnt calculate A_P yet, inheriting A_N we can
ATTR Productions Production Rules Rule [
-- result type of this constructor
dty : {MyType} || ]
ATTR Rules Rule Children Child Expression HsTokensRoot HsTokens HsToken [
pll : {PLabel} || ]
SEM Nonterminal | Nonterminal
loc.dty = TyData (getName @nt)
ATTR Nonterminals Nonterminal Productions Production Children Child
FieldAtts FieldAtt [
an : {MyType -> MyAttributes}
nmprf : NMP_R|
olab : Int -- chained attribute for handing out labels to occurrences
flab : Int |--chained attribute for handing out labels to fields
ap USE {Map.unionWith (++)} {Map.empty} : A_P
gen USE {Map.union} {Map.empty} : {Map Int Int}
inss USE {Map.unionWith (++)} {Map.empty} : {Map Int [Int]}
pmp USE {Map.union} {Map.empty} : PMP
pmpr USE {Map.union} {Map.empty} : PMP_R
-- maps for each occurrence to which field it belongs
ofld USE {(++)} {[]} : {[(Int, Int)]}
fty USE {Map.union} {Map.empty} : FTY
]
SEM Grammar | Grammar
nonts.an = map2F @loc.an
nonts.nmprf= @loc.nmpr
nonts.olab = if Map.null @loc.nmp then 0 else (fst $ Map.findMax @loc.nmp)
nonts.flab = 0
ATTR Children Child [||
fieldMap USE {Map.union} {Map.empty} : FMap
hoMap USE {Map.unionWith (Set.union)} {Map.empty} : HOMap
]
SEM Children [ dty : {MyType} || ]
| Nil
loc.flab = @lhs.flab + 1
loc.atp = fst @lhs.pll
inst.fatts : FieldAtts
inst.fatts = map ((FieldAtt @loc.atp @lhs.pll "lhs") . alab) $
@lhs.an @loc.atp
fatts.flab = @loc.flab
loc.label = (@lhs.pll, "lhs")
loc.foccsI = Set.fromList $ handAllOut @loc.label $ @lhs.ain @loc.atp
loc.foccsS = Set.fromList $ handAllOut @loc.label $ @lhs.asn @loc.atp
loc.fieldMap= Map.singleton @loc.label (@loc.foccsI, @loc.foccsS)
lhs.fty = Map.singleton @loc.label @lhs.dty
SEM Child | Child
loc.flab = @lhs.flab + 1
loc.atp = toMyTy @tp
inst.fatts : FieldAtts
inst.fatts = map ((FieldAtt @loc.atp @lhs.pll (getName @name)) . alab)
$ @lhs.an @loc.atp
fatts.flab = @loc.flab
loc.ident = getName @name
loc.label = (@lhs.pll, @loc.ident)
loc.foccsI = Set.fromList $ handAllOut @loc.label $ @lhs.ain @loc.atp
loc.foccsS = Set.fromList $ handAllOut @loc.label $ @lhs.asn @loc.atp
loc.fieldMap= if Set.null @loc.foccsI && Set.null @loc.foccsS
then Map.empty
else Map.singleton @loc.label (@loc.foccsS,@loc.foccsI)
loc.hoMap = case @kind of
ChildAttr -> Map.singleton @lhs.pll (Set.singleton @loc.ident)
_ -> Map.empty
lhs.fty = Map.singleton (@lhs.pll, getName @name) @loc.atp
SEM FieldAtt | FieldAtt
loc.olab = @lhs.olab + 1
loc.alab = findWithErr @lhs.nmprf "getting attr label" @loc.att
loc.att = @t <.> @a
loc.occ = (@p, @f) >.< @a
loc.pmp = Map.singleton @loc.olab @loc.occ
loc.pmpr = Map.singleton @loc.occ @loc.olab
loc.inss = Map.singleton @loc.alab [@loc.olab]
loc.gen = Map.singleton @loc.olab @loc.alab
lhs.ap = Map.singleton @p [@loc.occ]
lhs.ofld = [(@loc.olab, @lhs.flab)]
-- calculate representation of semantic function
-- definitions per non-terminal and from it, calculate E_P
SEM Grammar | Grammar
loc.sfp = repLocRefs @nonts.lfp $ addHigherOrders @nonts.lfp @nonts.sfp
ATTR Nonterminals Nonterminal Productions Production Rules Rule [ ||
sfp USE {Map.unionWith (Set.union)} {Map.empty} : SF_P -- deps of non-locals
ruleMap USE {Map.union} {Map.empty} : {Map.Map MyOccurrence Identifier}
lfp USE {Map.unionWith (Set.union)} {Map.empty} : SF_P -- deps of local attrs
lfpr USE {Map.unionWith (Set.union)} {Map.empty} : SF_P ]-- reverse
SEM Production | Production
loc.pll = (@lhs.dty,getName @con)
rules.pll = @pll
rules.pts = @children.pts
lhs.fsInP = Map.singleton @pll $ Map.keys @children.fieldMap
ATTR Children Child [ ||
pts USE {Set.union} {Set.empty} : {Set.Set FLabel} ]
SEM Child | Child
lhs.pts = Set.singleton $ getName @name
ATTR Rules Rule [
lfpf : SF_P ||
usedLocals USE {(Set.union)} {Set.empty} : {Set.Set MyOccurrence}]
SEM Rule | Rule
loc.usedLocals = Set.filter (\(MyOccurrence (_,f) _) -> f == "loc") @rhs.used
loc.usesLocals = not $ Set.null @loc.usedLocals
(lhs.sfp,lhs.ruleMap,lhs.lfp,lhs.lfpr) =
foldr (\(f, a, b) (m',rm', l', lr') ->
let att = (@lhs.pll, f) >.< a
rm = Map.insert att @rulename rm'
l = if @loc.usesLocals && not b
then Map.insert att @loc.usedLocals l'
else l'
lr = if @loc.usesLocals && not b
then Set.fold (\k m -> Map.insertWith (Set.union) k
(Set.singleton att) m) lr' @loc.usedLocals
else lr'
sfpins = Map.insert att (@rhs.used `Set.union` fromHO) m'
fromHO = maybe Set.empty id (Map.lookup hOcc @lhs.lfpf)
where hOcc = (@lhs.pll, "inst") >.< (f, AnyDir)
in if b
then (m',rm, Map.insert att @rhs.used l,
Set.fold (\k m -> Map.insertWith (Set.union) k
(Set.singleton att) m) lr @rhs.used)
else (sfpins,rm,l,lr))
(Map.empty,Map.empty,Map.empty,Map.empty) @pattern.afs
ATTR Patterns Pattern [ ||
-- the boolean represents whether this occurrence is
-- an transparent occurrence (only there to pass on dependencies)
afs USE {++} {[]} : {[(FLabel, ALabel, Bool)]} ]
SEM Pattern | Alias
lhs.afs = let isLocal = (@field == _LOC || @field == _INST)
in [(getName @field, (getName @attr, dlhs @field),
isLocal)] ++ @pat.afs
ATTR Rules Rule Expression HsTokensRoot HsTokens HsToken [
-- the terminals of current production
pts : {Set.Set (FLabel)} || ]
ATTR Rule Expression HsTokensRoot HsTokens HsToken [ ||
used USE {Set.union} {Set.empty} : {Set.Set MyOccurrence} ]
SEM Expression | Expression
inst.tokens : HsTokensRoot
inst.tokens = HsTokensRoot @tks
tokens.pll = @lhs.pll
tokens.pts = @lhs.pts
lhs.used = @tokens.used
-- reference to terminals of which some are local attributes
SEM HsToken | AGLocal
lhs.used =
case getName @var `Set.member` @lhs.pts of
True -> Set.empty
-- local found without flabel
False -> Set.singleton $ (@lhs.pll, getName _LOC) >.<
(getName @var, drhs _LOC)
-- includes both locals and attributes
-- locals will be replaced later by repLocRefs
SEM HsToken | AGField
lhs.used = Set.singleton $ (@lhs.pll, getName @field) >.<
(getName @attr, drhs @field)
{
-- | Replace the references to local attributes, by his attrs dependencies,
-- | rendering the local attributes 'transparent'.
repLocRefs :: SF_P -> SF_P -> SF_P
repLocRefs lfp sfp =
Map.map (setConcatMap $ rep Set.empty) sfp
where rep :: Set.Set MyOccurrence -> MyOccurrence -> Set.Set MyOccurrence
rep done occ | occ `Set.member` done = Set.empty
| isLoc occ = setConcatMap (rep $ Set.insert occ done) $
findWithErr lfp "repping locals" occ
| otherwise = Set.singleton occ
-- | Add dependencies from a higher order child to all its attributes
addHigherOrders :: SF_P -> SF_P -> SF_P
addHigherOrders lfp sfp =
Map.mapWithKey f $ Map.map (setConcatMap (\mo -> f mo (Set.singleton mo))) sfp
where f :: MyOccurrence -> Set.Set MyOccurrence -> Set.Set MyOccurrence
f mo@(MyOccurrence (p,f) _) deps =
let ho = ((p,"inst") >.< (f,AnyDir))
in if ho `Map.member` lfp
then ho `Set.insert` deps
else deps
}