Add several new record features
[ghc-hetmet.git] / compiler / parser / Parser.y.pp
index 7166e1e..82f6474 100644 (file)
@@ -31,7 +31,7 @@ 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 )
@@ -42,16 +42,49 @@ import HaddockUtils
 
 import FastString
 import Maybes          ( orElse )
-import Monad            ( when )
 import Outputable
-import GLAEXTS
 
+import Control.Monad    ( unless )
+import GHC.Exts
 import Data.Char
 import Control.Monad    ( mplus )
 }
 
 {-
 -----------------------------------------------------------------------------
+24 Februar 2006
+
+Conflicts: 33 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
+
+-----------------------------------------------------------------------------
+31 December 2006
+
+Conflicts: 34 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
+
+-----------------------------------------------------------------------------
+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
@@ -167,9 +200,9 @@ incorrect.
  'data'        { L _ ITdata } 
  'default'     { L _ ITdefault }
  'deriving'    { L _ ITderiving }
+ 'derive'      { L _ ITderive }
  'do'          { L _ ITdo }
  'else'        { L _ ITelse }
- 'for'                 { L _ ITfor }
  'hiding'      { L _ IThiding }
  'if'          { L _ ITif }
  'import'      { L _ ITimport }
@@ -197,7 +230,6 @@ incorrect.
  'threadsafe'  { L _ ITthreadsafe }
  'unsafe'      { L _ ITunsafe }
  'mdo'         { L _ ITmdo }
- 'iso'         { L _ ITiso }
  'family'      { L _ ITfamily }
  'stdcall'      { L _ ITstdcallconv }
  'ccall'        { L _ ITccallconv }
@@ -212,6 +244,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 }
@@ -328,10 +361,10 @@ module    :: { Located (HsModule RdrName) }
                {% 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
+        | body2
                {% fileSrcSpan >>= \ loc ->
                   return (L loc (HsModule Nothing Nothing 
-                          (fst $2) (snd $2) Nothing Nothing emptyHaddockModInfo 
+                          (fst $1) (snd $1) Nothing Nothing emptyHaddockModInfo 
                           Nothing)) }
 
 optdoc :: { (Maybe String, HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }                             
@@ -352,6 +385,10 @@ body       :: { ([LImportDecl RdrName], [LHsDecl RdrName]) }
        :  '{'            top '}'               { $2 }
        |      vocurly    top close             { $2 }
 
+body2  :: { ([LImportDecl RdrName], [LHsDecl RdrName]) }
+       :  '{' top '}'                          { $2 }
+       |  missing_module_keyword top close     { $2 }
+
 top    :: { ([LImportDecl RdrName], [LHsDecl RdrName]) }
        : importdecls                           { (reverse $1,[]) }
        | importdecls ';' cvtopdecls            { (reverse $1,$3) }
@@ -491,9 +528,10 @@ topdecls :: { OrdList (LHsDecl RdrName) }
 topdecl :: { OrdList (LHsDecl RdrName) }
        : cl_decl                       { unitOL (L1 (TyClD (unLoc $1))) }
        | ty_decl                       { unitOL (L1 (TyClD (unLoc $1))) }
-         | 'instance' inst_type where
-               { let (binds, sigs, ats, _) = cvBindsAndSigs (unLoc $3)
-                 in unitOL (L (comb3 $1 $2 $3) (InstD (InstDecl $2 binds sigs ats))) }
+       | '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)) }
@@ -510,7 +548,7 @@ topdecl :: { OrdList (LHsDecl RdrName) }
 -- Type classes
 --
 cl_decl :: { LTyClDecl RdrName }
-       : 'class' tycl_hdr fds where
+       : 'class' tycl_hdr fds where_cls
                {% do { let { (binds, sigs, ats, docs)           = 
                                cvBindsAndSigs (unLoc $4)
                            ; (ctxt, tc, tvs, tparms) = unLoc $2}
@@ -534,7 +572,7 @@ ty_decl :: { LTyClDecl RdrName }
                -- infix type constructors to be declared 
                {% do { (tc, tvs, _) <- checkSynHdr $2 False
                      ; return (L (comb2 $1 $4) 
-                                 (TySynonym tc tvs Nothing $4)) 
+                                 (TySynonym tc tvs Nothing $4))
                       } }
 
            -- type family declarations
@@ -543,11 +581,8 @@ ty_decl :: { LTyClDecl RdrName }
                -- 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))
+                                 (TyFamily TypeFamily tc tvs (unLoc $4)))
                      } }
 
            -- type instance declarations
