uuagc-0.9.54: src-ag/ExecutionPlanCommon.ag
-------------------------------------------------------------------------------
-- Distributing options
-------------------------------------------------------------------------------
ATTR Grammar Nonterminals Nonterminal Productions Production Children Child
[ options : {Options} | | ]
-------------------------------------------------------------------------------
-- Find out which nonterminals are recursive
-------------------------------------------------------------------------------
ATTR Nonterminals Nonterminal [ | | ntDeps, ntHoDeps USE {`mappend`} {mempty} : {Map NontermIdent (Set NontermIdent)} ]
ATTR Nonterminals Nonterminal [ closedNtDeps, closedHoNtDeps, closedHoNtRevDeps : {Map NontermIdent (Set NontermIdent)} | | ]
ATTR Productions Production Children Child [ | | refNts, refHoNts USE {`mappend`} {mempty} : {Set NontermIdent} ]
SEM Nonterminal | Nonterminal
lhs.ntDeps = Map.singleton @nt @prods.refNts
lhs.ntHoDeps = Map.singleton @nt @prods.refHoNts
loc.closedNtDeps = Map.findWithDefault Set.empty @nt @lhs.closedNtDeps
loc.closedHoNtDeps = Map.findWithDefault Set.empty @nt @lhs.closedHoNtDeps
loc.closedHoNtRevDeps = Map.findWithDefault Set.empty @nt @lhs.closedHoNtRevDeps
loc.recursive = @nt `Set.member` @loc.closedNtDeps
loc.nontrivAcyc = @nt `Set.member` @loc.closedHoNtDeps
loc.hoInfo = HigherOrderInfo { hoNtDeps = @loc.closedHoNtDeps
, hoNtRevDeps = @loc.closedHoNtRevDeps
, hoAcyclic = @loc.nontrivAcyc
}
SEM Child | Child
loc.refNts = case @tp of
NT nt _ _ -> Set.singleton nt
_ -> mempty
loc.refHoNts = if @loc.isHigherOrder then @loc.refNts else mempty
loc.isHigherOrder = case @kind of
ChildSyntax -> False
_ -> True
SEM Grammar | Grammar
loc.closedNtDeps = closeMap @nonts.ntDeps
loc.closedHoNtDeps = closeMap @nonts.ntHoDeps
loc.closedHoNtRevDeps = revDeps @loc.closedHoNtDeps
-------------------------------------------------------------------------------
-- Distribute the ContextMap to nonterminals
-------------------------------------------------------------------------------
ATTR Nonterminals Nonterminal [ classContexts : ContextMap | | ]
SEM Grammar | Grammar
nonts.classContexts = @contextMap
SEM Nonterminal | Nonterminal
loc.classContexts = Map.findWithDefault [] @nt @lhs.classContexts
-------------------------------------------------------------------------------
-- Gather all rules per production for the execution plan
-------------------------------------------------------------------------------
ATTR Expression [ | | copy : SELF ]
ATTR Rule [ | | erules : ERule ]
ATTR Rules [ | | erules USE {:} {[]} : ERules ]
SEM Rule
| Rule lhs.erules = ERule @loc.rulename
@pattern.copy
@rhs.copy
@owrt
@origin
@explicit
@pure
@mbError
-------------------------------------------------------------------------------
-- Determine which children have an around-rule
-------------------------------------------------------------------------------
-- Propagate the around-map downward
ATTR Nonterminals Nonterminal
[ aroundMap : {Map NontermIdent (Map ConstructorIdent (Map Identifier [Expression]))} || ]
ATTR Productions Production
[ aroundMap : {Map ConstructorIdent (Map Identifier [Expression])} || ]
ATTR Children Child
[ aroundMap : {Map Identifier [Expression]} | | ]
SEM Nonterminal | Nonterminal loc.aroundMap = Map.findWithDefault Map.empty @nt @lhs.aroundMap
SEM Production | Production loc.aroundMap = Map.findWithDefault Map.empty @con @lhs.aroundMap
SEM Grammar | Grammar
nonts.aroundMap = @aroundsMap
SEM Child | Child
loc.hasArounds = case Map.lookup @name @lhs.aroundMap of
Nothing -> False
Just as -> not (null as)
-------------------------------------------------------------------------------
-- Determine which children are used by merges
-------------------------------------------------------------------------------
-- Propagate the around-map downward
ATTR Nonterminals Nonterminal
[ mergeMap : {Map NontermIdent (Map ConstructorIdent (Map Identifier (Identifier, [Identifier], Expression)))} || ]
ATTR Productions Production
[ mergeMap : {Map ConstructorIdent (Map Identifier (Identifier, [Identifier], Expression))} || ]
ATTR Children Child
[ mergeMap : {Map Identifier (Identifier, [Identifier], Expression)} mergedChildren : {Set Identifier} | | ]
SEM Nonterminal | Nonterminal loc.mergeMap = Map.findWithDefault Map.empty @nt @lhs.mergeMap
SEM Production | Production loc.mergeMap = Map.findWithDefault Map.empty @con @lhs.mergeMap
SEM Grammar | Grammar
nonts.mergeMap = @mergeMap
SEM Production | Production
loc.mergedChildren = Set.unions [ Set.fromList ms | (_,ms,_) <- Map.elems @loc.mergeMap ]
SEM Child | Child
loc.merges = maybe Nothing (\(_,ms,_) -> Just ms) $ Map.lookup @name @lhs.mergeMap
loc.isMerged = @name `Set.member` @lhs.mergedChildren
-------------------------------------------------------------------------------
-- Gather all childs per production for the execution plan
-------------------------------------------------------------------------------
ATTR Child [ | | echilds : EChild ]
ATTR Children [ | | echilds USE {:} {[]} : EChildren ]
SEM Child
| Child lhs.echilds = case @tp of
NT _ _ _ -> EChild @name @tp @kind @loc.hasArounds @loc.merges @loc.isMerged
_ -> ETerm @name @tp
-------------------------------------------------------------------------------
-- Output nonterminal type mappings
-------------------------------------------------------------------------------
ATTR Grammar
Nonterminals [ | | inhmap USE {`Map.union`} {Map.empty} : {Map.Map NontermIdent Attributes}
synmap USE {`Map.union`} {Map.empty} : {Map.Map NontermIdent Attributes} ]
ATTR Nonterminal [ | | inhmap : {Map.Map NontermIdent Attributes}
synmap : {Map.Map NontermIdent Attributes} ]
SEM Nonterminal
| Nonterminal lhs.inhmap = Map.singleton @nt @inh
lhs.synmap = Map.singleton @nt @syn
-------------------------------------------------------------------------------
-- Output nonterminal type mappings
-------------------------------------------------------------------------------
ATTR Grammar Nonterminals Nonterminal [ | | localSigMap USE {`Map.union`} {Map.empty} : {Map.Map NontermIdent (Map.Map ConstructorIdent (Map.Map Identifier Type))} ]
ATTR Productions Production [ | | localSigMap USE {`Map.union`} {Map.empty} : {Map.Map ConstructorIdent (Map.Map Identifier Type)} ]
ATTR TypeSigs TypeSig [ | | localSigMap USE {`Map.union`} {Map.empty} : {Map Identifier Type} ]
SEM Nonterminal | Nonterminal lhs.localSigMap = Map.singleton @nt @prods.localSigMap
SEM Production | Production lhs.localSigMap = Map.singleton @con @typeSigs.localSigMap
SEM TypeSig | TypeSig lhs.localSigMap = Map.singleton @name @tp