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