@@ -583,16 +618,15 @@ ty_decl :: { LTyClDecl RdrName }
                              (unLoc $3) (reverse (unLoc $5)) (unLoc $6)) } }
 
           -- data/newtype family
-        | data_or_newtype 'family' tycl_hdr opt_kind_sig
+        | 'data' '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
+                      ; checkTyVars tparms            -- no type pattern
+                     ; unless (null (unLoc ctxt)) $  -- and no context
+                         parseError (getLoc ctxt) 
+                           "A family declaration cannot have a context"
                      ; return $
                          L (comb3 $1 $2 $4)
-                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) 
-                             (Just kind) [] Nothing) } }
+                           (TyFamily DataFamily tc tvs (unLoc $4)) } }
 
           -- data/newtype instance declaration
        | data_or_newtype 'instance' tycl_hdr constrs deriving
@@ -616,23 +650,27 @@ ty_decl :: { LTyClDecl RdrName }
                            (mkTyData (unLoc $1) (ctxt, tc, tvs, Just tparms) 
                               (unLoc $4) (reverse (unLoc $6)) (unLoc $7)) } }
 
--- Associate type declarations
+-- 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 :: { LTyClDecl RdrName }
+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))
+                                 (TyFamily TypeFamily tc tvs (unLoc $3)))
                      } }
 
-           -- type instance declarations
+           -- default type instance
         | 'type' type '=' ctype
                -- Note the use of type for the head; this allows
                -- infix type constructors and type patterns
@@ -642,14 +680,30 @@ at_decl :: { LTyClDecl RdrName }
                                  (TySynonym tc tvs (Just typats) $4)) 
                       } }
 
-          -- data/newtype family
-        | data_or_newtype tycl_hdr '::' kind
+          -- data/newtype family declaration
+        | 'data' tycl_hdr opt_kind_sig
                {% do { let {(ctxt, tc, tvs, tparms) = unLoc $2}
-                      ; checkTyVars tparms    -- no type pattern
+                      ; checkTyVars tparms            -- no type pattern
+                     ; unless (null (unLoc ctxt)) $  -- and no context
+                         parseError (getLoc ctxt) 
+                           "A family declaration cannot have a context"
                      ; return $
-                         L (comb3 $1 $2 $4)
-                           (mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing) 
-                             (Just (unLoc $4)) [] Nothing) } }
+                         L (comb3 $1 $2 $3)
+                           (TyFamily DataFamily tc tvs (unLoc $3)) 
+                      } }
+
+-- 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
@@ -673,10 +727,6 @@ at_decl :: { LTyClDecl RdrName }
                            (mkTyData (unLoc $1) (ctxt, tc, tvs, Just tparms) 
                             (unLoc $3) (reverse (unLoc $5)) (unLoc $6)) } }
 
-opt_iso :: { Bool }
-       :       { False }
-       | 'iso' { True  }
-
 data_or_newtype :: { Located NewOrData }
        : 'data'        { L1 DataType }
        | 'newtype'     { L1 NewType }
