Big tidy-up of deriving code
[ghc-hetmet.git] / compiler / parser / Parser.y.pp
index 1ad8d5f..889e4ce 100644 (file)
@@ -31,21 +31,50 @@ import SrcLoc               ( Located(..), unLoc, getLoc, noLoc, combineSrcSpans,
                          SrcSpan, combineLocs, srcLocFile, 
                          mkSrcLoc, mkSrcSpan )
 import Module
-import StaticFlags     ( opt_SccProfilingOn )
+import StaticFlags     ( opt_SccProfilingOn, opt_Hpc )
 import Type            ( Kind, mkArrowKind, liftedTypeKind, unliftedTypeKind )
 import BasicTypes      ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
                          Activation(..), defaultInlineSpec )
 import OrdList
+import HaddockParse
+import {-# SOURCE #-} HaddockLex hiding ( Token )
+import HaddockUtils
 
 import FastString
 import Maybes          ( orElse )
 import Outputable
-import GLAEXTS
+
+import Control.Monad    ( when )
+import GHC.Exts
+import Data.Char
+import Control.Monad    ( mplus )
 }
 
 {-
 -----------------------------------------------------------------------------
-Conflicts: 36 shift/reduce (1.25)
+6 December 2006
+
+Conflicts: 32 shift/reduce
+           1 reduce/reduce
+
+The reduce/reduce conflict is weird.  It's between tyconsym and consym, and I
+would think the two should never occur in the same context.
+
+  -=chak
+
+-----------------------------------------------------------------------------
+26 July 2006
+
+Conflicts: 37 shift/reduce
+           1 reduce/reduce
+
+The reduce/reduce conflict is weird.  It's between tyconsym and consym, and I
+would think the two should never occur in the same context.
+
+  -=chak
+
+-----------------------------------------------------------------------------
+Conflicts: 38 shift/reduce (1.25)
 
 10 for abiguity in 'if x then y else z + 1'            [State 178]
        (shift parses as 'if x then y else (z + 1)', as per longest-parse rule)
@@ -91,6 +120,10 @@ Conflicts: 36 shift/reduce (1.25)
        This saves explicitly defining a grammar for the rule lhs that
        doesn't include 'forall'.
 
+1 for ambiguity when the source file starts with "-- | doc". We need another
+  token of lookahead to determine if a top declaration or the 'module' keyword
+  follows. Shift parses as if the 'module' keyword follows.   
+
 -- ---------------------------------------------------------------------------
 -- Adding location info
 
@@ -102,6 +135,7 @@ and LL.  Each of these macros can be thought of as having type
 They each add a SrcSpan to their argument.
 
    L0  adds 'noSrcSpan', used for empty productions
+     -- This doesn't seem to work anymore -=chak
 
    L1   for a production with a single token on the lhs.  Grabs the SrcSpan
        from that token.
@@ -144,6 +178,7 @@ incorrect.
  'data'        { L _ ITdata } 
  'default'     { L _ ITdefault }
  'deriving'    { L _ ITderiving }
+ 'derived'     { L _ ITderived }
  'do'          { L _ ITdo }
  'else'        { L _ ITelse }
  'hiding'      { L _ IThiding }
@@ -164,7 +199,7 @@ incorrect.
  'where'       { L _ ITwhere }
  '_scc_'       { L _ ITscc }         -- ToDo: remove
 
- 'forall'      { L _ ITforall }                        -- GHC extension keywords
+ 'forall'      { L _ ITforall }                -- GHC extension keywords
  'foreign'     { L _ ITforeign }
  'export'      { L _ ITexport }
  'label'       { L _ ITlabel } 
@@ -173,6 +208,8 @@ incorrect.
  'threadsafe'  { L _ ITthreadsafe }
  'unsafe'      { L _ ITunsafe }
  'mdo'         { L _ ITmdo }
+ 'iso'         { L _ ITiso }
+ 'family'      { L _ ITfamily }
  'stdcall'      { L _ ITstdcallconv }
  'ccall'        { L _ ITccallconv }
  'dotnet'       { L _ ITdotnet }
@@ -186,6 +223,7 @@ incorrect.
  '{-# RULES'      { L _ ITrules_prag }
  '{-# CORE'        { L _ ITcore_prag }              -- hdaume: annotated core
  '{-# SCC'        { L _ ITscc_prag }
+ '{-# GENERATED'   { L _ ITgenerated_prag }
  '{-# DEPRECATED'  { L _ ITdeprecated_prag }
  '{-# UNPACK'      { L _ ITunpack_prag }
  '#-}'            { L _ ITclose_prag }
@@ -240,7 +278,6 @@ incorrect.
  QCONSYM       { L _ (ITqconsym  _) }
 
  IPDUPVARID    { L _ (ITdupipvarid   _) }              -- GHC extension
- IPSPLITVARID          { L _ (ITsplitipvarid _) }              -- GHC extension
 
  CHAR          { L _ (ITchar     _) }
  STRING                { L _ (ITstring   _) }
@@ -252,7 +289,13 @@ incorrect.
  PRIMINTEGER   { L _ (ITprimint    _) }
  PRIMFLOAT     { L _ (ITprimfloat  _) }
  PRIMDOUBLE    { L _ (ITprimdouble _) }
-                   
+
+ DOCNEXT       { L _ (ITdocCommentNext _) }
+ DOCPREV       { L _ (ITdocCommentPrev _) }
+ DOCNAMED      { L _ (ITdocCommentNamed _) }
+ DOCSECTION    { L _ (ITdocSection _ _) }
+ DOCOPTIONS    { L _ (ITdocOptions _) }
+
 -- Template Haskell 
 '[|'            { L _ ITopenExpQuote  }       
 '[p|'           { L _ ITopenPatQuote  }      
@@ -293,13 +336,22 @@ identifier :: { Located RdrName }
 -- know what they are doing. :-)
 
 module         :: { Located (HsModule RdrName) }
