1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
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
|