@@ -704,40 +754,64 @@ tycl_hdr :: { Located (LHsContext RdrName,
 
 -- Glasgow extension: stand-alone deriving declarations
 stand_alone_deriving :: { LDerivDecl RdrName }
-       : 'deriving' qtycon            'for' qtycon  {% do { p <- checkInstType (fmap HsTyVar $2)
-                                                          ; checkDerivDecl (LL (DerivDecl p $4)) } }
-
-        | 'deriving' '(' inst_type ')' 'for' qtycon  {% checkDerivDecl (LL (DerivDecl $3 $6)) }
+       : 'derive' 'instance' inst_type {% checkDerivDecl (LL (DerivDecl $3)) }
 
 -----------------------------------------------------------------------------
 -- Nested declarations
 
--- Type declaration or value declaration
+-- Declaration in class bodies
 --
-tydecl  :: { Located (OrdList (LHsDecl RdrName)) }
-tydecl  : at_decl                      { LL (unitOL (L1 (TyClD (unLoc $1)))) }
-       | decl                          { $1 }
-
-tydecls        :: { Located (OrdList (LHsDecl RdrName)) }      -- Reversed
-       : tydecls ';' tydecl            { LL (unLoc $1 `appOL` unLoc $3) }
-       | tydecls ';'                   { LL (unLoc $1) }
-       | tydecl                        { $1 }
-       | {- empty -}                   { noLoc nilOL }
+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 }
 
-tydecllist 
+
+decllist_cls
         :: { Located (OrdList (LHsDecl RdrName)) }     -- Reversed
-       : '{'            tydecls '}'    { LL (unLoc $2) }
-       |     vocurly    tydecls close  { $2 }
+       : '{'         decls_cls '}'     { LL (unLoc $2) }
+       |     vocurly decls_cls close   { $2 }
 
--- Form of the body of class and instance declarations
+-- Class body
 --
-where  :: { Located (OrdList (LHsDecl RdrName)) }      -- Reversed
+where_cls :: { Located (OrdList (LHsDecl RdrName)) }   -- Reversed
                                -- No implicit parameters
                                -- May have type declarations
-       : 'where' tydecllist            { LL (unLoc $2) }
+       : '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) }
@@ -908,8 +982,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)) }
@@ -919,7 +998,8 @@ 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 }
@@ -1056,7 +1136,7 @@ forall :: { Located [LHsTyVarBndr RdrName] }
        : 'forall' tv_bndrs '.'         { LL $2 }
        | {- empty -}                   { noLoc [] }
 
-constr_stuff :: { Located (Located RdrName, HsConDetails RdrName (LBangType RdrName)) }
+constr_stuff :: { Located (Located RdrName, HsConDeclDetails RdrName) }
 -- We parse the constructor declaration 
 --     C t1 t2
 -- as a btype (treating C as a type constructor) and then convert C to be