-       : 'module' modid maybemoddeprec maybeexports 'where' body 
-               {% fileSrcSpan >>= \ loc ->
-                  return (L loc (HsModule (Just $2) $4 (fst $6) (snd $6) $3)) }
+       : optdoc 'module' modid maybemoddeprec maybeexports 'where' body 
+               {% fileSrcSpan >>= \ loc -> case $1 of { (opt, info, doc) -> 
+                  return (L loc (HsModule (Just $3) $5 (fst $7) (snd $7) $4 
+                          opt info doc) )}}
        | missing_module_keyword top close
                {% fileSrcSpan >>= \ loc ->
                   return (L loc (HsModule Nothing Nothing 
-                               (fst $2) (snd $2) Nothing)) }
+                          (fst $2) (snd $2) Nothing Nothing emptyHaddockModInfo 
+                          Nothing)) }
+
+optdoc :: { (Maybe String, HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }                             
+        : moduleheader            { (Nothing, fst $1, snd $1) }
+        | docoptions              { (Just $1, emptyHaddockModInfo, Nothing)} 
+        | docoptions moduleheader { (Just $1, fst $2, snd $2) } 
+        | moduleheader docoptions { (Just $2, fst $1, snd $1) } 
+        | {- empty -}             { (Nothing, emptyHaddockModInfo, Nothing) }  
 
 missing_module_keyword :: { () }
        : {- empty -}                           {% pushCurrentContext }
@@ -324,12 +376,14 @@ cvtopdecls :: { [LHsDecl RdrName] }
 -- Module declaration & imports only
 
 header         :: { Located (HsModule RdrName) }
-       : 'module' modid maybemoddeprec maybeexports 'where' header_body
-               {% fileSrcSpan >>= \ loc ->
-                  return (L loc (HsModule (Just $2) $4 $6 [] $3)) }
+       : optdoc 'module' modid maybemoddeprec maybeexports 'where' header_body
+               {% fileSrcSpan >>= \ loc -> case $1 of { (opt, info, doc) -> 
+                  return (L loc (HsModule (Just $3) $5 $7 [] $4 
+                   opt info doc))}}
        | missing_module_keyword importdecls
                {% fileSrcSpan >>= \ loc ->
-                  return (L loc (HsModule Nothing Nothing $2 [] Nothing)) }
+                  return (L loc (HsModule Nothing Nothing $2 [] Nothing 
+                   Nothing emptyHaddockModInfo Nothing)) }
 
 header_body :: { [LImportDecl RdrName] }
        :  '{'            importdecls           { $2 }
@@ -342,15 +396,24 @@ maybeexports :: { Maybe [LIE RdrName] }
        :  '(' exportlist ')'                   { Just $2 }
        |  {- empty -}                          { Nothing }
 
-exportlist  :: { [LIE RdrName] }
-       : ','                                   { [] }
+exportlist :: { [LIE RdrName] }
+       : expdoclist ',' expdoclist             { $1 ++ $3 }
        | exportlist1                           { $1 }
 
 exportlist1 :: { [LIE RdrName] }
-       :  export                               { [$1] }
-       |  export ',' exportlist                { $1 : $3 }
-       |  {- empty -}                          { [] }
-
+        : expdoclist export expdoclist ',' exportlist  { $1 ++ ($2 : $3) ++ $5 }
+       | expdoclist export expdoclist                 { $1 ++ ($2 : $3) }
+       | expdoclist                                   { $1 }
+
+expdoclist :: { [LIE RdrName] }
+        : exp_doc expdoclist                           { $1 : $2 }
+        | {- empty -}                                  { [] }
+
+exp_doc :: { LIE RdrName }                                                   
+        : docsection    { L1 (case (unLoc $1) of (n, doc) -> IEGroup n doc) }
+        | docnamed      { L1 (IEDocNamed ((fst . unLoc) $1)) } 
+        | docnext       { L1 (IEDoc (unLoc $1)) }       
+                       
    -- No longer allow things like [] and (,,,) to be exported
    -- They are built in syntax, always available
 export         :: { LIE RdrName }
@@ -362,12 +425,20 @@ export    :: { LIE RdrName }
        |  'module' modid               { LL (IEModuleContents (unLoc $2)) }
 
 qcnames :: { [RdrName] }
-       :  qcnames ',' qcname                   { unLoc $3 : $1 }
-       |  qcname                               { [unLoc $1]  }
+       :  qcnames ',' qcname_ext       { unLoc $3 : $1 }
+       |  qcname_ext                   { [unLoc $1]  }
 
+qcname_ext :: { Located RdrName }      -- Variable or data constructor
+                                       -- or tagged type constructor
+       :  qcname                       { $1 }
+       |  'type' qcon                  { sL (comb2 $1 $2) 
+                                            (setRdrNameSpace (unLoc $2) 
+                                                             tcClsName)  }
+
+-- Cannot pull into qcname_ext, as qcname is also used in expression.
 qcname         :: { Located RdrName }  -- Variable or data constructor
-       :  qvar                                 { $1 }
-       |  qcon                                 { $1 }
+       :  qvar                         { $1 }
+       |  qcon                         { $1 }
 
 -----------------------------------------------------------------------------
 -- Import Declarations
@@ -425,15 +496,18 @@ ops       :: { Located [Located RdrName] }
 -- Top-Level Declarations
 
 topdecls :: { OrdList (LHsDecl RdrName) }
-       : topdecls ';' topdecl          { $1 `appOL` $3 }
-       | topdecls ';'                  { $1 }
-       | topdecl                       { $1 }
+        : topdecls ';' topdecl                 { $1 `appOL` $3 }
+        | topdecls ';'                         { $1 }
+       | topdecl                               { $1 }
 
 topdecl :: { OrdList (LHsDecl RdrName) }
-       : tycl_decl                     { unitOL (L1 (TyClD (unLoc $1))) }
-       | 'instance' inst_type where
-               { let (binds,sigs) = cvBindsAndSigs (unLoc $3)
-                 in unitOL (L (comb3 $1 $2 $3) (InstD (InstDecl $2 binds sigs))) }
+       : cl_decl                       { unitOL (L1 (TyClD (unLoc $1))) }
+       | ty_decl                       { unitOL (L1 (TyClD (unLoc $1))) }
+       | 'instance' inst_type where_inst
+           { let (binds, sigs, ats, _) = cvBindsAndSigs (unLoc $3)
+             in 
+             unitOL (L (comb3 $1 $2 $3) (InstD (InstDecl $2 binds sigs ats)))}
+        | stand_alone_deriving                  { unitOL (LL (DerivD (unLoc $1))) }
        | 'default' '(' comma_types0 ')'        { unitOL (LL $ DefD (DefaultDecl $3)) }
        | 'foreign' fdecl                       { unitOL (LL (unLoc $2)) }
        | '{-# DEPRECATED' deprecations '#-}'   { $2 }
@@ -446,79 +520,304 @@ topdecl :: { OrdList (LHsDecl RdrName) }
                                                        L1 $ HsVar (mkUnqual varName (getTH_ID_SPLICE $1))
                                                  )) }
 
