[project @ 2002-06-07 07:16:04 by chak]
[ghc-hetmet.git] / ghc / compiler / parser / Parser.y
index e57973e..ea8f6f5 100644 (file)
@@ -1,6 +1,6 @@
-{-
+{-                                                             -*-haskell-*-
 -----------------------------------------------------------------------------
-$Id: Parser.y,v 1.75 2001/10/22 09:37:24 simonpj Exp $
+$Id: Parser.y,v 1.100 2002/06/07 07:16:05 chak Exp $
 
 Haskell grammar.
 
@@ -9,26 +9,29 @@ Author(s): Simon Marlow, Sven Panne 1997, 1998, 1999
 -}
 
 {
-module Parser ( parseModule, parseStmt, parseIdentifier ) where
+module Parser ( parseModule, parseStmt, parseIdentifier, parseIface ) where
 
 import HsSyn
 import HsTypes         ( mkHsTupCon )
 
 import RdrHsSyn
+import RnMonad         ( ParsedIface(..) )
 import Lex
 import ParseUtil
 import RdrName
-import PrelNames       ( mAIN_Name, unitTyCon_RDR, funTyCon_RDR, listTyCon_RDR,
-                         tupleTyCon_RDR, unitCon_RDR, nilCon_RDR, tupleCon_RDR
-                       )
-import ForeignCall     ( Safety(..), CExportSpec(..), CCallSpec(..), 
+import PrelNames       ( mAIN_Name, unitTyCon_RDR, funTyCon_RDR, 
+                         listTyCon_RDR, parrTyCon_RDR, tupleTyCon_RDR, 
+                         unitCon_RDR, nilCon_RDR, tupleCon_RDR )
+import ForeignCall     ( Safety(..), CExportSpec(..), 
                          CCallConv(..), CCallTarget(..), defaultCCallConv,
-                         DNCallSpec(..) )
+                       )
 import OccName         ( UserFS, varName, tcName, dataName, tcClsName, tvName )
+import TyCon           ( DataConDetails(..) )
 import SrcLoc          ( SrcLoc )
 import Module
-import CmdLineOpts     ( opt_SccProfilingOn )
-import BasicTypes      ( Boxity(..), Fixity(..), FixityDirection(..), 
+import CmdLineOpts     ( opt_SccProfilingOn, opt_InPackage )
+import Type            ( Kind, mkArrowKind, liftedTypeKind )
+import BasicTypes      ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
                          NewOrData(..), StrictnessMark(..), Activation(..) )
 import Panic
 
@@ -43,18 +46,18 @@ import Outputable
 
 {-
 -----------------------------------------------------------------------------
-Conflicts: 14 shift/reduce
-       (note: it's currently 21 -- JRL, 31/1/2000)
+Conflicts: 21 shift/reduce, -=chak[4Feb2]
 
-8 for abiguity in 'if x then y else z + 1'
+11 for abiguity in 'if x then y else z + 1'            [State 128]
        (shift parses as 'if x then y else (z + 1)', as per longest-parse rule)
-1 for ambiguity in 'if x then y else z :: T'
-       (shift parses as 'if x then y else (z :: T)', as per longest-parse rule)
-3 for ambiguity in 'case x of y :: a -> b'
-       (don't know whether to reduce 'a' as a btype or shift the '->'.
-        conclusion:  bogus expression anyway, doesn't matter)
+       8 because op might be: - ! * . `x` VARSYM CONSYM QVARSYM QCONSYM
+
+1 for ambiguity in '{-# RULES "name" [ ... #-}         [State 210]
+       we don't know whether the '[' starts the activation or not: it
+       might be the start of the declaration with the activation being
+       empty.  --SDM 1/4/2002
 
-1 for ambiguity in '{-# RULES "name" forall = ... #-}' 
+1 for ambiguity in '{-# RULES "name" forall = ... #-}'         [State 412]
        since 'forall' is a valid variable name, we don't know whether
        to treat a forall on the input as the beginning of a quantifier
        or the beginning of the rule itself.  Resolving to shift means
@@ -62,9 +65,28 @@ Conflicts: 14 shift/reduce
        This saves explicitly defining a grammar for the rule lhs that
        doesn't include 'forall'.
 
-1 for ambiguity in 'x @ Rec{..}'.  
-       Only sensible parse is 'x @ (Rec{..})', which is what resolving
-       to shift gives us.
+1 for ambiguity in 'let ?x ...'                                [State 278]
+       the parser can't tell whether the ?x is the lhs of a normal binding or
+       an implicit binding.  Fortunately resolving as shift gives it the only
+       sensible meaning, namely the lhs of an implicit binding.
+
+
+8 for ambiguity in 'e :: a `b` c'.  Does this mean     [States 238,267]
+       (e::a) `b` c, or 
+       (e :: (a `b` c))
+
+6 for conflicts between `fdecl' and `fdeclDEPRECATED',         [States 402,403]
+  which are resolved correctly, and moreover, 
+  should go away when `fdeclDEPRECATED' is removed.
+
+1 for ambiguity in 'if x then y else z :: T'
+       (shift parses as 'if x then y else (z :: T)', as per longest-parse rule)
+1 for ambiguity in 'if x then y else z with ?x=3'
+       (shift parses as 'if x then y else (z with ?x=3)'
+3 for ambiguity in 'case x of y :: a -> b'
+       (don't know whether to reduce 'a' as a btype or shift the '->'.
+        conclusion:  bogus expression anyway, doesn't matter)
+
 
 -----------------------------------------------------------------------------
 -}
@@ -102,15 +124,17 @@ Conflicts: 14 shift/reduce
  'export'      { ITexport }
  'label'       { ITlabel } 
  'dynamic'     { ITdynamic }
+ 'safe'                { ITsafe }
+ 'threadsafe'  { ITthreadsafe }
  'unsafe'      { ITunsafe }
  'with'        { ITwith }
  'stdcall'      { ITstdcallconv }
  'ccall'        { ITccallconv }
  'dotnet'       { ITdotnet }
  '_ccall_'     { ITccall (False, False, PlayRisky) }
- '_ccall_GC_'  { ITccall (False, False, PlaySafe)  }
+ '_ccall_GC_'  { ITccall (False, False, PlaySafe False) }
  '_casm_'      { ITccall (False, True,  PlayRisky) }
- '_casm_GC_'   { ITccall (False, True,  PlaySafe)  }
+ '_casm_GC_'   { ITccall (False, True,  PlaySafe False) }
 
  '{-# SPECIALISE'  { ITspecialise_prag }
  '{-# SOURCE'     { ITsource_prag }
@@ -163,6 +187,7 @@ Conflicts: 14 shift/reduce
  '=>'          { ITdarrow }
  '-'           { ITminus }
  '!'           { ITbang }
+ '*'           { ITstar }
  '.'           { ITdot }
 
  '{'           { ITocurly }                    -- special symbols
@@ -172,6 +197,8 @@ Conflicts: 14 shift/reduce
  vccurly       { ITvccurly } -- virtual close curly (from layout)
  '['           { ITobrack }
  ']'           { ITcbrack }
+ '[:'          { ITopabrack }
+ ':]'          { ITcpabrack }
  '('           { IToparen }
  ')'           { ITcparen }
  '(#'          { IToubxparen }
@@ -189,7 +216,8 @@ Conflicts: 14 shift/reduce
  QVARSYM       { ITqvarsym  $$ }
  QCONSYM       { ITqconsym  $$ }
 
- IPVARID       { ITipvarid  $$ }               -- GHC extension
+ IPDUPVARID    { ITdupipvarid   $$ }           -- GHC extension
+ IPSPLITVARID          { ITsplitipvarid $$ }           -- GHC extension
 
  CHAR          { ITchar     $$ }
  STRING                { ITstring   $$ }
@@ -208,6 +236,7 @@ Conflicts: 14 shift/reduce
 %name parseModule module
 %name parseStmt   maybe_stmt
 %name parseIdentifier  identifier
+%name parseIface iface
 %tokentype { Token }
 %%
 
@@ -244,6 +273,56 @@ cvtopdecls :: { [RdrNameHsDecl] }
        : topdecls                              { cvTopDecls (groupBindings $1)}
 
 -----------------------------------------------------------------------------
+-- Interfaces (.hi-boot files)
+
+iface   :: { ParsedIface }
+       : 'module' modid 'where' ifacebody
+         {         ParsedIface {
+                       pi_mod     = $2,
+                       pi_pkg     = opt_InPackage,
+                       pi_vers    = 1,                 -- Module version
+                       pi_orphan  = False,
+                       pi_exports = (1,[($2,mkIfaceExports $4)]),
+                       pi_usages  = [],
+                       pi_fixity  = [],
+                       pi_insts   = [],
+                       pi_decls   = map (\x -> (1,x)) $4,
+                       pi_rules   = (1,[]),
+                       pi_deprecs = Nothing
+                   }
+          }
+
+ifacebody :: { [RdrNameTyClDecl] }
+       :  '{'            ifacedecls '}'                { $2 }
+       |      layout_on  ifacedecls close              { $2 }
+
+ifacedecls :: { [RdrNameTyClDecl] }
+       : ifacedecl ';' ifacedecls                      { $1 : $3 }
+       | ';' ifacedecls                                { $2 }
+       | ifacedecl                                     { [$1] }
+       | {- empty -}                                   { [] }
+
+ifacedecl :: { RdrNameTyClDecl }
+       : srcloc 'data' tycl_hdr constrs 
+         { mkTyData DataType $3 (DataCons (reverse $4)) Nothing $1 }
+
+       | srcloc 'newtype' tycl_hdr '=' newconstr
+         { mkTyData NewType $3 (DataCons [$5]) Nothing $1 }
+
+       | srcloc 'class' tycl_hdr fds where
+               { let 
+                       (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig 
+                                       (groupBindings $5) 
+                  in
+                  mkClassDecl $3 $4 sigs (Just binds) $1 }
+
+       | srcloc 'type' tycon tv_bndrs '=' ctype        
+         { TySynonym $3 $4 $6 $1 }
+
+       | srcloc var '::' sigtype
+         { IfaceSig $2 $4 [] $1 }
+
+-----------------------------------------------------------------------------
 -- The Export List
 
 maybeexports :: { Maybe [RdrNameIE] }
@@ -335,30 +414,29 @@ topdecls :: { [RdrBinding] }
        | topdecl                       { [$1] }
 
 topdecl :: { RdrBinding }
-       : srcloc 'type' simpletype '=' ctype    
+       : srcloc 'type' syn_hdr '=' ctype       
                -- Note ctype, not sigtype.
                -- We allow an explicit for-all but we don't insert one
                -- in   type Foo a = (b,b)
                -- Instead we just say b is out of scope
-               { RdrHsDecl (TyClD (TySynonym (fst $3) (snd $3) $5 $1)) }
+               { let (tc,tvs) = $3
+                 in RdrHsDecl (TyClD (TySynonym tc tvs $5 $1)) }
 
-       | srcloc 'data' ctype constrs deriving
-               {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
-                  returnP (RdrHsDecl (TyClD
-                     (mkTyData DataType cs c ts (reverse $4) (length $4) $5 $1))) }
 
-       | srcloc 'newtype' ctype '=' newconstr deriving
-               {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
-                  returnP (RdrHsDecl (TyClD
-                     (mkTyData NewType cs c ts [$5] 1 $6 $1))) }
+       | srcloc 'data' tycl_hdr constrs deriving
+               {% returnP (RdrHsDecl (TyClD
+                     (mkTyData DataType $3 (DataCons (reverse $4)) $5 $1))) }
 
-       | srcloc 'class' ctype fds where
-               {% checkDataHeader $3 `thenP` \(cs,c,ts) ->
-                  let 
+       | srcloc 'newtype' tycl_hdr '=' newconstr deriving
+               {% returnP (RdrHsDecl (TyClD
+                     (mkTyData NewType $3 (DataCons [$5]) $6 $1))) }
+
+       | srcloc 'class' tycl_hdr fds where
+               {% let 
                        (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig (groupBindings $5) 
                   in
                   returnP (RdrHsDecl (TyClD
-                     (mkClassDecl cs c ts $4 sigs (Just binds) $1))) }
+                     (mkClassDecl $3 $4 sigs (Just binds) $1))) }
 
        | srcloc 'instance' inst_type where
                { let (binds,sigs) 
@@ -366,45 +444,66 @@ topdecl :: { RdrBinding }
                                (groupBindings $4)
                  in RdrHsDecl (InstD (InstDecl $3 binds sigs Nothing $1)) }
 
-       | srcloc 'default' '(' types0 ')'               { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
-       | 'foreign' fordecl                             { RdrHsDecl $2 }
+       | srcloc 'default' '(' comma_types0 ')'         { RdrHsDecl (DefD (DefaultDecl $4 $1)) }
+       | 'foreign' fdecl                               { RdrHsDecl $2 }
        | '{-# DEPRECATED' deprecations '#-}'           { $2 }
        | '{-# RULES' rules '#-}'                       { $2 }
        | decl                                          { $1 }
 
-fordecl :: { RdrNameHsDecl }
-fordecl : srcloc 'label' ext_name varid '::' sigtype
-               { ForD (ForeignImport $4 $6 (LblImport ($3 `orElse` mkExtName $4)) $1) }
-
-
-       ----------- ccall/stdcall decls ------------
-       | srcloc 'import' ccallconv ext_name unsafe_flag varid_no_unsafe '::' sigtype
-               { let
-                   call_spec = CCallSpec (StaticTarget ($4 `orElse` mkExtName $6)) $3 $5
-                 in
-                 ForD (ForeignImport $6 $8 (CImport call_spec) $1)
-               }
+syn_hdr :: { (RdrName, [RdrNameHsTyVar]) }     -- We don't retain the syntax of an infix
+                                               -- type synonym declaration. Oh well.
+       : tycon tv_bndrs                { ($1, $2) }
+       | tv_bndr tyconop tv_bndr       { ($2, [$1,$3]) }
+
+-- tycl_hdr parses the header of a type or class decl,
+-- which takes the form
+--     T a b
+--     Eq a => T a
+--     (Eq a, Ord b) => T a b
+-- Rather a lot of inlining here, else we get reduce/reduce errors
+tycl_hdr :: { (RdrNameContext, RdrName, [RdrNameHsTyVar]) }
+       : context '=>' type             {% checkTyClHdr $3      `thenP` \ (tc,tvs) ->
+                                          returnP ($1, tc, tvs) }
+       | type                          {% checkTyClHdr $1      `thenP` \ (tc,tvs) ->
+                                          returnP ([], tc, tvs) }
 
-       | srcloc 'import' ccallconv 'dynamic' unsafe_flag varid_no_unsafe '::' sigtype
-               { let
-                   call_spec = CCallSpec DynamicTarget $3 $5
-                 in
-                 ForD (ForeignImport $6 $8 (CImport call_spec) $1)
-               }
-
-       | srcloc 'export' ccallconv ext_name varid '::' sigtype
-               { ForD (ForeignExport $5 $7 (CExport (CExportStatic ($4 `orElse` mkExtName $5) $3)) $1) }
-
-       | srcloc 'export' ccallconv 'dynamic' varid '::' sigtype
-               { ForD (ForeignImport $5 $7 (CDynImport $3) $1) } 
-
-
-       ----------- .NET decls ------------
-       | srcloc 'import' 'dotnet' ext_name varid '::' sigtype
-               { ForD (ForeignImport $5 $7 (DNImport (DNCallSpec ($4 `orElse` mkExtName $5))) $1) }
+{-
+       : '(' comma_types1 ')' '=>' gtycon tv_bndrs
+               {% mapP checkPred $2    `thenP` \ cxt ->
+                 returnP (cxt, $5, $6) }
+
+       | '(' ')' '=>' gtycon tv_bndrs
+               { ([], $4, $5) }
+
+          -- qtycon for the class below name would lead to many s/r conflicts
+         --   FIXME: does the renamer pick up all wrong forms and raise an
+         --          error 
+       | gtycon atypes1 '=>' gtycon atypes0    
+               {% checkTyVars $5       `thenP` \ tvs ->
+                  returnP ([HsClassP $1 $2], $4, tvs) }
+
+       | gtycon  atypes0
+               {% checkTyVars $2       `thenP` \ tvs ->
+                  returnP ([], $1, tvs) }
+               -- We have to have qtycon in this production to avoid s/r
+               -- conflicts with the previous one.  The renamer will complain
+               -- if we use a qualified tycon.
+               --
+               -- Using a `gtycon' throughout.  This enables special syntax,
+               -- such as "[]" for tycons as well as tycon ops in
+               -- parentheses.  This is beyond H98, but used repeatedly in
+               -- the Prelude modules.  (So, it would be a good idea to raise
+               -- an error in the renamer if some non-H98 form is used and
+               -- -fglasgow-exts is not given.)  -=chak 
+
+atypes0        :: { [RdrNameHsType] }
+       : atypes1                       { $1 }
+       | {- empty -}                   { [] }
 
-       | srcloc 'import' 'dotnet' 'type' ext_name tycon
-               { TyClD (ForeignType $6 $5 DNType $1) }
+atypes1        :: { [RdrNameHsType] }
+       : atype                         { [$1] }
+       | atype atypes1                 { $1 : $2 }
+-}
 
 decls  :: { [RdrBinding] }
        : decls ';' decl                { $3 : $1 }
@@ -437,6 +536,11 @@ decllist :: { [RdrBinding] }
        : '{'            decls '}'      { $2 }
        |     layout_on  decls close    { $2 }
 
+letbinds :: { RdrNameHsExpr -> RdrNameHsExpr }
+       : decllist              { HsLet (cvBinds cvValSig (groupBindings $1)) }
+       | '{'            dbinds '}'     { \e -> HsWith e $2 False{-not with-} }
+       |     layout_on  dbinds close   { \e -> HsWith e $2 False{-not with-} }
+
 fixdecl :: { RdrBinding }
        : srcloc infix prec ops         { foldr1 RdrAndBindings
                                            [ RdrSig (FixSig (FixitySig n 
@@ -454,15 +558,19 @@ rules     :: { RdrBinding }
 
 rule   :: { RdrBinding }
        : STRING activation rule_forall infixexp '=' srcloc exp
-            { RdrHsDecl (RuleD (HsRule $1 $2 [] $3 $4 $7 $6)) }
+            { RdrHsDecl (RuleD (HsRule $1 $2 $3 $4 $7 $6)) }
 
 activation :: { Activation }           -- Omitted means AlwaysActive
         : {- empty -}                           { AlwaysActive }
-        | '[' INTEGER ']'                       { ActiveAfter (fromInteger $2) }
+        | explicit_activation                   { $1 }
 
 inverse_activation :: { Activation }   -- Omitted means NeverActive
         : {- empty -}                           { NeverActive }
-        | '[' INTEGER ']'                       { ActiveAfter (fromInteger $2) }
+        | explicit_activation                   { $1 }
+
+explicit_activation :: { Activation }  -- In brackets
+        : '[' INTEGER ']'                       { ActiveAfter  (fromInteger $2) }
+        | '[' '~' INTEGER ']'                   { ActiveBefore (fromInteger $3) }
 
 rule_forall :: { [RdrNameRuleBndr] }
        : 'forall' rule_var_list '.'            { $2 }
@@ -491,18 +599,149 @@ deprecation :: { RdrBinding }
                { foldr RdrAndBindings RdrNullBind 
                        [ RdrHsDecl (DeprecD (Deprecation n $3 $1)) | n <- $2 ] }
 
------------------------------------------------------------------------------
--- Foreign import/export
-
-ccallconv :: { CCallConv }
-       : 'stdcall'             { StdCallConv }
-       | 'ccall'               { CCallConv }
-       | {- empty -}           { defaultCCallConv }
-
-unsafe_flag :: { Safety }
-       : 'unsafe'              { PlayRisky }
-       | {- empty -}           { PlaySafe }
 
+-----------------------------------------------------------------------------
+-- Foreign import and export declarations
+
+-- for the time being, the following accepts foreign declarations conforming
+-- to the FFI Addendum, Version 1.0 as well as pre-standard declarations
+--
+-- * a flag indicates whether pre-standard declarations have been used and
+--   triggers a deprecation warning further down the road
+--
+-- NB: The first two rules could be combined into one by replacing `safety1'
+--     with `safety'.  However, the combined rule conflicts with the
+--     DEPRECATED rules.
+--
+fdecl :: { RdrNameHsDecl }
+fdecl : srcloc 'import' callconv safety1 fspec {% mkImport $3 $4       $5 $1 }
+      | srcloc 'import' callconv         fspec {% mkImport $3 (PlaySafe False) $4 $1 }
+      | srcloc 'export'        callconv         fspec  {% mkExport $3          $4 $1 }
+        -- the following syntax is DEPRECATED
+      | srcloc fdecl1DEPRECATED                        { ForD ($2 True $1) }
+      | srcloc fdecl2DEPRECATED                        { $2 $1 }
+
+fdecl1DEPRECATED :: { Bool -> SrcLoc -> ForeignDecl RdrName }
+fdecl1DEPRECATED 
+  ----------- DEPRECATED label decls ------------
+  : 'label' ext_name varid '::' sigtype
+    { ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS 
+                                  (CLabel ($2 `orElse` mkExtName $3))) }
+
+  ----------- DEPRECATED ccall/stdcall decls ------------
+  --
+  -- NB: This business with the case expression below may seem overly
+  --    complicated, but it is necessary to avoid some conflicts.
+
+    -- DEPRECATED variant #1: lack of a calling convention specification
+    --                       (import) 
+  | 'import' {-no callconv-} ext_name safety varid_no_unsafe '::' sigtype
+    { let
+       target = StaticTarget ($2 `orElse` mkExtName $4)
+      in
+      ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS 
+                                  (CFunction target)) }
+
+    -- DEPRECATED variant #2: external name consists of two separate strings
+    --                       (module name and function name) (import)
+  | 'import' callconv STRING STRING safety varid_no_unsafe '::' sigtype
+    {% case $2 of
+         DNCall      -> parseError "Illegal format of .NET foreign import"
+        CCall cconv -> returnP $
+           let
+            imp = CFunction (StaticTarget $4)
+          in
+          ForeignImport $6 $8 (CImport cconv $5 nilFS nilFS imp) }
+
+    -- DEPRECATED variant #3: `unsafe' after entity
+  | 'import' callconv STRING 'unsafe' varid_no_unsafe '::' sigtype
+    {% case $2 of
+         DNCall      -> parseError "Illegal format of .NET foreign import"
+        CCall cconv -> returnP $
+           let
+            imp = CFunction (StaticTarget $3)
+          in
+          ForeignImport $5 $7 (CImport cconv PlayRisky nilFS nilFS imp) }
+
+    -- DEPRECATED variant #4: use of the special identifier `dynamic' without
+    --                       an explicit calling convention (import)
+  | 'import' {-no callconv-} 'dynamic' safety varid_no_unsafe '::' sigtype
+    { ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS 
+                                  (CFunction DynamicTarget)) }
+
+    -- DEPRECATED variant #5: use of the special identifier `dynamic' (import)
+  | 'import' callconv 'dynamic' safety varid_no_unsafe '::' sigtype
+    {% case $2 of
+         DNCall      -> parseError "Illegal format of .NET foreign import"
+        CCall cconv -> returnP $
+          ForeignImport $5 $7 (CImport cconv $4 nilFS nilFS 
+                                       (CFunction DynamicTarget)) }
+
+    -- DEPRECATED variant #6: lack of a calling convention specification
+    --                       (export) 
+  | 'export' {-no callconv-} ext_name varid '::' sigtype
+    { ForeignExport $3 $5 (CExport (CExportStatic ($2 `orElse` mkExtName $3) 
+                                  defaultCCallConv)) }
+
+    -- DEPRECATED variant #7: external name consists of two separate strings
+    --                       (module name and function name) (export)
+  | 'export' callconv STRING STRING varid '::' sigtype
+    {% case $2 of
+         DNCall      -> parseError "Illegal format of .NET foreign import"
+        CCall cconv -> returnP $
+           ForeignExport $5 $7 
+                        (CExport (CExportStatic $4 cconv)) }
+
+    -- DEPRECATED variant #8: use of the special identifier `dynamic' without
+    --                       an explicit calling convention (export)
+  | 'export' {-no callconv-} 'dynamic' varid '::' sigtype
+    { ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS 
+                                  CWrapper) }
+
+    -- DEPRECATED variant #9: use of the special identifier `dynamic' (export)
+  | 'export' callconv 'dynamic' varid '::' sigtype
+    {% case $2 of
+         DNCall      -> parseError "Illegal format of .NET foreign import"
+        CCall cconv -> returnP $
+          ForeignImport $4 $6 (CImport cconv (PlaySafe False) nilFS nilFS CWrapper) }
+
+  ----------- DEPRECATED .NET decls ------------
+  -- NB: removed the .NET call declaration, as it is entirely subsumed
+  --     by the new standard FFI declarations
+
+fdecl2DEPRECATED :: { SrcLoc -> RdrNameHsDecl }
+fdecl2DEPRECATED 
+  : 'import' 'dotnet' 'type' ext_name tycon
+         { \loc -> TyClD (ForeignType $5 $4 DNType loc) }
+    -- left this one unchanged for the moment as type imports are not
+    -- covered currently by the FFI standard -=chak
+
+
+callconv :: { CallConv }
+         : 'stdcall'                   { CCall  StdCallConv }
+         | 'ccall'                     { CCall  CCallConv   }
+         | 'dotnet'                    { DNCall             }
+
+safety :: { Safety }
+       : 'unsafe'                      { PlayRisky }
+       | 'safe'                        { PlaySafe False }
+       | 'threadsafe'                  { PlaySafe True  }
+       | {- empty -}                   { PlaySafe False }
+
+safety1 :: { Safety }
+       : 'unsafe'                      { PlayRisky }
+       | 'safe'                        { PlaySafe  False }
+       | 'threadsafe'                  { PlaySafe  True }
+         -- only needed to avoid conflicts with the DEPRECATED rules
+
+fspec :: { (FastString, RdrName, RdrNameHsType) }
+       : STRING varid '::' sigtype      { ($1      , $2, $4) }
+       |        varid '::' sigtype      { (nilFS, $1, $3) }
+         -- if the entity string is missing, it defaults to the empty string;
+         -- the meaning of an empty entity string depends on the calling
+         -- convention
+
+-- DEPRECATED syntax
 ext_name :: { Maybe CLabelString }
        : STRING                { Just $1 }
        | STRING STRING         { Just $2 }     -- Ignore "module name" for now
@@ -525,7 +764,7 @@ sigtypes :: { [RdrNameHsType] }
        | sigtypes ',' sigtype          { $3 : $1 }
 
 sigtype :: { RdrNameHsType }
-       : ctype                         { (mkHsForAllTy Nothing [] $1) }
+       : ctype                         { mkHsForAllTy Nothing [] $1 }
 
 sig_vars :: { [RdrName] }
         : sig_vars ',' var             { $3 : $1 }
@@ -536,32 +775,40 @@ sig_vars :: { [RdrName] }
 
 -- A ctype is a for-all type
 ctype  :: { RdrNameHsType }
-       : 'forall' tyvars '.' ctype     { mkHsForAllTy (Just $2) [] $4 }
-       | context type                  { mkHsForAllTy Nothing   $1 $2 }
+       : 'forall' tv_bndrs '.' ctype   { mkHsForAllTy (Just $2) [] $4 }
+       | context '=>' type             { mkHsForAllTy Nothing   $1 $3 }
        -- A type of form (context => type) is an *implicit* HsForAllTy
        | type                          { $1 }
 
+-- We parse a context as a btype so that we don't get reduce/reduce
+-- errors in ctype.  The basic problem is that
+--     (Eq a, Ord a)
+-- looks so much like a tuple type.  We can't tell until we find the =>
+context :: { RdrNameContext }
+       : btype                         {% checkContext $1 }
+
 type :: { RdrNameHsType }
-       : gentype '->' type             { HsFunTy $1 $3 }
-       | ipvar '::' type               { mkHsIParamTy $1 $3 }
+       : ipvar '::' gentype            { mkHsIParamTy $1 $3 }
        | gentype                       { $1 }
 
 gentype :: { RdrNameHsType }
         : btype                         { $1 }
--- Generics
-        | atype tyconop atype           { HsOpTy $1 $2 $3 }
+        | btype qtyconop gentype        { HsOpTy $1 (HsTyOp $2) $3 }
+       | btype '->' gentype            { HsOpTy $1 HsArrow $3 }
 
 btype :: { RdrNameHsType }
-       : btype atype                   { (HsAppTy $1 $2) }
+       : btype atype                   { HsAppTy $1 $2 }
        | atype                         { $1 }
 
 atype :: { RdrNameHsType }
        : gtycon                        { HsTyVar $1 }
        | tyvar                         { HsTyVar $1 }
-       | '(' type ',' types ')'        { HsTupleTy (mkHsTupCon tcName Boxed  ($2:$4)) ($2 : reverse $4) }
-       | '(#' types '#)'               { HsTupleTy (mkHsTupCon tcName Unboxed     $2) (reverse $2)      }
-       | '[' type ']'                  { HsListTy $2 }
-       | '(' ctype ')'                 { $2 }
+       | '(' type ',' comma_types1 ')' { HsTupleTy (mkHsTupCon tcName Boxed  ($2:$4)) ($2:$4) }
+       | '(#' comma_types1 '#)'        { HsTupleTy (mkHsTupCon tcName Unboxed     $2) $2      }
+       | '[' type ']'                  { HsListTy  $2 }
+       | '[:' type ':]'                { HsPArrTy  $2 }
+       | '(' ctype ')'                 { HsParTy   $2 }
+       | '(' ctype '::' kind ')'       { HsKindSig $2 $4 }
 -- Generics
         | INTEGER                       { HsNumTy $1 }
 
@@ -572,20 +819,21 @@ atype :: { RdrNameHsType }
 inst_type :: { RdrNameHsType }
        : ctype                         {% checkInstType $1 }
 
-types0  :: { [RdrNameHsType] }
-       : types                         { reverse $1 }
+comma_types0  :: { [RdrNameHsType] }
+       : comma_types1                  { $1 }
        | {- empty -}                   { [] }
 
-types  :: { [RdrNameHsType] }
+comma_types1   :: { [RdrNameHsType] }
        : type                          { [$1] }
-       | types  ',' type               { $3 : $1 }
+       | type  ',' comma_types1        { $1 : $3 }
 
-simpletype :: { (RdrName, [RdrNameHsTyVar]) }
-       : tycon tyvars                  { ($1, reverse $2) }
+tv_bndrs :: { [RdrNameHsTyVar] }
+        : tv_bndr tv_bndrs             { $1 : $2 }
+        | {- empty -}                  { [] }
 
-tyvars :: { [RdrNameHsTyVar] }
-       : tyvars tyvar                  { UserTyVar $2 : $1 }
-       | {- empty -}                   { [] }
+tv_bndr :: { RdrNameHsTyVar }
+       : tyvar                         { UserTyVar $1 }
+       | '(' tyvar '::' kind ')'       { IfaceTyVar $2 $4 }
 
 fds :: { [([RdrName], [RdrName])] }
        : {- empty -}                   { [] }
@@ -603,6 +851,18 @@ varids0    :: { [RdrName] }
        | varids0 tyvar                 { $2 : $1 }
 
 -----------------------------------------------------------------------------
+-- Kinds
+
+kind   :: { Kind }
+       : akind                 { $1 }
+       | akind '->' kind       { mkArrowKind $1 $3 }
+
+akind  :: { Kind }
+       : '*'                   { liftedTypeKind }
+       | '(' kind ')'          { $2 }
+
+
+-----------------------------------------------------------------------------
 -- Datatype declarations
 
 newconstr :: { RdrNameConDecl }
@@ -619,21 +879,19 @@ constrs1 :: { [RdrNameConDecl] }
        | constr                        { [$1] }
 
 constr :: { RdrNameConDecl }
-       : srcloc forall context constr_stuff
-               { mkConDecl (fst $4) $2 $3 (snd $4) $1 }
+       : srcloc forall context '=>' constr_stuff
+               { mkConDecl (fst $5) $2 $3 (snd $5) $1 }
        | srcloc forall constr_stuff
                { mkConDecl (fst $3) $2 [] (snd $3) $1 }
 
 forall :: { [RdrNameHsTyVar] }
-       : 'forall' tyvars '.'           { $2 }
+       : 'forall' tv_bndrs '.'         { $2 }
        | {- empty -}                   { [] }
 
-context :: { RdrNameContext }
-       : btype '=>'                    {% checkContext $1 }
-
 constr_stuff :: { (RdrName, RdrNameConDetails) }
        : btype                         {% mkVanillaCon $1 []               }
        | btype '!' atype satypes       {% mkVanillaCon $1 (BangType MarkedUserStrict $3 : $4) }
+       | gtycon '{' '}'                {% mkRecCon $1 [] }
        | gtycon '{' fielddecls '}'     {% mkRecCon $1 $3 }
        | sbtype conop sbtype           { ($2, InfixCon $1 $3) }
 
@@ -657,15 +915,11 @@ stype :: { RdrNameBangType }
        : ctype                         { unbangedType $1 }
        | '!' atype                     { BangType MarkedUserStrict $2 }
 
-deriving :: { Maybe [RdrName] }
+deriving :: { Maybe RdrNameContext }
        : {- empty -}                   { Nothing }
-       | 'deriving' qtycls             { Just [$2] }
-       | 'deriving' '('          ')'   { Just [] }
-       | 'deriving' '(' dclasses ')'   { Just (reverse $3) }
-
-dclasses :: { [RdrName] }
-       : dclasses ',' qtycls           { $3 : $1 }
-               | qtycls                        { [$1] }
+       | 'deriving' context            { Just $2 }
+             -- Glasgow extension: allow partial 
+             -- applications in derivings
 
 -----------------------------------------------------------------------------
 -- Value definitions
@@ -714,7 +968,7 @@ gdrh :: { RdrNameGRHS }
 
 exp   :: { RdrNameHsExpr }
        : infixexp '::' sigtype         { (ExprWithTySig $1 $3) }
-       | infixexp 'with' dbinding      { HsWith $1 $3 }
+       | infixexp 'with' dbinding      { HsWith $1 $3 True{-not a let-} }
        | infixexp                      { $1 }
 
 infixexp :: { RdrNameHsExpr }
@@ -725,20 +979,20 @@ infixexp :: { RdrNameHsExpr }
 exp10 :: { RdrNameHsExpr }
        : '\\' srcloc aexp aexps opt_asig '->' srcloc exp       
                        {% checkPatterns $2 ($3 : reverse $4) `thenP` \ ps -> 
-                          returnP (HsLam (Match [] ps $5 
+                          returnP (HsLam (Match ps $5 
                                            (GRHSs (unguardedRHS $8 $7) 
                                                   EmptyBinds placeHolderType))) }
-       | 'let' declbinds 'in' exp              { HsLet $2 $4 }
+       | 'let' letbinds 'in' exp               { $2 $4 }
        | 'if' srcloc exp 'then' exp 'else' exp { HsIf $3 $5 $7 $2 }
        | 'case' srcloc exp 'of' altslist       { HsCase $3 $5 $2 }
        | '-' fexp                              { mkHsNegApp $2 }
        | srcloc 'do' stmtlist                  {% checkDo $3  `thenP` \ stmts ->
-                                                  returnP (HsDo DoExpr stmts $1) }
+                                                  returnP (mkHsDo DoExpr stmts $1) }
 
        | '_ccall_'    ccallid aexps0           { HsCCall $2 $3 PlayRisky False placeHolderType }
-       | '_ccall_GC_' ccallid aexps0           { HsCCall $2 $3 PlaySafe  False placeHolderType }
+       | '_ccall_GC_' ccallid aexps0           { HsCCall $2 $3 (PlaySafe False) False placeHolderType }
        | '_casm_'     CLITLIT aexps0           { HsCCall $2 $3 PlayRisky True  placeHolderType }
-       | '_casm_GC_'  CLITLIT aexps0           { HsCCall $2 $3 PlaySafe  True  placeHolderType }
+       | '_casm_GC_'  CLITLIT aexps0           { HsCCall $2 $3 (PlaySafe False) True  placeHolderType }
 
         | scc_annot exp                                { if opt_SccProfilingOn
                                                        then HsSCC $1 $2
@@ -746,11 +1000,11 @@ exp10 :: { RdrNameHsExpr }
 
        | fexp                                  { $1 }
 
-scc_annot :: { FAST_STRING }
+scc_annot :: { FastString }
        : '_scc_' STRING                        { $2 }
        | '{-# SCC' STRING '#-}'                { $2 }
 
-ccallid :: { FAST_STRING }
+ccallid :: { FastString }
        :  VARID                                { $1 }
        |  CONID                                { $1 }
 
@@ -759,23 +1013,29 @@ fexp     :: { RdrNameHsExpr }
        | aexp                                  { $1 }
 
 aexps0         :: { [RdrNameHsExpr] }
-       : aexps                                 { (reverse $1) }
+       : aexps                                 { reverse $1 }
 
 aexps  :: { [RdrNameHsExpr] }
        : aexps aexp                            { $2 : $1 }
        | {- empty -}                           { [] }
 
 aexp   :: { RdrNameHsExpr }
-        : var_or_con '{|' gentype '|}'          { (HsApp $1 (HsType $3)) }
-       | aexp '{' fbinds '}'                   {% (mkRecConstrOrUpdate $1 
+       : qvar '@' aexp                 { EAsPat $1 $3 }
+       | '~' aexp                      { ELazyPat $2 }
+       | aexp1                         { $1 }
+
+aexp1  :: { RdrNameHsExpr }
+        : aexp1 '{' fbinds '}'                         {% (mkRecConstrOrUpdate $1 
                                                        (reverse $3)) }
-       | aexp1                                 { $1 }
+       | aexp2                                 { $1 }
+       | var_or_con '{|' gentype '|}'          { HsApp $1 (HsType $3) }
+
 
 var_or_con :: { RdrNameHsExpr }
         : qvar                          { HsVar $1 }
         | gcon                          { HsVar $1 }
 
-aexp1  :: { RdrNameHsExpr }
+aexp2  :: { RdrNameHsExpr }
        : ipvar                         { HsIPVar $1 }
        | var_or_con                    { $1 }
        | literal                       { HsLit $1 }
@@ -785,11 +1045,10 @@ aexp1    :: { RdrNameHsExpr }
        | '(' exp ',' texps ')'         { ExplicitTuple ($2 : reverse $4) Boxed}
        | '(#' texps '#)'               { ExplicitTuple (reverse $2)      Unboxed }
        | '[' list ']'                  { $2 }
+       | '[:' parr ':]'                { $2 }
        | '(' infixexp qop ')'          { (SectionL $2 (HsVar $3))  }
        | '(' qopm infixexp ')'         { (SectionR $2 $3) }
-       | qvar '@' aexp                 { EAsPat $1 $3 }
        | '_'                           { EWildPat }
-       | '~' aexp1                     { ELazyPat $2 }
 
 texps :: { [RdrNameHsExpr] }
        : texps ',' exp                 { $3 : $1 }
@@ -812,9 +1071,9 @@ list :: { RdrNameHsExpr }
        | exp srcloc pquals             {% let { body [qs] = qs;
                                                 body  qss = [ParStmt (map reverse qss)] }
                                           in
-                                          returnP ( HsDo ListComp
-                                                          (reverse (ResultStmt $1 $2 : body $3))
-                                                          $2
+                                          returnP ( mkHsDo ListComp
+                                                           (reverse (ResultStmt $1 $2 : body $3))
+                                                           $2
                                                  )
                                        }
 
@@ -834,6 +1093,35 @@ quals :: { [RdrNameStmt] }
        | stmt                          { [$1] }
 
 -----------------------------------------------------------------------------
+-- Parallel array expressions
+
+-- The rules below are little bit contorted; see the list case for details.
+-- Note that, in contrast to lists, we only have finite arithmetic sequences.
+-- Moreover, we allow explicit arrays with no element (represented by the nil
+-- constructor in the list case).
+
+parr :: { RdrNameHsExpr }
+       :                               { ExplicitPArr placeHolderType [] }
+       | exp                           { ExplicitPArr placeHolderType [$1] }
+       | lexps                         { ExplicitPArr placeHolderType 
+                                                      (reverse $1) }
+       | exp '..' exp                  { PArrSeqIn (FromTo $1 $3) }
+       | exp ',' exp '..' exp          { PArrSeqIn (FromThenTo $1 $3 $5) }
+       | exp srcloc pquals             {% let {
+                                            body [qs] = qs;
+                                            body  qss = [ParStmt 
+                                                          (map reverse qss)]}
+                                          in
+                                          returnP $ 
+                                            mkHsDo PArrComp 
+                                                   (reverse (ResultStmt $1 $2 
+                                                            : body $3))
+                                                   $2
+                                       }
+
+-- We are reusing `lexps' and `pquals' from the list case.
+
+-----------------------------------------------------------------------------
 -- Case alternatives
 
 altslist :: { [RdrNameMatch] }
@@ -852,12 +1140,12 @@ alts1    :: { [RdrNameMatch] }
 alt    :: { RdrNameMatch }
        : srcloc infixexp opt_sig ralt wherebinds
                                        {% (checkPattern $1 $2 `thenP` \p ->
-                                          returnP (Match [] [p] $3
+                                          returnP (Match [p] $3
                                                     (GRHSs $4 $5 placeHolderType))  )}
 
 ralt :: { [RdrNameGRHS] }
        : '->' srcloc exp               { [GRHS [ResultStmt $3 $2] $2] }
-       | gdpats                        { (reverse $1) }
+       | gdpats                        { reverse $1 }
 
 gdpats :: { [RdrNameGRHS] }
        : gdpats gdpat                  { $2 : $1 }
@@ -914,17 +1202,17 @@ fbind    :: { (RdrName, RdrNameHsExpr, Bool) }
 -----------------------------------------------------------------------------
 -- Implicit Parameter Bindings
 
-dbinding :: { [(RdrName, RdrNameHsExpr)] }
+dbinding :: { [(IPName RdrName, RdrNameHsExpr)] }
        : '{' dbinds '}'                { $2 }
        | layout_on dbinds close        { $2 }
 
-dbinds         :: { [(RdrName, RdrNameHsExpr)] }
+dbinds         :: { [(IPName RdrName, RdrNameHsExpr)] }
        : dbinds ';' dbind              { $3 : $1 }
        | dbinds ';'                    { $1 }
        | dbind                         { [$1] }
-       | {- empty -}                   { [] }
+--     | {- empty -}                   { [] }
 
-dbind  :: { (RdrName, RdrNameHsExpr) }
+dbind  :: { (IPName RdrName, RdrNameHsExpr) }
 dbind  : ipvar '=' exp                 { ($1, $3) }
 
 -----------------------------------------------------------------------------
@@ -949,13 +1237,15 @@ gtycon   :: { RdrName }
        | '(' ')'                       { unitTyCon_RDR }
        | '(' '->' ')'                  { funTyCon_RDR }
        | '[' ']'                       { listTyCon_RDR }
+       | '[:' ':]'                     { parrTyCon_RDR }
        | '(' commas ')'                { tupleTyCon_RDR $2 }
 
-gcon   :: { RdrName }
+gcon   :: { RdrName }  -- Data constructor namespace
        : '(' ')'               { unitCon_RDR }
        | '[' ']'               { nilCon_RDR }
        | '(' commas ')'        { tupleCon_RDR $2 }
        | qcon                  { $1 }
+-- the case of '[:' ':]' is part of the production `parr'
 
 var    :: { RdrName }
        : varid                 { $1 }
@@ -969,8 +1259,9 @@ qvar       :: { RdrName }
 -- whether it's a qvar or a var can be postponed until
 -- *after* we see the close paren.
 
-ipvar  :: { RdrName }
-       : IPVARID               { (mkUnqual varName (tailFS $1)) }
+ipvar  :: { IPName RdrName }
+       : IPDUPVARID            { Dupable (mkUnqual varName $1) }
+       | IPSPLITVARID          { Linear  (mkUnqual varName $1) }
 
 qcon   :: { RdrName }
        : qconid                { $1 }
@@ -997,6 +1288,26 @@ qconop :: { RdrName }
        | '`' qconid '`'        { $2 }
 
 -----------------------------------------------------------------------------
+-- Type constructors
+
+tycon  :: { RdrName }  -- Unqualified
+       : CONID                 { mkUnqual tcClsName $1 }
+
+tyconop        :: { RdrName }  -- Unqualified
+       : CONSYM                { mkUnqual tcClsName $1 }
+       | '`' tyvar '`'         { $2 }
+       | '`' tycon '`'         { $2 }
+
+qtycon :: { RdrName }  -- Qualified or unqualified
+       : QCONID                { mkQual tcClsName $1 }
+       | tycon                 { $1 }
+
+qtyconop :: { RdrName }        -- Qualified or unqualified
+         : QCONSYM             { mkQual tcClsName $1 }
+         | '`' QCONID '`'      { mkQual tcClsName $2 }
+         | tyconop             { $1 }
+
+-----------------------------------------------------------------------------
 -- Any operator
 
 op     :: { RdrName }   -- used in infix decls
@@ -1020,54 +1331,38 @@ qvarid :: { RdrName }
 
 varid :: { RdrName }
        : varid_no_unsafe       { $1 }
-       | 'unsafe'              { mkUnqual varName SLIT("unsafe") }
+       | 'unsafe'              { mkUnqual varName FSLIT("unsafe") }
+       | 'safe'                { mkUnqual varName FSLIT("safe") }
+       | 'threadsafe'          { mkUnqual varName FSLIT("threadsafe") }
 
 varid_no_unsafe :: { RdrName }
        : VARID                 { mkUnqual varName $1 }
        | special_id            { mkUnqual varName $1 }
-       | 'forall'              { mkUnqual varName SLIT("forall") }
+       | 'forall'              { mkUnqual varName FSLIT("forall") }
 
 tyvar  :: { RdrName }
        : VARID                 { mkUnqual tvName $1 }
        | special_id            { mkUnqual tvName $1 }
-       | 'unsafe'              { mkUnqual tvName SLIT("unsafe") }
+       | 'unsafe'              { mkUnqual tvName FSLIT("unsafe") }
+       | 'safe'                { mkUnqual tvName FSLIT("safe") }
+       | 'threadsafe'          { mkUnqual tvName FSLIT("threadsafe") }
 
 -- These special_ids are treated as keywords in various places, 
--- but as ordinary ids elsewhere.   A special_id collects all thsee
+-- but as ordinary ids elsewhere.   'special_id' collects all these
 -- except 'unsafe' and 'forall' whose treatment differs depending on context
 special_id :: { UserFS }
 special_id
-       : 'as'                  { SLIT("as") }
-       | 'qualified'           { SLIT("qualified") }
-       | 'hiding'              { SLIT("hiding") }
-       | 'export'              { SLIT("export") }
-       | 'label'               { SLIT("label")  }
-       | 'dynamic'             { SLIT("dynamic") }
-       | 'stdcall'             { SLIT("stdcall") }
-       | 'ccall'               { SLIT("ccall") }
-
------------------------------------------------------------------------------
--- ConIds
-
-qconid :: { RdrName }
-       : conid                 { $1 }
-       | QCONID                { mkQual dataName $1 }
-
-conid  :: { RdrName }
-       : CONID                 { mkUnqual dataName $1 }
-
------------------------------------------------------------------------------
--- ConSyms
-
-qconsym :: { RdrName }
-       : consym                { $1 }
-       | QCONSYM               { mkQual dataName $1 }
-
-consym :: { RdrName }
-       : CONSYM                { mkUnqual dataName $1 }
+       : 'as'                  { FSLIT("as") }
+       | 'qualified'           { FSLIT("qualified") }
+       | 'hiding'              { FSLIT("hiding") }
+       | 'export'              { FSLIT("export") }
+       | 'label'               { FSLIT("label")  }
+       | 'dynamic'             { FSLIT("dynamic") }
+       | 'stdcall'             { FSLIT("stdcall") }
+       | 'ccall'               { FSLIT("ccall") }
 
 -----------------------------------------------------------------------------
--- VarSyms
+-- Variables 
 
 qvarsym :: { RdrName }
        : varsym                { $1 }
@@ -1082,7 +1377,7 @@ qvarsym1 : QVARSYM                { mkQual varName $1 }
 
 varsym :: { RdrName }
        : varsym_no_minus       { $1 }
-       | '-'                   { mkUnqual varName SLIT("-") }
+       | '-'                   { mkUnqual varName FSLIT("-") }
 
 varsym_no_minus :: { RdrName } -- varsym not including '-'
        : VARSYM                { mkUnqual varName $1 }
@@ -1091,8 +1386,27 @@ varsym_no_minus :: { RdrName } -- varsym not including '-'
 
 -- See comments with special_id
 special_sym :: { UserFS }
-special_sym : '!'      { SLIT("!") }
-           | '.'       { SLIT(".") }
+special_sym : '!'      { FSLIT("!") }
+           | '.'       { FSLIT(".") }
+           | '*'       { FSLIT("*") }
+
+-----------------------------------------------------------------------------
+-- Data constructors
+
+qconid :: { RdrName }  -- Qualified or unqualifiedb
+       : conid                 { $1 }
+       | QCONID                { mkQual dataName $1 }
+
+conid  :: { RdrName }
+       : CONID                 { mkUnqual dataName $1 }
+
+qconsym :: { RdrName } -- Qualified or unqualified
+       : consym                { $1 }
+       | QCONSYM               { mkQual dataName $1 }
+
+consym :: { RdrName }
+       : CONSYM                { mkUnqual dataName $1 }
+
 
 -----------------------------------------------------------------------------
 -- Literals
@@ -1130,23 +1444,6 @@ modid    :: { ModuleName }
                                        '.':unpackFS (snd $1)))
                                }
 
-tycon  :: { RdrName }
-       : CONID                 { mkUnqual tcClsName $1 }
-
-tyconop        :: { RdrName }
-       : CONSYM                { mkUnqual tcClsName $1 }
-
-qtycon :: { RdrName }
-       : tycon                 { $1 }
-       | QCONID                { mkQual tcClsName $1 }
-
-qtyconop :: { RdrName }
-         : tyconop             { $1 }
-         | QCONSYM             { mkQual tcClsName $1 }
-
-qtycls         :: { RdrName }
-       : qtycon                { $1 }
-
 commas :: { Int }
        : commas ','                    { $1 + 1 }
        | ','                           { 2 }