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 Monad ( when )
import Outputable
-import GLAEXTS
+
+import Control.Monad ( when )
+import GHC.Exts
+import Data.Char
+import Control.Monad ( mplus )
}
{-
-----------------------------------------------------------------------------
+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
-=chak
-----------------------------------------------------------------------------
-Conflicts: 36 shift/reduce (1.25)
+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)
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
'deriving' { L _ ITderiving }
'do' { L _ ITdo }
'else' { L _ ITelse }
+ 'for' { L _ ITfor }
'hiding' { L _ IThiding }
'if' { L _ ITif }
'import' { L _ ITimport }
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 }
-- 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 }
-- 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 }
: '(' 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 }
-- 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) }
: 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)) }
| '{-# DEPRECATED' deprecations '#-}' { $2 }
-- Type classes
--
cl_decl :: { LTyClDecl RdrName }
- : 'class' tycl_hdr fds where
- {% do { let { (binds, sigs, ats) =
+ : '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) } }
+ (unLoc $3) sigs binds ats docs) } }
-- Type declarations (toplevel)
--
(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).
--
-at_decl :: { LTyClDecl RdrName }
+-- * 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
(TyFunction tc tvs False kind))
} }
- -- 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
(TySynonym tc tvs (Just typats) $4))
} }
- -- data/newtype family
- | data_or_newtype tycl_hdr '::' kind
+ -- 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 $4)
+ L (comb3 $1 $2 $3)
(mkTyData (unLoc $1) (ctxt, tc, tvs, Nothing)
- (Just (unLoc $4)) [] 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
| type {% checkTyClHdr (noLoc []) $1 >>= return.L1 }
-----------------------------------------------------------------------------
+-- Stand-alone deriving
+
+-- 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)) }
+
+-----------------------------------------------------------------------------
-- 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 }
+
+
+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 }
-tydecllist
+-- 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
- : '{' tydecls '}' { LL (unLoc $2) }
- | vocurly tydecls close { $2 }
+ : '{' decls_inst '}' { LL (unLoc $2) }
+ | vocurly decls_inst close { $2 }
--- Form of the body of class and instance declarations
+-- Instance body
--
-where :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
+where_inst :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
-- No implicit parameters
-- May have type declarations
- : 'where' tydecllist { LL (unLoc $2) }
+ : '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 }
| '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
: 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] }
-----------------------------------------------------------------------------
-- 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 }
: 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)) }
-- 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 }
: 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).
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) }
: '|' 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)))
| 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 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 }
| 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)) }
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
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) }
: 'as' { L1 FSLIT("as") }
| 'qualified' { L1 FSLIT("qualified") }
| 'hiding' { L1 FSLIT("hiding") }
+ | 'for' { L1 FSLIT("for") }
| 'export' { L1 FSLIT("export") }
| 'label' { L1 FSLIT("label") }
| 'dynamic' { L1 FSLIT("dynamic") }
| ',' { 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
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