+usages_part :: { UsagesMap }
+usages_part : USAGES_PART module_stuff_pairs { bagToFM $2 }
+ | { emptyFM }
+
+versions_part :: { VersionsMap }
+versions_part : VERSIONS_PART name_version_pairs { bagToFM $2 }
+ | { emptyFM }
+
+module_stuff_pairs :: { Bag (Module, (Version, FiniteMap FAST_STRING Version)) }
+module_stuff_pairs : module_stuff_pair
+ { unitBag $1 }
+ | module_stuff_pairs module_stuff_pair
+ { $1 `snocBag` $2 }
+
+module_stuff_pair :: { (Module, (Version, FiniteMap FAST_STRING Version)) }
+module_stuff_pair : CONID INTEGER DCOLON name_version_pairs SEMI
+ { ($1, (fromInteger $2, bagToFM $4)) }
+
+name_version_pairs :: { Bag (FAST_STRING, Int) }
+name_version_pairs : name_version_pair
+ { unitBag $1 }
+ | name_version_pairs name_version_pair
+ { $1 `snocBag` $2 }
+
+name_version_pair :: { (FAST_STRING, Int) }
+name_version_pair : name INTEGER
+ { ($1, fromInteger $2)
+--------------------------------------------------------------------------
+ }
+
+exports_part :: { ExportsMap }
+exports_part : EXPORTS_PART export_items { bagToFM $2 }
+ | { emptyFM }
+
+export_items :: { Bag (FAST_STRING, (OrigName, ExportFlag)) }
+export_items : export_item { unitBag $1 }
+ | export_items export_item { $1 `snocBag` $2 }
+
+export_item :: { (FAST_STRING, (OrigName, ExportFlag)) }
+export_item : CONID name maybe_dotdot { ($2, (OrigName $1 $2, $3)) }
+
+maybe_dotdot :: { ExportFlag }
+maybe_dotdot : DOTDOT { ExportAll }
+ | { ExportAbs
+--------------------------------------------------------------------------
+ }
+
+inst_modules_part :: { Bag Module }
+inst_modules_part : INSTANCE_MODULES_PART mod_list { $2 }
+ | { emptyBag }
+
+mod_list :: { Bag Module }
+mod_list : CONID { unitBag $1 }
+ | mod_list CONID { $1 `snocBag` $2
+--------------------------------------------------------------------------
+ }
+
+fixities_part :: { FixitiesMap }
+fixities_part : FIXITIES_PART fixes { $2 }
+ | { emptyFM }
+
+fixes :: { FixitiesMap }
+fixes : fix { case $1 of (k,v) -> unitFM k v }
+ | fixes fix { case $2 of (k,v) -> addToFM $1 k v }
+
+fix :: { (FAST_STRING, RdrNameFixityDecl) }
+fix : INFIXL INTEGER qname SEMI { (de_qual $3, InfixL $3 (fromInteger $2)) }
+ | INFIXR INTEGER qname SEMI { (de_qual $3, InfixR $3 (fromInteger $2)) }
+ | INFIX INTEGER qname SEMI { (de_qual $3, InfixN $3 (fromInteger $2))
+--------------------------------------------------------------------------
+ }
+
+decls_part :: { (LocalTyDefsMap, LocalValDefsMap) }
+decls_part : DECLARATIONS_PART topdecls { $2 }
+ | { (emptyFM, emptyFM) }
+
+topdecls :: { (LocalTyDefsMap, LocalValDefsMap) }
+topdecls : topdecl { $1 }
+ | topdecls topdecl { case $1 of { (ts1, vs1) ->
+ case $2 of { (ts2, vs2) ->
+ (plusFM ts1 ts2, plusFM vs1 vs2)}}
+ }
+
+topdecl :: { (LocalTyDefsMap, LocalValDefsMap) }
+topdecl : typed SEMI { ($1, emptyFM) }
+ | datad SEMI { $1 }
+ | newtd SEMI { $1 }
+ | classd SEMI { $1 }
+ | decl { case $1 of { (n, Sig qn ty _ loc) ->
+ (emptyFM, unitFM n (ValSig qn loc ty)) }
+ }
+
+typed :: { LocalTyDefsMap }
+typed : TYPE simple EQUAL type { mk_type $2 $4 }
+
+datad :: { (LocalTyDefsMap, LocalValDefsMap) }
+datad : DATA simple EQUAL constrs { mk_data [] $2 $4 }
+ | DATA context DARROW simple EQUAL constrs { mk_data $2 $4 $6 }
+
+newtd :: { (LocalTyDefsMap, LocalValDefsMap) }
+newtd : NEWTYPE simple EQUAL constr1 { mk_new [] $2 $4 }
+ | NEWTYPE context DARROW simple EQUAL constr1 { mk_new $2 $4 $6 }
+
+classd :: { (LocalTyDefsMap, LocalValDefsMap) }
+classd : CLASS class cbody { mk_class [] $2 $3 }
+ | CLASS context DARROW class cbody { mk_class $2 $4 $5 }
+
+cbody :: { [(FAST_STRING, RdrNameSig)] }
+cbody : WHERE OCURLY decls CCURLY { $3 }
+ | { [] }
+
+decls :: { [(FAST_STRING, RdrNameSig)] }
+decls : decl { [$1] }
+ | decls decl { $1 ++ [$2] }
+
+decl :: { (FAST_STRING, RdrNameSig) }
+decl : var DCOLON ctype SEMI { (de_qual $1, Sig $1 $3 noGenPragmas mkIfaceSrcLoc) }
+
+context :: { RdrNameContext }
+context : DOCURLY context_list DCCURLY { reverse $2 }
+
+context_list :: { RdrNameContext{-reversed-} }
+context_list : class { [$1] }
+ | context_list COMMA class { $3 : $1 }
+
+class :: { (RdrName, RdrName) }
+class : gtycon VARID { ($1, Unqual $2) }
+
+ctype :: { RdrNamePolyType }
+ctype : FORALL OBRACK tyvars CBRACK context DARROW type { HsForAllTy (map Unqual $3) $5 $7 }
+ | FORALL OBRACK tyvars CBRACK type { HsForAllTy (map Unqual $3) [] $5 }
+ | type { HsForAllTy [] [] $1 }
+
+type :: { RdrNameMonoType }
+type : btype { $1 }
+ | btype RARROW type { MonoFunTy $1 $3 }
+
+types :: { [RdrNameMonoType] }
+types : type { [$1] }
+ | types COMMA type { $1 ++ [$3] }
+
+btype :: { RdrNameMonoType }
+btype : gtyconapp { case $1 of (tc, tys) -> MonoTyApp tc tys }
+ | ntyconapp { case $1 of { (ty1, tys) ->
+ if null tys
+ then ty1
+ else
+ case ty1 of {
+ MonoTyVar tv -> MonoTyApp tv tys;
+ MonoTyApp tc ts -> MonoTyApp tc (ts++tys);
+ MonoFunTy t1 t2 -> MonoTyApp (preludeQual SLIT("->")) (t1:t2:tys);
+ MonoListTy ty -> MonoTyApp (preludeQual SLIT("[]")) (ty:tys);
+ MonoTupleTy ts -> MonoTyApp (preludeQual (mkTupNameStr (length ts)))
+ (ts++tys);
+-- _ -> pprPanic "test:" (ppr PprDebug $1)
+ }}
+ }
+
+ntyconapp :: { (RdrNameMonoType, [RdrNameMonoType]) }
+ntyconapp : ntycon { ($1, []) }
+ | ntyconapp atype { case $1 of (t1,tys) -> (t1, tys ++ [$2]) }
+
+gtyconapp :: { (RdrName, [RdrNameMonoType]) }
+gtyconapp : gtycon { ($1, []) }
+ | gtyconapp atype { case $1 of (tc,tys) -> (tc, tys ++ [$2]) }
+
+atype :: { RdrNameMonoType }
+atype : gtycon { MonoTyApp $1 [] }
+ | ntycon { $1 }
+
+atypes :: { [RdrNameMonoType] }
+atypes : atype { [$1] }
+ | atypes atype { $1 ++ [$2] }
+
+ntycon :: { RdrNameMonoType }
+ntycon : VARID { MonoTyVar (Unqual $1) }
+ | OPAREN type COMMA types CPAREN { MonoTupleTy ($2 : $4) }
+ | OBRACK type CBRACK { MonoListTy $2 }
+ | OPAREN type CPAREN { $2 }
+
+gtycon :: { RdrName }
+gtycon : QCONID { $1 }
+ | OPAREN RARROW CPAREN { preludeQual SLIT("->") }
+ | OBRACK CBRACK { preludeQual SLIT("[]") }
+ | OPAREN CPAREN { preludeQual SLIT("()") }
+ | OPAREN commas CPAREN { preludeQual (mkTupNameStr $2) }
+
+commas :: { Int }
+commas : COMMA { 2{-1 comma => arity 2-} }
+ | commas COMMA { $1 + 1 }
+
+simple :: { (RdrName, [FAST_STRING]) }
+simple : gtycon { ($1, []) }
+ | gtyconvars { case $1 of (tc,tvs) -> (tc, reverse tvs) }
+
+gtyconvars :: { (RdrName, [FAST_STRING] {-reversed-}) }
+gtyconvars : gtycon VARID { ($1, [$2]) }
+ | gtyconvars VARID { case $1 of (tc,tvs) -> (tc, $2 : tvs) }
+
+constrs :: { [(RdrName, RdrNameConDecl)] }
+constrs : constr { [$1] }
+ | constrs VBAR constr { $1 ++ [$3] }
+
+constr :: { (RdrName, RdrNameConDecl) }
+constr : btyconapp
+ { case $1 of (con, tys) -> (con, ConDecl con tys mkIfaceSrcLoc) }
+ | QCONSYM { ($1, ConDecl $1 [] mkIfaceSrcLoc) }
+ | QCONSYM batypes { ($1, ConDecl $1 $2 mkIfaceSrcLoc) }
+ | gtycon OCURLY fields CCURLY
+ { ($1, RecConDecl $1 $3 mkIfaceSrcLoc) }
+
+btyconapp :: { (RdrName, [RdrNameBangType]) }
+btyconapp : gtycon { ($1, []) }
+ | btyconapp batype { case $1 of (tc,tys) -> (tc, tys ++ [$2]) }
+
+batype :: { RdrNameBangType }
+batype : atype { Unbanged (HsForAllTy [{-ToDo:tvs-}] [] $1) }
+ | BANG atype { Banged (HsForAllTy [{-ToDo:tvs-}] [] $2) }
+
+batypes :: { [RdrNameBangType] }
+batypes : batype { [$1] }
+ | batypes batype { $1 ++ [$2] }
+
+fields :: { [([RdrName], RdrNameBangType)] }
+fields : field { [$1] }
+ | fields COMMA field { $1 ++ [$3] }
+
+field :: { ([RdrName], RdrNameBangType) }
+field : var DCOLON type { ([$1], Unbanged (HsForAllTy [{-ToDo:tvs-}] [] $3)) }
+ | var DCOLON BANG atype { ([$1], Banged (HsForAllTy [{-ToDo:tvs-}] [] $4)) }
+
+constr1 :: { (RdrName, RdrNameMonoType) }
+constr1 : gtycon atype { ($1, $2) }
+
+var :: { RdrName }
+var : QVARID { $1 }
+ | QVARSYM { $1 }
+
+qname :: { RdrName }
+qname : QVARID { $1 }
+ | QCONID { $1 }
+ | QVARSYM { $1 }
+ | QCONSYM { $1 }
+
+name :: { FAST_STRING }
+name : VARID { $1 }
+ | CONID { $1 }
+ | VARSYM { $1 }
+ | BANG { SLIT("!"){-sigh, double-sigh-} }
+ | CONSYM { $1 }
+ | OBRACK CBRACK { SLIT("[]") }
+ | OPAREN CPAREN { SLIT("()") }
+ | OPAREN commas CPAREN { mkTupNameStr $2 }
+
+instances_part :: { Bag RdrIfaceInst }
+instances_part : INSTANCES_PART instdecls { $2 }
+ | { emptyBag }
+
+instdecls :: { Bag RdrIfaceInst }
+instdecls : instd { unitBag $1 }
+ | instdecls instd { $1 `snocBag` $2 }
+
+instd :: { RdrIfaceInst }
+instd : INSTANCE FORALL OBRACK tyvars CBRACK context DARROW gtycon restrict_inst SEMI { mk_inst (map Unqual $4) $6 $8 $9 }
+ | INSTANCE FORALL OBRACK tyvars CBRACK gtycon general_inst SEMI { mk_inst (map Unqual $4) [] $6 $7 }
+ | INSTANCE gtycon general_inst SEMI { mk_inst [] [] $2 $3 }
+
+restrict_inst :: { RdrNameMonoType }
+restrict_inst : gtycon { MonoTyApp $1 [] }
+ | OPAREN gtyconvars CPAREN { case $2 of (tc,tvs) -> MonoTyApp tc (map en_mono (reverse tvs)) }
+ | OPAREN VARID COMMA tyvars CPAREN { MonoTupleTy (map en_mono ($2:$4)) }
+ | OBRACK VARID CBRACK { MonoListTy (en_mono $2) }
+ | OPAREN VARID RARROW VARID CPAREN { MonoFunTy (en_mono $2) (en_mono $4) }
+
+general_inst :: { RdrNameMonoType }
+general_inst : gtycon { MonoTyApp $1 [] }
+ | OPAREN gtyconapp CPAREN { case $2 of (tc,tys) -> MonoTyApp tc tys }
+ | OPAREN type COMMA types CPAREN { MonoTupleTy ($2:$4) }
+ | OBRACK type CBRACK { MonoListTy $2 }
+ | OPAREN btype RARROW type CPAREN { MonoFunTy $2 $4 }
+
+tyvars :: { [FAST_STRING] }
+tyvars : VARID { [$1] }
+ | tyvars COMMA VARID { $1 ++ [$3]
+--------------------------------------------------------------------------
+ }
+
+pragmas_part :: { LocalPragmasMap }
+pragmas_part : PRAGMAS_PART