-tycl_decl :: { LTyClDecl RdrName }
-       : 'type' type '=' ctype 
-               -- Note type on the left of the '='; this allows
-               -- infix type constructors to be declared
-               -- 
-               -- Note ctype, not sigtype, on the right
+-- Type classes
+--
+cl_decl :: { LTyClDecl RdrName }
+       : 'class' tycl_hdr fds where_cls
+               {% do { let { (binds, sigs, ats, docs)           = 
+                               cvBindsAndSigs (unLoc $4)
+                           ; (ctxt, tc, tvs, tparms) = unLoc $2}
+                      ; checkTyVars tparms      -- only type vars allowed
+                     ; checkKindSigs ats
+                     ; return $ L (comb4 $1 $2 $3 $4) 
+                                  (mkClassDecl (ctxt, tc, tvs) 
+                                               (unLoc $3) sigs binds ats docs) } }
+
+-- Type declarations (toplevel)
+--
+ty_decl :: { LTyClDecl RdrName }
+           -- ordinary type synonyms
+        : 'type' type '=' ctype
+               -- Note ctype, not sigtype, on the right of '='
                -- 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
-               {% do { (tc,tvs) <- checkSynHdr $2
-                     ; return (LL (TySynonym tc tvs $4)) } }
-
+               --
+               -- Note the use of type for the head; this allows
+               -- infix type constructors to be declared 
+               {% do { (tc, tvs, _) <- checkSynHdr $2 False
+                     ; return (L (comb2 $1 $4) 
+                                 (TySynonym tc tvs Nothing $4)) 
+                      } }
+
+           -- type family declarations
+        | 'type' 'family' type opt_kind_sig 
+               -- Note the use of type for the head; this allows
+               -- infix type constructors to be declared
+               --
+               {% do { (tc, tvs, _) <- checkSynHdr $3 False
+                     ; let kind = case unLoc $4 of
+                                    Nothing -> liftedTypeKind
+                                    Just ki -> ki
+                     ; return (L (comb3 $1 $3 $4) 
+                                 (TyFunction tc tvs False kind))
+                     } }
+
+           -- type instance declarations
+        | 'type' 'instance' type '=' ctype
+               -- Note the use of type for the head; this allows
+               -- infix type constructors and type patterns
+               --
+               {% do { (tc, tvs, typats) <- checkSynHdr $3 True
+                     ; return (L (comb2 $1 $5) 
+                                 (TySynonym tc tvs (Just typats) $5)) 
+                      } }
+
+          -- ordinary data type or newtype declaration
        | data_or_newtype tycl_hdr constrs deriving
-               { L (comb4 $1 $2 $3 $4) -- We need the location on tycl_hdr 
-                                       -- in case constrs and deriving are both empty
-                   (mkTyData (unLoc $1) (unLoc $2) Nothing (reverse (unLoc $3)) (unLoc $4)) }
-
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
+                      ; checkTyVars tparms    -- no type pattern
+                     ; return $
+                         L (comb4 $1 $2 $3 $4)
+                                  -- We need the location on tycl_hdr in case 
+                                  -- constrs and deriving are both empty
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) 
+                              Nothing (reverse (unLoc $3)) (unLoc $4)) } }
+
+          -- ordinary GADT declaration
         | data_or_newtype tycl_hdr opt_kind_sig 
                 'where' gadt_constrlist
                 deriving
-               { L (comb4 $1 $2 $4 $5)
-                   (mkTyData (unLoc $1) (unLoc $2) $3 (reverse (unLoc $5)) (unLoc $6)) }
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
+                      ; checkTyVars tparms    -- can have type pats
+                     ; return $
+                         L (comb4 $1 $2 $4 $5)
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) 
+                             (unLoc $3) (reverse (unLoc $5)) (unLoc $6)) } }
+
+          -- data/newtype family
+        | data_or_newtype 'family' tycl_hdr opt_kind_sig
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $3}
+                      ; checkTyVars tparms    -- no type pattern
+                     ; let kind = case unLoc $4 of
+                                    Nothing -> liftedTypeKind
+                                    Just ki -> ki
+                     ; return $
+                         L (comb3 $1 $2 $4)
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) 
+                             (Just kind) [] Nothing) } }
+
+          -- data/newtype instance declaration
+       | data_or_newtype 'instance' tycl_hdr constrs deriving
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $3}
+                                             -- can have type pats
+                     ; return $
+                         L (comb4 $1 $3 $4 $5)
+                                  -- We need the location on tycl_hdr in case 
+                                  -- constrs and deriving are both empty
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Just tparms) 
+                             Nothing (reverse (unLoc $4)) (unLoc $5)) } }
+
+          -- GADT instance declaration
+        | data_or_newtype 'instance' tycl_hdr opt_kind_sig 
+                'where' gadt_constrlist
+                deriving
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $3}
+                                             -- can have type pats
+                     ; return $
+                         L (comb4 $1 $3 $6 $7)
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Just tparms) 
+                              (unLoc $4) (reverse (unLoc $6)) (unLoc $7)) } }
+
+-- Associate type family declarations
+--
+-- * They have a different syntax than on the toplevel (no family special
+--   identifier).
+--
+-- * They also need to be separate from instances; otherwise, data family
+--   declarations without a kind signature cause parsing conflicts with empty
+--   data declarations. 
+--
+at_decl_cls :: { LTyClDecl RdrName }
+           -- type family declarations
+        : 'type' type opt_kind_sig
+               -- Note the use of type for the head; this allows
+               -- infix type constructors to be declared
+               --
+               {% do { (tc, tvs, _) <- checkSynHdr $2 False
+                     ; let kind = case unLoc $3 of
+                                    Nothing -> liftedTypeKind
+                                    Just ki -> ki
+                     ; return (L (comb3 $1 $2 $3) 
+                                 (TyFunction tc tvs False kind))
+                     } }
+
+           -- default type instance
+        | 'type' type '=' ctype
+               -- Note the use of type for the head; this allows
+               -- infix type constructors and type patterns
+               --
+               {% do { (tc, tvs, typats) <- checkSynHdr $2 True
+                     ; return (L (comb2 $1 $4) 
+                                 (TySynonym tc tvs (Just typats) $4)) 
+                      } }
+
+          -- data/newtype family declaration
+        | data_or_newtype tycl_hdr opt_kind_sig
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
+                      ; checkTyVars tparms    -- no type pattern
+                     ; let kind = case unLoc $3 of
+                                    Nothing -> liftedTypeKind
+                                    Just ki -> ki
+                     ; return $
+                         L (comb3 $1 $2 $3)
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) 
+                             (Just kind) [] Nothing) } }
+
+-- Associate type instances
+--
+at_decl_inst :: { LTyClDecl RdrName }
+           -- type instance declarations
+        : 'type' type '=' ctype
+               -- Note the use of type for the head; this allows
+               -- infix type constructors and type patterns
+               --
+               {% do { (tc, tvs, typats) <- checkSynHdr $2 True
+                     ; return (L (comb2 $1 $4) 
+                                 (TySynonym tc tvs (Just typats) $4)) 
+                      } }
+
+        -- data/newtype instance declaration
+       | data_or_newtype tycl_hdr constrs deriving
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
+                                             -- can have type pats
+                     ; return $
+                         L (comb4 $1 $2 $3 $4)
+                                  -- We need the location on tycl_hdr in case 
+                                  -- constrs and deriving are both empty
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Just tparms) 
+                             Nothing (reverse (unLoc $3)) (unLoc $4)) } }
+
+        -- GADT instance declaration
+        | data_or_newtype tycl_hdr opt_kind_sig 
+                'where' gadt_constrlist
+                deriving
+               {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
+                                             -- can have type pats
+                     ; return $
+                         L (comb4 $1 $2 $5 $6)
+                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Just tparms) 
+                            (unLoc $3) (reverse (unLoc $5)) (unLoc $6)) } }
 