@@ -1069,7 +1149,7 @@ constr_stuff :: { Located (Located RdrName, HsConDetails RdrName (LBangType RdrN
        | oqtycon '{' fielddecls '}'    {% mkRecCon $1 $3 >>= return.LL }
        | btype conop btype             { LL ($2, InfixCon $1 $3) }
 
-constr_stuff_record :: { Located (Located RdrName, HsConDetails RdrName (LBangType RdrName)) }
+constr_stuff_record :: { Located (Located RdrName, HsConDeclDetails RdrName) }
        : oqtycon '{' '}'               {% mkRecCon $1 [] >>= return.sL (comb2 $1 $>) }
        | oqtycon '{' fielddecls '}'    {% mkRecCon $1 $3 >>= return.sL (comb2 $1 $>) }
 
@@ -1128,7 +1208,7 @@ docdecld :: { LDocDecl RdrName }
 
 decl   :: { Located (OrdList (LHsDecl RdrName)) }
        : sigdecl                       { $1 }
-       | '!' infixexp rhs              {% do { pat <- checkPattern $2;
+       | '!' aexp rhs                  {% do { pat <- checkPattern $2;
                                                return (LL $ unitOL $ LL $ ValD ( 
                                                        PatBind (LL $ BangPat pat) (unLoc $3)
                                                                placeHolderType placeHolderNames)) } }
@@ -1183,15 +1263,14 @@ 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)) }
-       | '-' fexp                              { LL $ mkHsNegApp $2 }
+       | '-' fexp                              { LL $ NegApp $2 noSyntaxExpr }
 
        | 'do' stmtlist                 {% let loc = comb2 $1 $2 in
                                           checkDo loc (unLoc $2)  >>= \ (stmts,body) ->
@@ -1202,6 +1281,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 -> 
@@ -1217,24 +1299,30 @@ 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 }
-        : aexp1 '{' fbinds '}'         {% do { r <- mkRecConstrOrUpdate $1 (comb2 $2 $4) 
-                                                       (reverse $3);
-                                       return (LL r) }}
+        : aexp1 '{' fbinds '}'         {% do { r <- mkRecConstrOrUpdate $1 (comb2 $2 $4) $3
+                                     ; return (LL r) }}
        | aexp2                 { $1 }
 
 -- Here was the syntax for type applications that I was planning
@@ -1249,6 +1337,9 @@ aexp2     :: { LHsExpr RdrName }
        : ipvar                         { L1 (HsIPVar $! unLoc $1) }
        | qcname                        { L1 (HsVar   $! unLoc $1) }
        | literal                       { L1 (HsLit   $! unLoc $1) }
+-- This will enable overloaded strings permanently.  Normally the renamer turns HsString
+-- into HsOverLit when -foverloaded-strings is on.
+--     | STRING                        { L1 (HsOverLit $! mkHsIsString (getSTRING $1)) }
        | INTEGER                       { L1 (HsOverLit $! mkHsIntegral (getINTEGER $1)) }
        | RATIONAL                      { L1 (HsOverLit $! mkHsFractional (getRATIONAL $1)) }
        | '(' exp ')'                   { LL (HsPar $2) }
@@ -1273,8 +1364,9 @@ aexp2     :: { LHsExpr RdrName }
        | '[|' exp '|]'         { LL $ HsBracket (ExpBr $2) }                       
        | '[t|' ctype '|]'      { LL $ HsBracket (TypBr $2) }                       
        | '[p|' infixexp '|]'   {% checkPattern $2 >>= \p ->
-                                          return (LL $ HsBracket (PatBr p)) }
-       | '[d|' cvtopbody '|]'  { LL $ HsBracket (DecBr (mkGroup $2)) }
+                                       return (LL $ HsBracket (PatBr p)) }
+       | '[d|' cvtopbody '|]'  {% checkDecBrGroup $2 >>= \g -> 
+                                       return (LL $ HsBracket (DecBr g)) }
 
        -- arrow notation extension
        | '(|' aexp2 cmdargs '|)'       { LL $ HsArrForm $2 Nothing (reverse $3) }
@@ -1355,12 +1447,12 @@ quals :: { Located [LStmt RdrName] }
 
 parr :: { LHsExpr RdrName }
        :                               { noLoc (ExplicitPArr placeHolderType []) }
-       | exp                           { L1 $ ExplicitPArr placeHolderType [$1] }
+       | texp                          { L1 $ ExplicitPArr placeHolderType [$1] }
        | lexps                         { L1 $ ExplicitPArr placeHolderType 
                                                       (reverse (unLoc $1)) }
-       | exp '..' exp                  { LL $ PArrSeq noPostTcExpr (FromTo $1 $3) }
-       | exp ',' exp '..' exp          { LL $ PArrSeq noPostTcExpr (FromThenTo $1 $3 $5) }
-       | exp pquals                    { sL (comb2 $1 $>) $ mkHsDo PArrComp (reverse (unLoc $2)) $1 }
+       | texp '..' exp                 { LL $ PArrSeq noPostTcExpr (FromTo $1 $3) }
+       | texp ',' exp '..' exp         { LL $ PArrSeq noPostTcExpr (FromThenTo $1 $3 $5) }
+       | texp pquals                   { sL (comb2 $1 $>) $ mkHsDo PArrComp (reverse (unLoc $2)) $1 }
 
 -- We are reusing `lexps' and `pquals' from the list case.
 
@@ -1381,10 +1473,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))) }
-       | '!' infixexp opt_sig alt_rhs  {%  checkPattern $2 >>= \p ->
-                                           return (LL (Match [LL $ BangPat p] $3 (unLoc $4))) }
+       : pat opt_sig alt_rhs           { LL (Match [$1] $2 (unLoc $3)) }
 
 alt_rhs :: { Located (GRHSs RdrName) }
        : ralt wherebinds               { LL (GRHSs (unLoc $1) (unLoc $2)) }
