packages feed

uuagc-0.9.50: src-ag/ResolveLocals.ag

INCLUDE "AbstractSyntax.ag"
INCLUDE "Patterns.ag"
INCLUDE "Expression.ag"
INCLUDE "DistChildAttr.ag"


--
-- Checks right-hand sides for missing attributes.
-- Attribute references @xxx are now explicitly mapped to @loc.xxx if there is such
-- an attribute in scope and there is no terminal @xxx.
--


imports
{
import qualified Data.Set as Set
import qualified Data.Map as Map
import Data.Map(Map)
import qualified Data.Sequence as Seq
import Data.Sequence(Seq,(><))
import CommonTypes
import Patterns
import ErrorMessages
import AbstractSyntax
import Expression
import Options
import HsToken(HsTokensRoot(HsTokensRoot))
import SemHsTokens(sem_HsTokensRoot,wrap_HsTokensRoot, Syn_HsTokensRoot(..),Inh_HsTokensRoot(..))
import Data.Maybe
}

WRAPPER Grammar


--
-- Main attributes
--

ATTR Grammar Nonterminals Nonterminal Productions Production Rule Rules Expression
  [ options:{Options} | | ]

ATTR Grammar Nonterminals Nonterminal Productions Production Rule Rules Pattern Patterns Expression
  [ | | errors USE {Seq.><} {Seq.empty} : {Seq Error} ]

ATTR Grammar Nonterminals Nonterminal Productions Production Child Children Rule Rules Pattern Patterns TypeSig TypeSigs Expression
  [ | | output : SELF ]

--
-- Collect inputs to expressions
--

-- Collecting nts
ATTR Nonterminal Nonterminals
     Production Productions
     Rule Rules
     Child Children [allnts:{[Identifier]} | | ]

SEM Grammar
  | Grammar nonts.allnts = map fst (@nonts.nonts)

ATTR Nonterminals Nonterminal [ | | nonts USE {++} {[]} : {[(NontermIdent,[ConstructorIdent])]} ]
SEM  Nonterminal
  |  Nonterminal  lhs.nonts = [(@nt,@prods.cons)]
ATTR Productions Production [ | | cons USE {++} {[]} : {[ConstructorIdent]} ]
SEM  Production
  |  Production  lhs.cons = [@con]

-- Collecting fields
ATTR Rule Rules
     Child Children [allfields:{[(Identifier,Type,ChildKind)]} attrs:{[(Identifier,Identifier)]} | | ]

SEM Production
  | Production loc.allfields  = @children.fields
                   .attrs      = map ((,) _LOC)  @rules.locVars ++
                                 map ((,) _INST) @rules.instVars ++
                                 map ((,) _LHS)  @inhnames ++
                                 concat [map ((,) nm) (Map.keys as) | (nm,_,as) <- @children.attributes]
                   .inhnames   = Map.keys @lhs.inh
                   .synnames   = Map.keys @lhs.syn

ATTR Children [ | | attributes USE {++} {[]} : {[(Identifier,Attributes,Attributes)]} ]
SEM Child [ | | attributes:{[(Identifier,Attributes,Attributes)]} ]
  | Child lhs.attributes = [(@name, @loc.inh, @loc.syn)]

SEM Child [ | | field : {(Identifier,Type,ChildKind)} ]
  | Child lhs.field = (@name, @tp, @kind)

SEM Children [ | | fields : {[(Identifier,Type,ChildKind)]} ]
  | Cons  lhs.fields = @hd.field : @tl.fields
  | Nil   lhs.fields = []

ATTR Rules Rule Patterns Pattern [ | | locVars USE {++} {[]}:{[Identifier]} instVars USE {++} {[]} : {[Identifier]} ]

SEM Pattern
  | Alias    lhs.locVars   = if @field == _LOC
                                then [@attr]
                                else []
             lhs.instVars  = if @field == _INST
                                then [@attr]
                                else []

--         Distributing name of nonterminal and names of attributes
ATTR Productions Production Child Children Rules Rule Patterns Pattern [ nt : {Identifier} inh,syn : {Attributes} | | ]
ATTR Child Children Rules Rule Patterns Pattern [ con : {Identifier} | | ]

SEM Production
  | Production children . con = @con
SEM Production
  | Production rules . con = @con
SEM Nonterminal
  | Nonterminal prods . nt = @nt

SEM Nonterminal
  | Nonterminal prods.inh  = @inh
                prods.syn  = @syn

-- merge map
SEM Grammar
  | Grammar  nonts.mergeMap  = Map.map (Map.map (Map.map (\(nt,srcs,_) -> (nt,srcs)))) @mergeMap

ATTR Nonterminals Nonterminal
  [ mergeMap : {Map NontermIdent (Map ConstructorIdent (Map Identifier (Identifier,[Identifier])))} | | ]

ATTR Productions Production
  [ mergeMap : {Map ConstructorIdent (Map Identifier (Identifier,[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

ATTR Rules Rule Children Child Expression [ mergeMap : {Map Identifier (Identifier,[Identifier])} | | ]


--
-- Handling Expressions
--

ATTR Expression [ nt,con   :{Identifier}
                  allfields:{[(Identifier,Type,ChildKind)]}
                  allnts   :{[Identifier]}
                  attrs    :{[(Identifier,Identifier)]}
                || ]

SEM Expression
  | Expression  loc.(errors,newTks)
                            = let mergedChildren = [ x | (_,xs) <- Map.elems @lhs.mergeMap, x <- xs ]
                                  attrsIn = filter (\(fld,_) -> not (fld `elem` mergedChildren)) @lhs.attrs
                                  inherited = Inh_HsTokensRoot
                                              { attrs_Inh_HsTokensRoot      = attrsIn
                                              , con_Inh_HsTokensRoot        = @lhs.con
                                              , allfields_Inh_HsTokensRoot  = @lhs.allfields
                                              , allnts_Inh_HsTokensRoot     = @lhs.allnts
                                              , nt_Inh_HsTokensRoot         = @lhs.nt
                                              , options_Inh_HsTokensRoot    = @lhs.options
                                              }
                                  synthesized = wrap_HsTokensRoot (sem_HsTokensRoot (HsTokensRoot @tks)) inherited
                              in (errors_Syn_HsTokensRoot synthesized, output_Syn_HsTokensRoot synthesized)
                lhs.output = Expression @pos @loc.newTks