-       | 'class' tycl_hdr fds where
-               { let 
-                       (binds,sigs) = cvBindsAndSigs (unLoc $4)
-                 in
-                 L (comb4 $1 $2 $3 $4) (mkClassDecl (unLoc $2) (unLoc $3) sigs 
-                                         binds) }
+opt_iso :: { Bool }
+       :       { False }
+       | 'iso' { True  }
 
 data_or_newtype :: { Located NewOrData }
        : 'data'        { L1 DataType }
        | 'newtype'     { L1 NewType }
 
-opt_kind_sig :: { Maybe Kind }
-       :                               { Nothing }
-       | '::' kind                     { Just $2 }
+opt_kind_sig :: { Located (Maybe Kind) }
+       :                               { noLoc Nothing }
+       | '::' kind                     { LL (Just (unLoc $2)) }
 
--- tycl_hdr parses the header of a type or class decl,
+-- tycl_hdr parses the header of a class or data type decl,
 -- which takes the form
 --     T a b
 --     Eq a => T a
 --     (Eq a, Ord b) => T a b
+--      T Int [a]                      -- for associated types
 -- Rather a lot of inlining here, else we get reduce/reduce errors
-tycl_hdr :: { Located (LHsContext RdrName, Located RdrName, [LHsTyVarBndr RdrName]) }
+tycl_hdr :: { Located (LHsContext RdrName, 
+                      Located RdrName, 
+                      [LHsTyVarBndr RdrName],
+                      [LHsType RdrName]) }
        : context '=>' type             {% checkTyClHdr $1         $3 >>= return.LL }
        | type                          {% checkTyClHdr (noLoc []) $1 >>= return.L1 }
 
 -----------------------------------------------------------------------------
+-- Stand-alone deriving
+
+-- Glasgow extension: stand-alone deriving declarations
+stand_alone_deriving :: { LDerivDecl RdrName }
+       : 'derived' 'instance' inst_type {% checkDerivDecl (LL (DerivDecl $3)) }
+
+-----------------------------------------------------------------------------
 -- Nested declarations
 
+-- Declaration in class bodies
+--
+decl_cls  :: { Located (OrdList (LHsDecl RdrName)) }
+decl_cls  : at_decl_cls                        { LL (unitOL (L1 (TyClD (unLoc $1)))) }
+         | decl                        { $1 }
+
+decls_cls :: { Located (OrdList (LHsDecl RdrName)) }   -- Reversed
+         : decls_cls ';' decl_cls      { LL (unLoc $1 `appOL` unLoc $3) }
+         | decls_cls ';'               { LL (unLoc $1) }
+         | decl_cls                    { $1 }
+         | {- empty -}                 { noLoc nilOL }
+
+
+decllist_cls
+        :: { Located (OrdList (LHsDecl RdrName)) }     -- Reversed
+       : '{'         decls_cls '}'     { LL (unLoc $2) }
+       |     vocurly decls_cls close   { $2 }
+
+-- Class body
+--
+where_cls :: { Located (OrdList (LHsDecl RdrName)) }   -- Reversed
+                               -- No implicit parameters
+                               -- May have type declarations
+       : 'where' decllist_cls          { LL (unLoc $2) }
+       | {- empty -}                   { noLoc nilOL }
+
+-- Declarations in instance bodies
+--
+decl_inst  :: { Located (OrdList (LHsDecl RdrName)) }
+decl_inst  : at_decl_inst              { LL (unitOL (L1 (TyClD (unLoc $1)))) }
+          | decl                       { $1 }
+
+decls_inst :: { Located (OrdList (LHsDecl RdrName)) }  -- Reversed
+          : decls_inst ';' decl_inst   { LL (unLoc $1 `appOL` unLoc $3) }
+          | decls_inst ';'             { LL (unLoc $1) }
+          | decl_inst                  { $1 }
+          | {- empty -}                { noLoc nilOL }
+
+decllist_inst 
+        :: { Located (OrdList (LHsDecl RdrName)) }     -- Reversed
+       : '{'         decls_inst '}'    { LL (unLoc $2) }
+       |     vocurly decls_inst close  { $2 }
+
+-- Instance body
+--
+where_inst :: { Located (OrdList (LHsDecl RdrName)) }  -- Reversed
+                               -- No implicit parameters
+                               -- May have type declarations
+       : 'where' decllist_inst         { LL (unLoc $2) }
+       | {- empty -}                   { noLoc nilOL }
+
+-- Declarations in binding groups other than classes and instances
+--
 decls  :: { Located (OrdList (LHsDecl RdrName)) }      
        : decls ';' decl                { LL (unLoc $1 `appOL` unLoc $3) }
        | decls ';'                     { LL (unLoc $1) }
        | decl                          { $1 }
        | {- empty -}                   { noLoc nilOL }
 
-
 decllist :: { Located (OrdList (LHsDecl RdrName)) }
        : '{'            decls '}'      { LL (unLoc $2) }
        |     vocurly    decls close    { $2 }
 
-where  :: { Located (OrdList (LHsDecl RdrName)) }
-                               -- No implicit parameters
-       : 'where' decllist              { LL (unLoc $2) }
-       | {- empty -}                   { noLoc nilOL }
-
+-- Binding groups other than those of class and instance declarations
+--
 binds  ::  { Located (HsLocalBinds RdrName) }          -- May have implicit parameters
+                                               -- No type declarations
        : decllist                      { L1 (HsValBinds (cvBindGroup (unLoc $1))) }
        | '{'            dbinds '}'     { LL (HsIPBinds (IPBinds (unLoc $2) emptyLHsBinds)) }
        |     vocurly    dbinds close   { L (getLoc $2) (HsIPBinds (IPBinds (unLoc $2) emptyLHsBinds)) }
 
 wherebinds :: { Located (HsLocalBinds RdrName) }       -- May have implicit parameters