@@ -1400,6 +1489,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
 
@@ -1429,29 +1534,34 @@ 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) }
 
 -----------------------------------------------------------------------------
 -- Record Field Update/Construction
 
-fbinds         :: { HsRecordBinds RdrName }
+fbinds         :: { ([HsRecField RdrName (LHsExpr RdrName)], Bool) }
        : fbinds1                       { $1 }
-       | {- empty -}                   { [] }
+       | {- empty -}                   { ([], False) }
 
-fbinds1        :: { HsRecordBinds RdrName }
-       : fbinds1 ',' fbind             { $3 : $1 }
-       | fbind                         { [$1] }
+fbinds1        :: { ([HsRecField RdrName (LHsExpr RdrName)], Bool) }
+       : fbind ',' fbinds1             { case $3 of (flds, dd) -> ($1 : flds, dd) } 
+       | fbind                         { ([$1], False) }
+       | '..'                          { ([],   True) }
   
-fbind  :: { (Located RdrName, LHsExpr RdrName) }
-       : qvar '=' exp                  { ($1,$3) }
+fbind  :: { HsRecField RdrName (LHsExpr RdrName) }
+       : qvar '=' exp  { HsRecField $1 $3 False }
+       | qvar          { HsRecField $1 (L (getLoc $1) (HsVar (unLoc $1))) True }
+                       -- Here's where we say that plain 'x'
+                       -- means exactly 'x = x'.  The pun-flag boolean is
+                       -- there so we can still print it right
 
 -----------------------------------------------------------------------------
 -- Implicit Parameter Bindings
@@ -1618,7 +1728,6 @@ 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 }
@@ -1643,14 +1752,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', 'forall', 'family', and 'iso' whose treatment differs
+-- except 'unsafe', 'forall', and 'family' whose treatment differs
 -- depending on context 
 special_id :: { Located FastString }
 special_id
        : 'as'                  { L1 FSLIT("as") }
        | 'qualified'           { L1 FSLIT("qualified") }
        | 'hiding'              { L1 FSLIT("hiding") }
-        | 'for'                 { L1 FSLIT("for") }
+       | 'derive'              { L1 FSLIT("derive") }
        | 'export'              { L1 FSLIT("export") }
        | 'label'               { L1 FSLIT("label")  }
        | 'dynamic'             { L1 FSLIT("dynamic") }
@@ -1688,7 +1797,7 @@ consym :: { Located RdrName }
 
 literal :: { Located HsLit }
        : CHAR                  { L1 $ HsChar       $ getCHAR $1 }
-       | STRING                { L1 $ HsString     $ getSTRING $1 }
+       | STRING                { L1 $ HsString     $ getSTRING $1 }
        | PRIMINTEGER           { L1 $ HsIntPrim    $ getPRIMINTEGER $1 }
        | PRIMCHAR              { L1 $ HsCharPrim   $ getPRIMCHAR $1 }
        | PRIMSTRING            { L1 $ HsStringPrim $ getPRIMSTRING $1 }
@@ -1755,7 +1864,7 @@ moduleheader :: { (HaddockModInfo RdrName, Maybe (HsDoc RdrName)) }
                      Left err -> parseError (getLoc $1) err;                    
                      Right doc -> return (info, Just doc);          
                    };                                             
-                 Left err -> parseError (getLoc $1) err                           
+                 Left err -> parseError (getLoc $1) err
             }  }                                                  
 
 maybe_docprev :: { Maybe (LHsDoc RdrName) }