+                                               -- No type declarations
        : 'where' binds                 { LL (unLoc $2) }
        | {- empty -}                   { noLoc emptyLocalBinds }
 
@@ -597,8 +896,8 @@ safety :: { Safety }
        | 'threadsafe'                  { PlaySafe  True }
 
 fspec :: { Located (Located FastString, Located RdrName, LHsType RdrName) }
-       : STRING var '::' sigtype      { LL (L (getLoc $1) (getSTRING $1), $2, $4) }
-       |        var '::' sigtype      { LL (noLoc nilFS, $1, $3) }
+       : STRING var '::' sigtypedoc     { LL (L (getLoc $1) (getSTRING $1), $2, $4) }
+       |        var '::' sigtypedoc     { LL (noLoc 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
@@ -622,6 +921,10 @@ sigtype :: { LHsType RdrName }
        : ctype                         { L1 (mkImplicitHsForAllTy (noLoc []) $1) }
        -- Wrap an Implicit forall if there isn't one there already
 
+sigtypedoc :: { LHsType RdrName }
+       : ctypedoc                      { L1 (mkImplicitHsForAllTy (noLoc []) $1) }
+       -- Wrap an Implicit forall if there isn't one there already
+
 sig_vars :: { Located [Located RdrName] }
         : sig_vars ',' var             { LL ($3 : unLoc $1) }
         | var                          { L1 [$1] }
@@ -629,6 +932,27 @@ sig_vars :: { Located [Located RdrName] }
 -----------------------------------------------------------------------------
 -- Types
 
+infixtype :: { LHsType RdrName }
+       : btype qtyconop gentype         { LL $ HsOpTy $1 $2 $3 }
+        | btype tyvarop  gentype        { LL $ HsOpTy $1 $2 $3 }
+
+infixtypedoc :: { LHsType RdrName }
+        : infixtype                      { $1 }
+       | infixtype docprev              { LL $ HsDocTy $1 $2 }
+
+gentypedoc :: { LHsType RdrName }
+        : btype                          { $1 }
+        | btypedoc                       { $1 }
+        | infixtypedoc                   { $1 }
+        | btype '->' ctypedoc            { LL $ HsFunTy $1 $3 }
+        | btypedoc '->' ctypedoc         { LL $ HsFunTy $1 $3 }
+
+ctypedoc  :: { LHsType RdrName }
+        : 'forall' tv_bndrs '.' ctypedoc { LL $ mkExplicitHsForAllTy $2 (noLoc []) $4 }
+        | context '=>' gentypedoc        { LL $ mkImplicitHsForAllTy   $1 $3 }
+       -- A type of form (context => type) is an *implicit* HsForAllTy
+       | gentypedoc                     { $1 }
+       
 strict_mark :: { Located HsBang }
        : '!'                           { L1 HsStrict }
        | '{-# UNPACK' '#-}' '!'        { LL HsUnbox }
@@ -644,8 +968,13 @@ ctype      :: { LHsType RdrName }
 -- 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 =>
+--
+-- We have the t1 ~ t2 form here and in gentype, to permit an individual
+-- equational constraint without parenthesis.
 context :: { LHsContext RdrName }
-       : btype                         {% checkContext $1 }
+        : btype '~'      btype         {% checkContext
+                                            (LL $ HsPredTy (HsEqualP $1 $3)) }
+       | btype                         {% checkContext $1 }
 
 type :: { LHsType RdrName }
        : ipvar '::' gentype            { LL (HsPredTy (HsIParam (unLoc $1) $3)) }
@@ -655,12 +984,17 @@ gentype :: { LHsType RdrName }
         : btype                         { $1 }
         | btype qtyconop gentype        { LL $ HsOpTy $1 $2 $3 }
         | btype tyvarop  gentype       { LL $ HsOpTy $1 $2 $3 }
-       | btype '->' ctype              { LL $ HsFunTy $1 $3 }
+       | btype '->'     ctype          { LL $ HsFunTy $1 $3 }
+        | btype '~'      btype         { LL $ HsPredTy (HsEqualP $1 $3) }
 
 btype :: { LHsType RdrName }
        : btype atype                   { LL $ HsAppTy $1 $2 }
        | atype                         { $1 }
 
+btypedoc :: { LHsType RdrName }
+       : btype atype docprev           { LL $ HsDocTy (L (comb2 $1 $2) (HsAppTy $1 $2)) $3 }
+        | atype docprev                 { LL $ HsDocTy $1 $2 }
+
 atype :: { LHsType RdrName }
        : gtycon                        { L1 (HsTyVar (unLoc $1)) }
        | tyvar                         { L1 (HsTyVar (unLoc $1)) }
@@ -670,7 +1004,7 @@ atype :: { LHsType RdrName }
        | '[' ctype ']'                 { LL $ HsListTy  $2 }
        | '[:' ctype ':]'               { LL $ HsPArrTy  $2 }
        | '(' ctype ')'                 { LL $ HsParTy   $2 }
-       | '(' ctype '::' kind ')'       { LL $ HsKindSig $2 $4 }
+       | '(' ctype '::' kind ')'       { LL $ HsKindSig $2 (unLoc $4) }
 -- Generics
         | INTEGER                       { L1 (HsNumTy (getINTEGER $1)) }
 
@@ -699,7 +1033,8 @@ tv_bndrs :: { [LHsTyVarBndr RdrName] }
 
 tv_bndr :: { LHsTyVarBndr RdrName }
        : tyvar                         { L1 (UserTyVar (unLoc $1)) }
-       | '(' tyvar '::' kind ')'       { LL (KindedTyVar (unLoc $2) $4) }
+       | '(' tyvar '::' kind ')'       { LL (KindedTyVar (unLoc $2) 
+                                                         (unLoc $4)) }
 
 fds :: { Located [Located ([RdrName], [RdrName])] }
        : {- empty -}                   { noLoc [] }
@@ -720,14 +1055,14 @@ varids0  :: { Located [RdrName] }
 -----------------------------------------------------------------------------
 -- Kinds
 
-kind   :: { Kind }
+kind   :: { Located Kind }
        : akind                 { $1 }
-       | akind '->' kind       { mkArrowKind $1 $3 }
+       | akind '->' kind       { LL (mkArrowKind (unLoc $1) (unLoc $3)) }
 
-akind  :: { Kind }
-       : '*'                   { liftedTypeKind }
-       | '!'                   { unliftedTypeKind }
-       | '(' kind ')'          { $2 }
+akind  :: { Located Kind }
+       : '*'                   { L1 liftedTypeKind }
+       | '!'                   { L1 unliftedTypeKind }
+       | '(' kind ')'          { LL (unLoc $2) }
 
 
 -----------------------------------------------------------------------------
@@ -753,35 +1088,35 @@ gadt_constr :: { LConDecl RdrName }
               { LL (mkGadtDecl $1 $3) } 
         -- Syntax: Maybe merge the record stuff with the single-case above?
         --         (to kill the mostly harmless reduce/reduce error)
-        -- XXX revisit autrijus
+        -- XXX revisit audreyt
        | constr_stuff_record '::' sigtype
                { let (con,details) = unLoc $1 in 
-                 LL (ConDecl con Implicit [] (noLoc []) details (ResTyGADT $3)) }
+                 LL (ConDecl con Implicit [] (noLoc []) details (ResTyGADT $3) Nothing) }
 {-
        | forall context '=>' constr_stuff_record '::' sigtype
                { let (con,details) = unLoc $4 in 
-                 LL (ConDecl con Implicit (unLoc $1) $2 details (ResTyGADT $6)) }
+                 LL (ConDecl con Implicit (unLoc $1) $2 details (ResTyGADT $6) Nothing ) }
        | forall constr_stuff_record '::' sigtype
                { let (con,details) = unLoc $2 in 
-                 LL (ConDecl con Implicit (unLoc $1) (noLoc []) details (ResTyGADT $4)) }
+                 LL (ConDecl con Implicit (unLoc $1) (noLoc []) details (ResTyGADT $4) Nothing) }
 -}
 
 
 constrs :: { Located [LConDecl RdrName] }
         : {- empty; a GHC extension -}  { noLoc [] }
-        | '=' constrs1                  { LL (unLoc $2) }
+        | maybe_docnext '=' constrs1    { L (comb2 $2 $3) (addConDocs (unLoc $3) $1) }
 
 constrs1 :: { Located [LConDecl RdrName] }
-       : constrs1 '|' constr           { LL ($3 : unLoc $1) }
-       | constr                        { L1 [$1] }
+       : constrs1 maybe_docnext '|' maybe_docprev constr { LL (addConDoc $5 $2 : addConDocFirst (unLoc $1) $4) }
+       | constr                                          { L1 [$1] }
 
 constr :: { LConDecl RdrName }
-       : forall context '=>' constr_stuff      
-               { let (con,details) = unLoc $4 in 
-                 LL (ConDecl con Explicit (unLoc $1) $2 details ResTyH98) }
-       | forall constr_stuff
-               { let (con,details) = unLoc $2 in 
-                 LL (ConDecl con Explicit (unLoc $1) (noLoc []) details ResTyH98) }
+       : maybe_docnext forall context '=>' constr_stuff maybe_docprev  
+               { let (con,details) = unLoc $5 in 
+                 L (comb4 $2 $3 $4 $5) (ConDecl con Explicit (unLoc $2) $3 details ResTyH98 ($1 `mplus` $6)) }
+       | maybe_docnext forall constr_stuff maybe_docprev
+               { let (con,details) = unLoc $3 in 
+                 L (comb2 $2 $3) (ConDecl con Explicit (unLoc $2) (noLoc []) details ResTyH98 ($1 `mplus` $4)) }
 
 forall :: { Located [LHsTyVarBndr RdrName] }
        : 'forall' tv_bndrs '.'         { LL $2 }
@@ -804,12 +1139,12 @@ constr_stuff_record :: { Located (Located RdrName, HsConDetails RdrName (LBangTy
        : oqtycon '{' '}'               {% mkRecCon $1 [] >>= return.sL (comb2 $1 $>) }
        | oqtycon '{' fielddecls '}'    {% mkRecCon $1 $3 >>= return.sL (comb2 $1 $>) }
 
-fielddecls :: { [([Located RdrName], LBangType RdrName)] }
-       : fielddecl ',' fielddecls      { unLoc $1 : $3 }
-       | fielddecl                     { [unLoc $1] }
+fielddecls :: { [([Located RdrName], LBangType RdrName, Maybe (LHsDoc RdrName))] }
+       : fielddecl maybe_docnext ',' maybe_docprev fielddecls { addFieldDoc (unLoc $1) $4 : addFieldDocs $5 $2 }
+       | fielddecl                                            { [unLoc $1] }
 
-fielddecl :: { Located ([Located RdrName], LBangType RdrName) }
-       : sig_vars '::' ctype           { LL (reverse (unLoc $1), $3) }
+fielddecl :: { Located ([Located RdrName], LBangType RdrName, Maybe (LHsDoc RdrName)) }
+       : maybe_docnext sig_vars '::' ctype maybe_docprev      { L (comb3 $2 $3 $4) (reverse (unLoc $2), $4, $1 `mplus` $5) }
 
 -- We allow the odd-looking 'inst_type' in a deriving clause, so that
 -- we can do deriving( forall a. C [a] ) in a newtype (GHC extension).
@@ -848,14 +1183,24 @@ deriving :: { Located (Maybe [LHsType RdrName]) }
   We can't tell whether to reduce var to qvar until after we've read the signatures.
 -}
 
+docdecl :: { LHsDecl RdrName }
+        : docdecld { L1 (DocD (unLoc $1)) }
+
+docdecld :: { LDocDecl RdrName }
+        : docnext                               { L1 (DocCommentNext (unLoc $1)) }
+        | docprev                               { L1 (DocCommentPrev (unLoc $1)) }
+        | docnamed                              { L1 (case (unLoc $1) of (n, doc) -> DocCommentNamed n doc) }
+        | docsection                            { L1 (case (unLoc $1) of (n, doc) -> DocGroup n doc) }
+
 decl   :: { Located (OrdList (LHsDecl RdrName)) }
        : sigdecl                       { $1 }
-       | '!' infixexp rhs              {% do { pat <- checkPattern $2;
-                                               return (LL $ unitOL $ LL $ ValD $ 
+       | '!' aexp rhs                  {% do { pat <- checkPattern $2;
+                                               return (LL $ unitOL $ LL $ ValD ( 
                                                        PatBind (LL $ BangPat pat) (unLoc $3)
-                                                               placeHolderType placeHolderNames) } }
+                                                               placeHolderType placeHolderNames)) } }
        | infixexp opt_sig rhs          {% do { r <- checkValDef $1 $2 $3;
                                                return (LL $ unitOL (LL $ ValD r)) } }
+        | docdecl                       { LL $ unitOL $1 }
 
 rhs    :: { Located (GRHSs RdrName) }
        : '=' exp wherebinds    { L (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) }
@@ -869,18 +1214,18 @@ gdrh :: { LGRHS RdrName }
        : '|' quals '=' exp     { sL (comb2 $1 $>) $ GRHS (reverse (unLoc $2)) $4 }
 
 sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
-       : infixexp '::' sigtype
+       : infixexp '::' sigtypedoc
                                {% do s <- checkValSig $1 $3; 
                                      return (LL $ unitOL (LL $ SigD s)) }
                -- See the above notes for why we need infixexp here
-       | var ',' sig_vars '::' sigtype 
+       | var ',' sig_vars '::' sigtypedoc
                                { LL $ toOL [ LL $ SigD (TypeSig n $5) | n <- $1 : unLoc $3 ] }
        | infix prec ops        { LL $ toOL [ LL $ SigD (FixSig (FixitySig n (Fixity $2 (unLoc $1))))
                                             | n <- unLoc $3 ] }
        | '{-# INLINE'   activation qvar '#-}'        
                                { LL $ unitOL (LL $ SigD (InlineSig $3 (mkInlineSpec $2 (getINLINE $1)))) }
        | '{-# SPECIALISE' qvar '::' sigtypes1 '#-}'
-                               { LL $ toOL [ LL $ SigD (SpecSig $2 t defaultInlineSpec)
+                               { LL $ toOL [ LL $ SigD (SpecSig $2 t defaultInlineSpec) 
                                            | t <- $4] }
        | '{-# SPECIALISE_INLINE' activation qvar '::' sigtypes1 '#-}'
                                { LL $ toOL [ LL $ SigD (SpecSig $3 t (mkInlineSpec $2 (getSPEC_INLINE $1)))
@@ -904,11 +1249,10 @@ infixexp :: { LHsExpr RdrName }
        | infixexp qop exp10            { LL (OpApp $1 $2 (panic "fixity") $3) }
 
 exp10 :: { LHsExpr RdrName }
-       : '\\' aexp aexps opt_asig '->' exp     
-                       {% checkPatterns ($2 : reverse $3) >>= \ ps -> 
-                          return (LL $ HsLam (mkMatchGroup [LL $ Match ps $4
-                                           (GRHSs (unguardedRHS $6) emptyLocalBinds
-                                                       )])) }
+       : '\\' apat apats opt_asig '->' exp     
+                       { LL $ HsLam (mkMatchGroup [LL $ Match ($2:$3) $4
+                                                               (unguardedGRHSs $6)
+                                                           ]) }
        | 'let' binds 'in' exp                  { LL $ HsLet (unLoc $2) $4 }
        | 'if' exp 'then' exp 'else' exp        { LL $ HsIf $2 $4 $6 }
        | 'case' exp 'of' altslist              { LL $ HsCase $2 (mkMatchGroup (unLoc $4)) }
@@ -923,6 +1267,9 @@ exp10 :: { LHsExpr RdrName }
         | scc_annot exp                                { LL $ if opt_SccProfilingOn
                                                        then HsSCC (unLoc $1) $2
                                                        else HsPar $2 }
+        | hpc_annot exp                                { LL $ if opt_Hpc
+                                                       then HsTickPragma (unLoc $1) $2
+                                                       else HsPar $2 }
 
        | 'proc' aexp '->' exp  
                        {% checkPattern $2 >>= \ p -> 
@@ -938,18 +1285,25 @@ scc_annot :: { Located FastString }
        : '_scc_' STRING                        { LL $ getSTRING $2 }
        | '{-# SCC' STRING '#-}'                { LL $ getSTRING $2 }
 
+hpc_annot :: { Located (FastString,(Int,Int),(Int,Int)) }
+       : '{-# GENERATED' STRING INTEGER ':' INTEGER '-' INTEGER ':' INTEGER '#-}'
+                                               { LL $ (getSTRING $2
+                                                      ,( fromInteger $ getINTEGER $3
+                                                       , fromInteger $ getINTEGER $5
+                                                       )
+                                                      ,( fromInteger $ getINTEGER $7
+                                                       , fromInteger $ getINTEGER $9
+                                                       )
+                                                      )
+                                                }
+
 fexp   :: { LHsExpr RdrName }
        : fexp aexp                             { LL $ HsApp $1 $2 }
        | aexp                                  { $1 }
 
-aexps  :: { [LHsExpr RdrName] }
-       : aexps aexp                            { $2 : $1 }
-       | {- empty -}                           { [] }
-
 aexp   :: { LHsExpr RdrName }
        : qvar '@' aexp                 { LL $ EAsPat $1 $3 }
        | '~' aexp                      { LL $ ELazyPat $2 }
---     | '!' aexp                      { LL $ EBangPat $2 }
        | aexp1                         { $1 }
 
 aexp1  :: { LHsExpr RdrName }
@@ -1102,8 +1456,7 @@ alts1     :: { Located [LMatch RdrName] }
        | alt                           { L1 [$1] }
 
 alt    :: { LMatch RdrName }
-       : infixexp opt_sig alt_rhs      {%  checkPattern $1 >>= \p ->
-                                           return (LL (Match [p] $2 (unLoc $3))) }
+       : pat opt_sig alt_rhs           { LL (Match [$1] $2 (unLoc $3)) }
 
 alt_rhs :: { Located (GRHSs RdrName) }
        : ralt wherebinds               { LL (GRHSs (unLoc $1) (unLoc $2)) }
@@ -1119,6 +1472,22 @@ gdpats :: { Located [LGRHS RdrName] }
 gdpat  :: { LGRHS RdrName }
        : '|' quals '->' exp            { sL (comb2 $1 $>) $ GRHS (reverse (unLoc $2)) $4 }
 
+-- 'pat' recognises a pattern, including one with a bang at the top
+--     e.g.  "!x" or "!(x,y)" or "C a b" etc
+-- Bangs inside are parsed as infix operator applications, so that
+-- we parse them right when bang-patterns are off
+pat     :: { LPat RdrName }
+pat    : infixexp              {% checkPattern $1 }
+       | '!' aexp              {% checkPattern (LL (SectionR (L1 (HsVar bang_RDR)) $2)) }
+
+apat   :: { LPat RdrName }     
+apat   : aexp                  {% checkPattern $1 }
+       | '!' aexp              {% checkPattern (LL (SectionR (L1 (HsVar bang_RDR)) $2)) }
+
+apats  :: { [LPat RdrName] }
+       : apat apats            { $1 : $2 }
+       | {- empty -}           { [] }
+
 -----------------------------------------------------------------------------
 -- Statement sequences
 
@@ -1148,13 +1517,13 @@ maybe_stmt :: { Maybe (LStmt RdrName) }
 
 stmt  :: { LStmt RdrName }
        : qual                          { $1 }
+-- What is this next production doing?  I have no clue!  SLPJ Dec06
        | infixexp '->' exp             {% checkPattern $3 >>= \p ->
                                           return (LL $ mkBindStmt p $1) }
        | 'rec' stmtlist                { LL $ mkRecStmt (unLoc $2) }
 
 qual  :: { LStmt RdrName }
-       : exp '<-' exp                  {% checkPattern $1 >>= \p ->
-                                          return (LL $ mkBindStmt p $3) }
+       : pat '<-' exp                  { LL $ mkBindStmt $1 $3 }
        | exp                           { L1 $ mkExprStmt $1 }
        | 'let' binds                   { LL $ LetStmt (unLoc $2) }
 
@@ -1185,8 +1554,7 @@ dbind     :: { LIPBind RdrName }
 dbind  : ipvar '=' exp                 { LL (IPBind (unLoc $1) $3) }
 
 ipvar  :: { Located (IPName RdrName) }
-       : IPDUPVARID            { L1 (Dupable (mkUnqual varName (getIPDUPVARID $1))) }
-       | IPSPLITVARID          { L1 (Linear  (mkUnqual varName (getIPSPLITVARID $1))) }
+       : IPDUPVARID            { L1 (IPName (mkUnqual varName (getIPDUPVARID $1))) }
 
 -----------------------------------------------------------------------------
 -- Deprecations
@@ -1338,6 +1706,8 @@ varid_no_unsafe :: { Located RdrName }
        : VARID                 { L1 $! mkUnqual varName (getVARID $1) }
        | special_id            { L1 $! mkUnqual varName (unLoc $1) }
        | 'forall'              { L1 $! mkUnqual varName FSLIT("forall") }
+       | 'iso'                 { L1 $! mkUnqual varName FSLIT("iso") }
+       | 'family'              { L1 $! mkUnqual varName FSLIT("family") }
 
 qvarsym :: { Located RdrName }
        : varsym                { $1 }
@@ -1361,12 +1731,14 @@ varsym_no_minus :: { Located RdrName } -- varsym not including '-'
 
 -- These special_ids are treated as keywords in various places, 
 -- but as ordinary ids elsewhere.   'special_id' collects all these
--- except 'unsafe' and 'forall' whose treatment differs depending on context
+-- except 'unsafe', 'forall', 'family', and 'iso' whose treatment differs
+-- depending on context 
 special_id :: { Located FastString }
 special_id
        : 'as'                  { L1 FSLIT("as") }
        | 'qualified'           { L1 FSLIT("qualified") }
        | 'hiding'              { L1 FSLIT("hiding") }
+       | 'derived'             { L1 FSLIT("derived") }
        | 'export'              { L1 FSLIT("export") }
        | 'label'               { L1 FSLIT("label")  }
        | 'dynamic'             { L1 FSLIT("dynamic") }
@@ -1434,6 +1806,53 @@ commas :: { Int }
        | ','                           { 2 }
 
 -----------------------------------------------------------------------------
+-- Documentation comments
+
+docnext :: { LHsDoc RdrName }
+  : DOCNEXT {% case parseHaddockParagraphs (tokenise (getDOCNEXT $1)) of {
+      Left  err -> parseError (getLoc $1) err;
+      Right doc -> return (L1 doc) } }
+
+docprev :: { LHsDoc RdrName }
+  : DOCPREV {% case parseHaddockParagraphs (tokenise (getDOCPREV $1)) of {
+      Left  err -> parseError (getLoc $1) err;
+      Right doc -> return (L1 doc) } }
+
+docnamed :: { Located (String, (HsDoc RdrName)) }
+  : DOCNAMED {%
+      let string = getDOCNAMED $1 
+          (name, rest) = break isSpace string
+      in case parseHaddockParagraphs (tokenise rest) of {
+        Left  err -> parseError (getLoc $1) err;
+        Right doc -> return (L1 (name, doc)) } }
+
+docsection :: { Located (n, HsDoc RdrName) }
+  : DOCSECTION {% let (n, doc) = getDOCSECTION $1 in
+        case parseHaddockString (tokenise doc) of {
+      Left  err -> parseError (getLoc $1) err;
+      Right doc -> return (L1 (n, doc)) } }
+
+docoptions :: { String }
+  : DOCOPTIONS { getDOCOPTIONS $1 }
+
+moduleheader :: { (HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }                                    
+        : DOCNEXT {% let string = getDOCNEXT $1 in
+               case parseModuleHeader string of {                       
+                 Right (str, info) ->                                  
+                   case parseHaddockParagraphs (tokenise str) of {               
+                     Left err -> parseError (getLoc $1) err;                    
+                     Right doc -> return (info, Just doc);          
+                   };                                             
+                 Left err -> parseError (getLoc $1) err
+            }  }                                                  
+
+maybe_docprev :: { Maybe (LHsDoc RdrName) }
+       : docprev                       { Just $1 }
+       | {- empty -}                   { Nothing }
+
+maybe_docnext :: { Maybe (LHsDoc RdrName) }
+       : docnext                       { Just $1 }
+       | {- empty -}                   { Nothing }
 
 {
 happyError :: P a
@@ -1448,7 +1867,6 @@ getQCONID         (L _ (ITqconid   x)) = x
 getQVARSYM     (L _ (ITqvarsym  x)) = x
 getQCONSYM     (L _ (ITqconsym  x)) = x
 getIPDUPVARID   (L _ (ITdupipvarid   x)) = x
-getIPSPLITVARID (L _ (ITsplitipvarid x)) = x
 getCHAR                (L _ (ITchar     x)) = x
 getSTRING      (L _ (ITstring   x)) = x
 getINTEGER     (L _ (ITinteger  x)) = x
@@ -1462,6 +1880,12 @@ getTH_ID_SPLICE (L _ (ITidEscape x)) = x
 getINLINE      (L _ (ITinline_prag b)) = b
 getSPEC_INLINE (L _ (ITspec_inline_prag b)) = b
 
+getDOCNEXT (L _ (ITdocCommentNext x)) = x
+getDOCPREV (L _ (ITdocCommentPrev x)) = x
+getDOCNAMED (L _ (ITdocCommentNamed x)) = x
+getDOCSECTION (L _ (ITdocSection n x)) = (n, x)
+getDOCOPTIONS (L _ (ITdocOptions x)) = x
+
 -- Utilities for combining source spans
 comb2 :: Located a -> Located b -> SrcSpan
 comb2 = combineLocs