summaryrefslogtreecommitdiff
path: root/compiler/parser/Parser.y.pp
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/parser/Parser.y.pp')
-rw-r--r--compiler/parser/Parser.y.pp1607
1 files changed, 1607 insertions, 0 deletions
diff --git a/compiler/parser/Parser.y.pp b/compiler/parser/Parser.y.pp
new file mode 100644
index 0000000000..3066a0f876
--- /dev/null
+++ b/compiler/parser/Parser.y.pp
@@ -0,0 +1,1607 @@
+-- -*-haskell-*-
+-- ---------------------------------------------------------------------------
+-- (c) The University of Glasgow 1997-2003
+---
+-- The GHC grammar.
+--
+-- Author(s): Simon Marlow, Sven Panne 1997, 1998, 1999
+-- ---------------------------------------------------------------------------
+
+{
+module Parser ( parseModule, parseStmt, parseIdentifier, parseType,
+ parseHeader ) where
+
+#define INCLUDE #include
+INCLUDE "HsVersions.h"
+
+import HsSyn
+import RdrHsSyn
+import HscTypes ( IsBootInterface, DeprecTxt )
+import Lexer
+import RdrName
+import TysWiredIn ( unitTyCon, unitDataCon, tupleTyCon, tupleCon, nilDataCon,
+ listTyCon_RDR, parrTyCon_RDR, consDataCon_RDR )
+import Type ( funTyCon )
+import ForeignCall ( Safety(..), CExportSpec(..), CLabelString,
+ CCallConv(..), CCallTarget(..), defaultCCallConv
+ )
+import OccName ( varName, dataName, tcClsName, tvName )
+import DataCon ( DataCon, dataConName )
+import SrcLoc ( Located(..), unLoc, getLoc, noLoc, combineSrcSpans,
+ SrcSpan, combineLocs, srcLocFile,
+ mkSrcLoc, mkSrcSpan )
+import Module
+import StaticFlags ( opt_SccProfilingOn )
+import Type ( Kind, mkArrowKind, liftedTypeKind )
+import BasicTypes ( Boxity(..), Fixity(..), FixityDirection(..), IPName(..),
+ Activation(..), defaultInlineSpec )
+import OrdList
+
+import FastString
+import Maybes ( orElse )
+import Outputable
+import GLAEXTS
+}
+
+{-
+-----------------------------------------------------------------------------
+Conflicts: 36 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)
+ 10 because op might be: : - ! * . `x` VARSYM CONSYM QVARSYM QCONSYM
+
+1 for ambiguity in 'if x then y else z :: T' [State 178]
+ (shift parses as 'if x then y else (z :: T)', as per longest-parse rule)
+
+4 for ambiguity in 'if x then y else z -< e' [State 178]
+ (shift parses as 'if x then y else (z -< T)', as per longest-parse rule)
+ There are four such operators: -<, >-, -<<, >>-
+
+
+2 for ambiguity in 'case v of { x :: T -> T ... } ' [States 11, 253]
+ Which of these two is intended?
+ case v of
+ (x::T) -> T -- Rhs is T
+ or
+ case v of
+ (x::T -> T) -> .. -- Rhs is ...
+
+10 for ambiguity in 'e :: a `b` c'. Does this mean [States 11, 253]
+ (e::a) `b` c, or
+ (e :: (a `b` c))
+ As well as `b` we can have !, VARSYM, QCONSYM, and CONSYM, hence 5 cases
+ Same duplication between states 11 and 253 as the previous case
+
+1 for ambiguity in 'let ?x ...' [State 329]
+ the parser can't tell whether the ?x is the lhs of a normal binding or
+ an implicit binding. Fortunately resolving as shift gives it the only
+ sensible meaning, namely the lhs of an implicit binding.
+
+1 for ambiguity in '{-# RULES "name" [ ... #-} [State 382]
+ we don't know whether the '[' starts the activation or not: it
+ might be the start of the declaration with the activation being
+ empty. --SDM 1/4/2002
+
+6 for conflicts between `fdecl' and `fdeclDEPRECATED', [States 393,394]
+ which are resolved correctly, and moreover,
+ should go away when `fdeclDEPRECATED' is removed.
+
+1 for ambiguity in '{-# RULES "name" forall = ... #-}' [State 474]
+ since 'forall' is a valid variable name, we don't know whether
+ to treat a forall on the input as the beginning of a quantifier
+ or the beginning of the rule itself. Resolving to shift means
+ it's always treated as a quantifier, hence the above is disallowed.
+ This saves explicitly defining a grammar for the rule lhs that
+ doesn't include 'forall'.
+
+-- ---------------------------------------------------------------------------
+-- Adding location info
+
+This is done in a stylised way using the three macros below, L0, L1
+and LL. Each of these macros can be thought of as having type
+
+ L0, L1, LL :: a -> Located a
+
+They each add a SrcSpan to their argument.
+
+ L0 adds 'noSrcSpan', used for empty productions
+
+ L1 for a production with a single token on the lhs. Grabs the SrcSpan
+ from that token.
+
+ LL for a production with >1 token on the lhs. Makes up a SrcSpan from
+ the first and last tokens.
+
+These suffice for the majority of cases. However, we must be
+especially careful with empty productions: LL won't work if the first
+or last token on the lhs can represent an empty span. In these cases,
+we have to calculate the span using more of the tokens from the lhs, eg.
+
+ | 'newtype' tycl_hdr '=' newconstr deriving
+ { L (comb3 $1 $4 $5)
+ (mkTyData NewType (unLoc $2) [$4] (unLoc $5)) }
+
+We provide comb3 and comb4 functions which are useful in such cases.
+
+Be careful: there's no checking that you actually got this right, the
+only symptom will be that the SrcSpans of your syntax will be
+incorrect.
+
+/*
+ * We must expand these macros *before* running Happy, which is why this file is
+ * Parser.y.pp rather than just Parser.y - we run the C pre-processor first.
+ */
+#define L0 L noSrcSpan
+#define L1 sL (getLoc $1)
+#define LL sL (comb2 $1 $>)
+
+-- -----------------------------------------------------------------------------
+
+-}
+
+%token
+ '_' { L _ ITunderscore } -- Haskell keywords
+ 'as' { L _ ITas }
+ 'case' { L _ ITcase }
+ 'class' { L _ ITclass }
+ 'data' { L _ ITdata }
+ 'default' { L _ ITdefault }
+ 'deriving' { L _ ITderiving }
+ 'do' { L _ ITdo }
+ 'else' { L _ ITelse }
+ 'hiding' { L _ IThiding }
+ 'if' { L _ ITif }
+ 'import' { L _ ITimport }
+ 'in' { L _ ITin }
+ 'infix' { L _ ITinfix }
+ 'infixl' { L _ ITinfixl }
+ 'infixr' { L _ ITinfixr }
+ 'instance' { L _ ITinstance }
+ 'let' { L _ ITlet }
+ 'module' { L _ ITmodule }
+ 'newtype' { L _ ITnewtype }
+ 'of' { L _ ITof }
+ 'qualified' { L _ ITqualified }
+ 'then' { L _ ITthen }
+ 'type' { L _ ITtype }
+ 'where' { L _ ITwhere }
+ '_scc_' { L _ ITscc } -- ToDo: remove
+
+ 'forall' { L _ ITforall } -- GHC extension keywords
+ 'foreign' { L _ ITforeign }
+ 'export' { L _ ITexport }
+ 'label' { L _ ITlabel }
+ 'dynamic' { L _ ITdynamic }
+ 'safe' { L _ ITsafe }
+ 'threadsafe' { L _ ITthreadsafe }
+ 'unsafe' { L _ ITunsafe }
+ 'mdo' { L _ ITmdo }
+ 'stdcall' { L _ ITstdcallconv }
+ 'ccall' { L _ ITccallconv }
+ 'dotnet' { L _ ITdotnet }
+ 'proc' { L _ ITproc } -- for arrow notation extension
+ 'rec' { L _ ITrec } -- for arrow notation extension
+
+ '{-# INLINE' { L _ (ITinline_prag _) }
+ '{-# SPECIALISE' { L _ ITspec_prag }
+ '{-# SPECIALISE_INLINE' { L _ (ITspec_inline_prag _) }
+ '{-# SOURCE' { L _ ITsource_prag }
+ '{-# RULES' { L _ ITrules_prag }
+ '{-# CORE' { L _ ITcore_prag } -- hdaume: annotated core
+ '{-# SCC' { L _ ITscc_prag }
+ '{-# DEPRECATED' { L _ ITdeprecated_prag }
+ '{-# UNPACK' { L _ ITunpack_prag }
+ '#-}' { L _ ITclose_prag }
+
+ '..' { L _ ITdotdot } -- reserved symbols
+ ':' { L _ ITcolon }
+ '::' { L _ ITdcolon }
+ '=' { L _ ITequal }
+ '\\' { L _ ITlam }
+ '|' { L _ ITvbar }
+ '<-' { L _ ITlarrow }
+ '->' { L _ ITrarrow }
+ '@' { L _ ITat }
+ '~' { L _ ITtilde }
+ '=>' { L _ ITdarrow }
+ '-' { L _ ITminus }
+ '!' { L _ ITbang }
+ '*' { L _ ITstar }
+ '-<' { L _ ITlarrowtail } -- for arrow notation
+ '>-' { L _ ITrarrowtail } -- for arrow notation
+ '-<<' { L _ ITLarrowtail } -- for arrow notation
+ '>>-' { L _ ITRarrowtail } -- for arrow notation
+ '.' { L _ ITdot }
+
+ '{' { L _ ITocurly } -- special symbols
+ '}' { L _ ITccurly }
+ '{|' { L _ ITocurlybar }
+ '|}' { L _ ITccurlybar }
+ vocurly { L _ ITvocurly } -- virtual open curly (from layout)
+ vccurly { L _ ITvccurly } -- virtual close curly (from layout)
+ '[' { L _ ITobrack }
+ ']' { L _ ITcbrack }
+ '[:' { L _ ITopabrack }
+ ':]' { L _ ITcpabrack }
+ '(' { L _ IToparen }
+ ')' { L _ ITcparen }
+ '(#' { L _ IToubxparen }
+ '#)' { L _ ITcubxparen }
+ '(|' { L _ IToparenbar }
+ '|)' { L _ ITcparenbar }
+ ';' { L _ ITsemi }
+ ',' { L _ ITcomma }
+ '`' { L _ ITbackquote }
+
+ VARID { L _ (ITvarid _) } -- identifiers
+ CONID { L _ (ITconid _) }
+ VARSYM { L _ (ITvarsym _) }
+ CONSYM { L _ (ITconsym _) }
+ QVARID { L _ (ITqvarid _) }
+ QCONID { L _ (ITqconid _) }
+ QVARSYM { L _ (ITqvarsym _) }
+ QCONSYM { L _ (ITqconsym _) }
+
+ IPDUPVARID { L _ (ITdupipvarid _) } -- GHC extension
+ IPSPLITVARID { L _ (ITsplitipvarid _) } -- GHC extension
+
+ CHAR { L _ (ITchar _) }
+ STRING { L _ (ITstring _) }
+ INTEGER { L _ (ITinteger _) }
+ RATIONAL { L _ (ITrational _) }
+
+ PRIMCHAR { L _ (ITprimchar _) }
+ PRIMSTRING { L _ (ITprimstring _) }
+ PRIMINTEGER { L _ (ITprimint _) }
+ PRIMFLOAT { L _ (ITprimfloat _) }
+ PRIMDOUBLE { L _ (ITprimdouble _) }
+
+-- Template Haskell
+'[|' { L _ ITopenExpQuote }
+'[p|' { L _ ITopenPatQuote }
+'[t|' { L _ ITopenTypQuote }
+'[d|' { L _ ITopenDecQuote }
+'|]' { L _ ITcloseQuote }
+TH_ID_SPLICE { L _ (ITidEscape _) } -- $x
+'$(' { L _ ITparenEscape } -- $( exp )
+TH_VAR_QUOTE { L _ ITvarQuote } -- 'x
+TH_TY_QUOTE { L _ ITtyQuote } -- ''T
+
+%monad { P } { >>= } { return }
+%lexer { lexer } { L _ ITeof }
+%name parseModule module
+%name parseStmt maybe_stmt
+%name parseIdentifier identifier
+%name parseType ctype
+%partial parseHeader header
+%tokentype { (Located Token) }
+%%
+
+-----------------------------------------------------------------------------
+-- Identifiers; one of the entry points
+identifier :: { Located RdrName }
+ : qvar { $1 }
+ | qcon { $1 }
+ | qvarop { $1 }
+ | qconop { $1 }
+
+-----------------------------------------------------------------------------
+-- Module Header
+
+-- The place for module deprecation is really too restrictive, but if it
+-- was allowed at its natural place just before 'module', we get an ugly
+-- s/r conflict with the second alternative. Another solution would be the
+-- introduction of a new pragma DEPRECATED_MODULE, but this is not very nice,
+-- either, and DEPRECATED is only expected to be used by people who really
+-- 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)) }
+ | missing_module_keyword top close
+ {% fileSrcSpan >>= \ loc ->
+ return (L loc (HsModule Nothing Nothing
+ (fst $2) (snd $2) Nothing)) }
+
+missing_module_keyword :: { () }
+ : {- empty -} {% pushCurrentContext }
+
+maybemoddeprec :: { Maybe DeprecTxt }
+ : '{-# DEPRECATED' STRING '#-}' { Just (getSTRING $2) }
+ | {- empty -} { Nothing }
+
+body :: { ([LImportDecl RdrName], [LHsDecl RdrName]) }
+ : '{' top '}' { $2 }
+ | vocurly top close { $2 }
+
+top :: { ([LImportDecl RdrName], [LHsDecl RdrName]) }
+ : importdecls { (reverse $1,[]) }
+ | importdecls ';' cvtopdecls { (reverse $1,$3) }
+ | cvtopdecls { ([],$1) }
+
+cvtopdecls :: { [LHsDecl RdrName] }
+ : topdecls { cvTopDecls $1 }
+
+-----------------------------------------------------------------------------
+-- 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)) }
+ | missing_module_keyword importdecls
+ {% fileSrcSpan >>= \ loc ->
+ return (L loc (HsModule Nothing Nothing $2 [] Nothing)) }
+
+header_body :: { [LImportDecl RdrName] }
+ : '{' importdecls { $2 }
+ | vocurly importdecls { $2 }
+
+-----------------------------------------------------------------------------
+-- The Export List
+
+maybeexports :: { Maybe [LIE RdrName] }
+ : '(' exportlist ')' { Just $2 }
+ | {- empty -} { Nothing }
+
+exportlist :: { [LIE RdrName] }
+ : exportlist ',' export { $3 : $1 }
+ | exportlist ',' { $1 }
+ | export { [$1] }
+ | {- empty -} { [] }
+
+ -- No longer allow things like [] and (,,,) to be exported
+ -- They are built in syntax, always available
+export :: { LIE RdrName }
+ : qvar { L1 (IEVar (unLoc $1)) }
+ | oqtycon { L1 (IEThingAbs (unLoc $1)) }
+ | oqtycon '(' '..' ')' { LL (IEThingAll (unLoc $1)) }
+ | oqtycon '(' ')' { LL (IEThingWith (unLoc $1) []) }
+ | oqtycon '(' qcnames ')' { LL (IEThingWith (unLoc $1) (reverse $3)) }
+ | 'module' modid { LL (IEModuleContents (unLoc $2)) }
+
+qcnames :: { [RdrName] }
+ : qcnames ',' qcname { unLoc $3 : $1 }
+ | qcname { [unLoc $1] }
+
+qcname :: { Located RdrName } -- Variable or data constructor
+ : qvar { $1 }
+ | qcon { $1 }
+
+-----------------------------------------------------------------------------
+-- Import Declarations
+
+-- import decls can be *empty*, or even just a string of semicolons
+-- whereas topdecls must contain at least one topdecl.
+
+importdecls :: { [LImportDecl RdrName] }
+ : importdecls ';' importdecl { $3 : $1 }
+ | importdecls ';' { $1 }
+ | importdecl { [ $1 ] }
+ | {- empty -} { [] }
+
+importdecl :: { LImportDecl RdrName }
+ : 'import' maybe_src optqualified modid maybeas maybeimpspec
+ { L (comb4 $1 $4 $5 $6) (ImportDecl $4 $2 $3 (unLoc $5) (unLoc $6)) }
+
+maybe_src :: { IsBootInterface }
+ : '{-# SOURCE' '#-}' { True }
+ | {- empty -} { False }
+
+optqualified :: { Bool }
+ : 'qualified' { True }
+ | {- empty -} { False }
+
+maybeas :: { Located (Maybe Module) }
+ : 'as' modid { LL (Just (unLoc $2)) }
+ | {- empty -} { noLoc Nothing }
+
+maybeimpspec :: { Located (Maybe (Bool, [LIE RdrName])) }
+ : impspec { L1 (Just (unLoc $1)) }
+ | {- empty -} { noLoc Nothing }
+
+impspec :: { Located (Bool, [LIE RdrName]) }
+ : '(' exportlist ')' { LL (False, reverse $2) }
+ | 'hiding' '(' exportlist ')' { LL (True, reverse $3) }
+
+-----------------------------------------------------------------------------
+-- Fixity Declarations
+
+prec :: { Int }
+ : {- empty -} { 9 }
+ | INTEGER {% checkPrecP (L1 (fromInteger (getINTEGER $1))) }
+
+infix :: { Located FixityDirection }
+ : 'infix' { L1 InfixN }
+ | 'infixl' { L1 InfixL }
+ | 'infixr' { L1 InfixR }
+
+ops :: { Located [Located RdrName] }
+ : ops ',' op { LL ($3 : unLoc $1) }
+ | op { L1 [$1] }
+
+-----------------------------------------------------------------------------
+-- Top-Level Declarations
+
+topdecls :: { OrdList (LHsDecl RdrName) } -- Reversed
+ : 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))) }
+ | 'default' '(' comma_types0 ')' { unitOL (LL $ DefD (DefaultDecl $3)) }
+ | 'foreign' fdecl { unitOL (LL (unLoc $2)) }
+ | '{-# DEPRECATED' deprecations '#-}' { $2 }
+ | '{-# RULES' rules '#-}' { $2 }
+ | '$(' exp ')' { unitOL (LL $ SpliceD (SpliceDecl $2)) }
+ | decl { unLoc $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
+ -- 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)) } }
+
+ | 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)) }
+
+ | 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)) }
+
+ | '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) }
+
+data_or_newtype :: { Located NewOrData }
+ : 'data' { L1 DataType }
+ | 'newtype' { L1 NewType }
+
+opt_kind_sig :: { Maybe Kind }
+ : { Nothing }
+ | '::' kind { Just $2 }
+
+-- tycl_hdr parses the header of a type or class decl,
+-- which takes the form
+-- T a b
+-- Eq a => T a
+-- (Eq a, Ord b) => T a b
+-- Rather a lot of inlining here, else we get reduce/reduce errors
+tycl_hdr :: { Located (LHsContext RdrName, Located RdrName, [LHsTyVarBndr RdrName]) }
+ : context '=>' type {% checkTyClHdr $1 $3 >>= return.LL }
+ | type {% checkTyClHdr (noLoc []) $1 >>= return.L1 }
+
+-----------------------------------------------------------------------------
+-- Nested declarations
+
+decls :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
+ : decls ';' decl { LL (unLoc $1 `appOL` unLoc $3) }
+ | decls ';' { LL (unLoc $1) }
+ | decl { $1 }
+ | {- empty -} { noLoc nilOL }
+
+
+decllist :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
+ : '{' decls '}' { LL (unLoc $2) }
+ | vocurly decls close { $2 }
+
+where :: { Located (OrdList (LHsDecl RdrName)) } -- Reversed
+ -- No implicit parameters
+ : 'where' decllist { LL (unLoc $2) }
+ | {- empty -} { noLoc nilOL }
+
+binds :: { Located (HsLocalBinds RdrName) } -- May have implicit parameters
+ : 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
+ : 'where' binds { LL (unLoc $2) }
+ | {- empty -} { noLoc emptyLocalBinds }
+
+
+-----------------------------------------------------------------------------
+-- Transformation Rules
+
+rules :: { OrdList (LHsDecl RdrName) } -- Reversed
+ : rules ';' rule { $1 `snocOL` $3 }
+ | rules ';' { $1 }
+ | rule { unitOL $1 }
+ | {- empty -} { nilOL }
+
+rule :: { LHsDecl RdrName }
+ : STRING activation rule_forall infixexp '=' exp
+ { LL $ RuleD (HsRule (getSTRING $1)
+ ($2 `orElse` AlwaysActive)
+ $3 $4 placeHolderNames $6 placeHolderNames) }
+
+activation :: { Maybe Activation }
+ : {- empty -} { Nothing }
+ | explicit_activation { Just $1 }
+
+explicit_activation :: { Activation } -- In brackets
+ : '[' INTEGER ']' { ActiveAfter (fromInteger (getINTEGER $2)) }
+ | '[' '~' INTEGER ']' { ActiveBefore (fromInteger (getINTEGER $3)) }
+
+rule_forall :: { [RuleBndr RdrName] }
+ : 'forall' rule_var_list '.' { $2 }
+ | {- empty -} { [] }
+
+rule_var_list :: { [RuleBndr RdrName] }
+ : rule_var { [$1] }
+ | rule_var rule_var_list { $1 : $2 }
+
+rule_var :: { RuleBndr RdrName }
+ : varid { RuleBndr $1 }
+ | '(' varid '::' ctype ')' { RuleBndrSig $2 $4 }
+
+-----------------------------------------------------------------------------
+-- Deprecations (c.f. rules)
+
+deprecations :: { OrdList (LHsDecl RdrName) } -- Reversed
+ : deprecations ';' deprecation { $1 `appOL` $3 }
+ | deprecations ';' { $1 }
+ | deprecation { $1 }
+ | {- empty -} { nilOL }
+
+-- SUP: TEMPORARY HACK, not checking for `module Foo'
+deprecation :: { OrdList (LHsDecl RdrName) }
+ : depreclist STRING
+ { toOL [ LL $ DeprecD (Deprecation n (getSTRING $2))
+ | n <- unLoc $1 ] }
+
+
+-----------------------------------------------------------------------------
+-- Foreign import and export declarations
+
+-- for the time being, the following accepts foreign declarations conforming
+-- to the FFI Addendum, Version 1.0 as well as pre-standard declarations
+--
+-- * a flag indicates whether pre-standard declarations have been used and
+-- triggers a deprecation warning further down the road
+--
+-- NB: The first two rules could be combined into one by replacing `safety1'
+-- with `safety'. However, the combined rule conflicts with the
+-- DEPRECATED rules.
+--
+fdecl :: { LHsDecl RdrName }
+fdecl : 'import' callconv safety1 fspec
+ {% mkImport $2 $3 (unLoc $4) >>= return.LL }
+ | 'import' callconv fspec
+ {% do { d <- mkImport $2 (PlaySafe False) (unLoc $3);
+ return (LL d) } }
+ | 'export' callconv fspec
+ {% mkExport $2 (unLoc $3) >>= return.LL }
+ -- the following syntax is DEPRECATED
+ | fdecl1DEPRECATED { L1 (ForD (unLoc $1)) }
+ | fdecl2DEPRECATED { L1 (unLoc $1) }
+
+fdecl1DEPRECATED :: { LForeignDecl RdrName }
+fdecl1DEPRECATED
+ ----------- DEPRECATED label decls ------------
+ : 'label' ext_name varid '::' sigtype
+ { LL $ ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS
+ (CLabel ($2 `orElse` mkExtName (unLoc $3)))) True }
+
+ ----------- DEPRECATED ccall/stdcall decls ------------
+ --
+ -- NB: This business with the case expression below may seem overly
+ -- complicated, but it is necessary to avoid some conflicts.
+
+ -- DEPRECATED variant #1: lack of a calling convention specification
+ -- (import)
+ | 'import' {-no callconv-} ext_name safety varid_no_unsafe '::' sigtype
+ { let
+ target = StaticTarget ($2 `orElse` mkExtName (unLoc $4))
+ in
+ LL $ ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS
+ (CFunction target)) True }
+
+ -- DEPRECATED variant #2: external name consists of two separate strings
+ -- (module name and function name) (import)
+ | 'import' callconv STRING STRING safety varid_no_unsafe '::' sigtype
+ {% case $2 of
+ DNCall -> parseError (comb2 $1 $>) "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ let
+ imp = CFunction (StaticTarget (getSTRING $4))
+ in
+ LL $ ForeignImport $6 $8 (CImport cconv $5 nilFS nilFS imp) True }
+
+ -- DEPRECATED variant #3: `unsafe' after entity
+ | 'import' callconv STRING 'unsafe' varid_no_unsafe '::' sigtype
+ {% case $2 of
+ DNCall -> parseError (comb2 $1 $>) "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ let
+ imp = CFunction (StaticTarget (getSTRING $3))
+ in
+ LL $ ForeignImport $5 $7 (CImport cconv PlayRisky nilFS nilFS imp) True }
+
+ -- DEPRECATED variant #4: use of the special identifier `dynamic' without
+ -- an explicit calling convention (import)
+ | 'import' {-no callconv-} 'dynamic' safety varid_no_unsafe '::' sigtype
+ { LL $ ForeignImport $4 $6 (CImport defaultCCallConv $3 nilFS nilFS
+ (CFunction DynamicTarget)) True }
+
+ -- DEPRECATED variant #5: use of the special identifier `dynamic' (import)
+ | 'import' callconv 'dynamic' safety varid_no_unsafe '::' sigtype
+ {% case $2 of
+ DNCall -> parseError (comb2 $1 $>) "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ LL $ ForeignImport $5 $7 (CImport cconv $4 nilFS nilFS
+ (CFunction DynamicTarget)) True }
+
+ -- DEPRECATED variant #6: lack of a calling convention specification
+ -- (export)
+ | 'export' {-no callconv-} ext_name varid '::' sigtype
+ { LL $ ForeignExport $3 $5 (CExport (CExportStatic ($2 `orElse` mkExtName (unLoc $3))
+ defaultCCallConv)) True }
+
+ -- DEPRECATED variant #7: external name consists of two separate strings
+ -- (module name and function name) (export)
+ | 'export' callconv STRING STRING varid '::' sigtype
+ {% case $2 of
+ DNCall -> parseError (comb2 $1 $>) "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ LL $ ForeignExport $5 $7
+ (CExport (CExportStatic (getSTRING $4) cconv)) True }
+
+ -- DEPRECATED variant #8: use of the special identifier `dynamic' without
+ -- an explicit calling convention (export)
+ | 'export' {-no callconv-} 'dynamic' varid '::' sigtype
+ { LL $ ForeignImport $3 $5 (CImport defaultCCallConv (PlaySafe False) nilFS nilFS
+ CWrapper) True }
+
+ -- DEPRECATED variant #9: use of the special identifier `dynamic' (export)
+ | 'export' callconv 'dynamic' varid '::' sigtype
+ {% case $2 of
+ DNCall -> parseError (comb2 $1 $>) "Illegal format of .NET foreign import"
+ CCall cconv -> return $
+ LL $ ForeignImport $4 $6
+ (CImport cconv (PlaySafe False) nilFS nilFS CWrapper) True }
+
+ ----------- DEPRECATED .NET decls ------------
+ -- NB: removed the .NET call declaration, as it is entirely subsumed
+ -- by the new standard FFI declarations
+
+fdecl2DEPRECATED :: { LHsDecl RdrName }
+fdecl2DEPRECATED
+ : 'import' 'dotnet' 'type' ext_name tycon { LL $ TyClD (ForeignType $5 $4 DNType) }
+ -- left this one unchanged for the moment as type imports are not
+ -- covered currently by the FFI standard -=chak
+
+
+callconv :: { CallConv }
+ : 'stdcall' { CCall StdCallConv }
+ | 'ccall' { CCall CCallConv }
+ | 'dotnet' { DNCall }
+
+safety :: { Safety }
+ : 'unsafe' { PlayRisky }
+ | 'safe' { PlaySafe False }
+ | 'threadsafe' { PlaySafe True }
+ | {- empty -} { PlaySafe False }
+
+safety1 :: { Safety }
+ : 'unsafe' { PlayRisky }
+ | 'safe' { PlaySafe False }
+ | 'threadsafe' { PlaySafe True }
+ -- only needed to avoid conflicts with the DEPRECATED rules
+
+fspec :: { 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) }
+ -- if the entity string is missing, it defaults to the empty string;
+ -- the meaning of an empty entity string depends on the calling
+ -- convention
+
+-- DEPRECATED syntax
+ext_name :: { Maybe CLabelString }
+ : STRING { Just (getSTRING $1) }
+ | STRING STRING { Just (getSTRING $2) } -- Ignore "module name" for now
+ | {- empty -} { Nothing }
+
+
+-----------------------------------------------------------------------------
+-- Type signatures
+
+opt_sig :: { Maybe (LHsType RdrName) }
+ : {- empty -} { Nothing }
+ | '::' sigtype { Just $2 }
+
+opt_asig :: { Maybe (LHsType RdrName) }
+ : {- empty -} { Nothing }
+ | '::' atype { Just $2 }
+
+sigtypes1 :: { [LHsType RdrName] }
+ : sigtype { [ $1 ] }
+ | sigtype ',' sigtypes1 { $1 : $3 }
+
+sigtype :: { LHsType RdrName }
+ : ctype { 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
+
+strict_mark :: { Located HsBang }
+ : '!' { L1 HsStrict }
+ | '{-# UNPACK' '#-}' '!' { LL HsUnbox }
+
+-- A ctype is a for-all type
+ctype :: { LHsType RdrName }
+ : 'forall' tv_bndrs '.' ctype { LL $ mkExplicitHsForAllTy $2 (noLoc []) $4 }
+ | context '=>' type { LL $ mkImplicitHsForAllTy $1 $3 }
+ -- A type of form (context => type) is an *implicit* HsForAllTy
+ | type { $1 }
+
+-- We parse a context as a btype so that we don't get reduce/reduce
+-- errors in ctype. The basic problem is that
+-- (Eq a, Ord a)
+-- looks so much like a tuple type. We can't tell until we find the =>
+context :: { LHsContext RdrName }
+ : btype {% checkContext $1 }
+
+type :: { LHsType RdrName }
+ : ipvar '::' gentype { LL (HsPredTy (HsIParam (unLoc $1) $3)) }
+ | gentype { $1 }
+
+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 :: { LHsType RdrName }
+ : btype atype { LL $ HsAppTy $1 $2 }
+ | atype { $1 }
+
+atype :: { LHsType RdrName }
+ : gtycon { L1 (HsTyVar (unLoc $1)) }
+ | tyvar { L1 (HsTyVar (unLoc $1)) }
+ | strict_mark atype { LL (HsBangTy (unLoc $1) $2) }
+ | '(' ctype ',' comma_types1 ')' { LL $ HsTupleTy Boxed ($2:$4) }
+ | '(#' comma_types1 '#)' { LL $ HsTupleTy Unboxed $2 }
+ | '[' ctype ']' { LL $ HsListTy $2 }
+ | '[:' ctype ':]' { LL $ HsPArrTy $2 }
+ | '(' ctype ')' { LL $ HsParTy $2 }
+ | '(' ctype '::' kind ')' { LL $ HsKindSig $2 $4 }
+-- Generics
+ | INTEGER { L1 (HsNumTy (getINTEGER $1)) }
+
+-- An inst_type is what occurs in the head of an instance decl
+-- e.g. (Foo a, Gaz b) => Wibble a b
+-- It's kept as a single type, with a MonoDictTy at the right
+-- hand corner, for convenience.
+inst_type :: { LHsType RdrName }
+ : sigtype {% checkInstType $1 }
+
+inst_types1 :: { [LHsType RdrName] }
+ : inst_type { [$1] }
+ | inst_type ',' inst_types1 { $1 : $3 }
+
+comma_types0 :: { [LHsType RdrName] }
+ : comma_types1 { $1 }
+ | {- empty -} { [] }
+
+comma_types1 :: { [LHsType RdrName] }
+ : ctype { [$1] }
+ | ctype ',' comma_types1 { $1 : $3 }
+
+tv_bndrs :: { [LHsTyVarBndr RdrName] }
+ : tv_bndr tv_bndrs { $1 : $2 }
+ | {- empty -} { [] }
+
+tv_bndr :: { LHsTyVarBndr RdrName }
+ : tyvar { L1 (UserTyVar (unLoc $1)) }
+ | '(' tyvar '::' kind ')' { LL (KindedTyVar (unLoc $2) $4) }
+
+fds :: { Located [Located ([RdrName], [RdrName])] }
+ : {- empty -} { noLoc [] }
+ | '|' fds1 { LL (reverse (unLoc $2)) }
+
+fds1 :: { Located [Located ([RdrName], [RdrName])] }
+ : fds1 ',' fd { LL ($3 : unLoc $1) }
+ | fd { L1 [$1] }
+
+fd :: { Located ([RdrName], [RdrName]) }
+ : varids0 '->' varids0 { L (comb3 $1 $2 $3)
+ (reverse (unLoc $1), reverse (unLoc $3)) }
+
+varids0 :: { Located [RdrName] }
+ : {- empty -} { noLoc [] }
+ | varids0 tyvar { LL (unLoc $2 : unLoc $1) }
+
+-----------------------------------------------------------------------------
+-- Kinds
+
+kind :: { Kind }
+ : akind { $1 }
+ | akind '->' kind { mkArrowKind $1 $3 }
+
+akind :: { Kind }
+ : '*' { liftedTypeKind }
+ | '(' kind ')' { $2 }
+
+
+-----------------------------------------------------------------------------
+-- Datatype declarations
+
+gadt_constrlist :: { Located [LConDecl RdrName] }
+ : '{' gadt_constrs '}' { LL (unLoc $2) }
+ | vocurly gadt_constrs close { $2 }
+
+gadt_constrs :: { Located [LConDecl RdrName] }
+ : gadt_constrs ';' gadt_constr { LL ($3 : unLoc $1) }
+ | gadt_constrs ';' { $1 }
+ | gadt_constr { L1 [$1] }
+
+-- We allow the following forms:
+-- C :: Eq a => a -> T a
+-- C :: forall a. Eq a => !a -> T a
+-- D { x,y :: a } :: T a
+-- forall a. Eq a => D { x,y :: a } :: T a
+
+gadt_constr :: { LConDecl RdrName }
+ : con '::' sigtype
+ { 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
+ | constr_stuff_record '::' sigtype
+ { let (con,details) = unLoc $1 in
+ LL (ConDecl con Implicit [] (noLoc []) details (ResTyGADT $3)) }
+{-
+ | forall context '=>' constr_stuff_record '::' sigtype
+ { let (con,details) = unLoc $4 in
+ LL (ConDecl con Implicit (unLoc $1) $2 details (ResTyGADT $6)) }
+ | forall constr_stuff_record '::' sigtype
+ { let (con,details) = unLoc $2 in
+ LL (ConDecl con Implicit (unLoc $1) (noLoc []) details (ResTyGADT $4)) }
+-}
+
+
+constrs :: { Located [LConDecl RdrName] }
+ : {- empty; a GHC extension -} { noLoc [] }
+ | '=' constrs1 { LL (unLoc $2) }
+
+constrs1 :: { Located [LConDecl RdrName] }
+ : constrs1 '|' constr { LL ($3 : unLoc $1) }
+ | 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) }
+
+forall :: { Located [LHsTyVarBndr RdrName] }
+ : 'forall' tv_bndrs '.' { LL $2 }
+ | {- empty -} { noLoc [] }
+
+constr_stuff :: { Located (Located RdrName, HsConDetails RdrName (LBangType RdrName)) }
+-- We parse the constructor declaration
+-- C t1 t2
+-- as a btype (treating C as a type constructor) and then convert C to be
+-- a data constructor. Reason: it might continue like this:
+-- C t1 t2 %: D Int
+-- in which case C really would be a type constructor. We can't resolve this
+-- ambiguity till we come across the constructor oprerator :% (or not, more usually)
+ : btype {% mkPrefixCon $1 [] >>= return.LL }
+ | oqtycon '{' '}' {% mkRecCon $1 [] >>= return.LL }
+ | 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)) }
+ : 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] }
+
+fielddecl :: { Located ([Located RdrName], LBangType RdrName) }
+ : sig_vars '::' ctype { LL (reverse (unLoc $1), $3) }
+
+-- 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).
+-- The 'C [a]' part is converted to an HsPredTy by checkInstType
+-- We don't allow a context, but that's sorted out by the type checker.
+deriving :: { Located (Maybe [LHsType RdrName]) }
+ : {- empty -} { noLoc Nothing }
+ | 'deriving' qtycon {% do { let { L loc tv = $2 }
+ ; p <- checkInstType (L loc (HsTyVar tv))
+ ; return (LL (Just [p])) } }
+ | 'deriving' '(' ')' { LL (Just []) }
+ | 'deriving' '(' inst_types1 ')' { LL (Just $3) }
+ -- Glasgow extension: allow partial
+ -- applications in derivings
+
+-----------------------------------------------------------------------------
+-- Value definitions
+
+{- There's an awkward overlap with a type signature. Consider
+ f :: Int -> Int = ...rhs...
+ Then we can't tell whether it's a type signature or a value
+ definition with a result signature until we see the '='.
+ So we have to inline enough to postpone reductions until we know.
+-}
+
+{-
+ ATTENTION: Dirty Hackery Ahead! If the second alternative of vars is var
+ instead of qvar, we get another shift/reduce-conflict. Consider the
+ following programs:
+
+ { (^^) :: Int->Int ; } Type signature; only var allowed
+
+ { (^^) :: Int->Int = ... ; } Value defn with result signature;
+ qvar allowed (because of instance decls)
+
+ We can't tell whether to reduce var to qvar until after we've read the signatures.
+-}
+
+decl :: { Located (OrdList (LHsDecl RdrName)) }
+ : sigdecl { $1 }
+ | '!' infixexp rhs {% do { pat <- checkPattern $2;
+ return (LL $ unitOL $ LL $ ValD $
+ PatBind (LL $ BangPat pat) (unLoc $3)
+ placeHolderType placeHolderNames) } }
+ | infixexp opt_sig rhs {% do { r <- checkValDef $1 $2 $3;
+ return (LL $ unitOL (LL $ ValD r)) } }
+
+rhs :: { Located (GRHSs RdrName) }
+ : '=' exp wherebinds { L (comb3 $1 $2 $3) $ GRHSs (unguardedRHS $2) (unLoc $3) }
+ | gdrhs wherebinds { LL $ GRHSs (reverse (unLoc $1)) (unLoc $2) }
+
+gdrhs :: { Located [LGRHS RdrName] }
+ : gdrhs gdrh { LL ($2 : unLoc $1) }
+ | gdrh { L1 [$1] }
+
+gdrh :: { LGRHS RdrName }
+ : '|' quals '=' exp { sL (comb2 $1 $>) $ GRHS (reverse (unLoc $2)) $4 }
+
+sigdecl :: { Located (OrdList (LHsDecl RdrName)) }
+ : infixexp '::' sigtype
+ {% 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
+ { 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)
+ | t <- $4] }
+ | '{-# SPECIALISE_INLINE' activation qvar '::' sigtypes1 '#-}'
+ { LL $ toOL [ LL $ SigD (SpecSig $3 t (mkInlineSpec $2 (getSPEC_INLINE $1)))
+ | t <- $5] }
+ | '{-# SPECIALISE' 'instance' inst_type '#-}'
+ { LL $ unitOL (LL $ SigD (SpecInstSig $3)) }
+
+-----------------------------------------------------------------------------
+-- Expressions
+
+exp :: { LHsExpr RdrName }
+ : infixexp '::' sigtype { LL $ ExprWithTySig $1 $3 }
+ | infixexp '-<' exp { LL $ HsArrApp $1 $3 placeHolderType HsFirstOrderApp True }
+ | infixexp '>-' exp { LL $ HsArrApp $3 $1 placeHolderType HsFirstOrderApp False }
+ | infixexp '-<<' exp { LL $ HsArrApp $1 $3 placeHolderType HsHigherOrderApp True }
+ | infixexp '>>-' exp { LL $ HsArrApp $3 $1 placeHolderType HsHigherOrderApp False}
+ | infixexp { $1 }
+
+infixexp :: { LHsExpr RdrName }
+ : exp10 { $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
+ )])) }
+ | '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 }
+
+ | 'do' stmtlist {% let loc = comb2 $1 $2 in
+ checkDo loc (unLoc $2) >>= \ (stmts,body) ->
+ return (L loc (mkHsDo DoExpr stmts body)) }
+ | 'mdo' stmtlist {% let loc = comb2 $1 $2 in
+ checkDo loc (unLoc $2) >>= \ (stmts,body) ->
+ return (L loc (mkHsDo (MDoExpr noPostTcTable) stmts body)) }
+ | scc_annot exp { LL $ if opt_SccProfilingOn
+ then HsSCC (unLoc $1) $2
+ else HsPar $2 }
+
+ | 'proc' aexp '->' exp
+ {% checkPattern $2 >>= \ p ->
+ return (LL $ HsProc p (LL $ HsCmdTop $4 []
+ placeHolderType undefined)) }
+ -- TODO: is LL right here?
+
+ | '{-# CORE' STRING '#-}' exp { LL $ HsCoreAnn (getSTRING $2) $4 }
+ -- hdaume: core annotation
+ | fexp { $1 }
+
+scc_annot :: { Located FastString }
+ : '_scc_' STRING { LL $ getSTRING $2 }
+ | '{-# SCC' STRING '#-}' { LL $ getSTRING $2 }
+
+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) }}
+ | aexp2 { $1 }
+
+-- Here was the syntax for type applications that I was planning
+-- but there are difficulties (e.g. what order for type args)
+-- so it's not enabled yet.
+-- But this case *is* used for the left hand side of a generic definition,
+-- which is parsed as an expression before being munged into a pattern
+ | qcname '{|' gentype '|}' { LL $ HsApp (sL (getLoc $1) (HsVar (unLoc $1)))
+ (sL (getLoc $3) (HsType $3)) }
+
+aexp2 :: { LHsExpr RdrName }
+ : ipvar { L1 (HsIPVar $! unLoc $1) }
+ | qcname { L1 (HsVar $! unLoc $1) }
+ | literal { L1 (HsLit $! unLoc $1) }
+ | INTEGER { L1 (HsOverLit $! mkHsIntegral (getINTEGER $1)) }
+ | RATIONAL { L1 (HsOverLit $! mkHsFractional (getRATIONAL $1)) }
+ | '(' exp ')' { LL (HsPar $2) }
+ | '(' texp ',' texps ')' { LL $ ExplicitTuple ($2 : reverse $4) Boxed }
+ | '(#' texps '#)' { LL $ ExplicitTuple (reverse $2) Unboxed }
+ | '[' list ']' { LL (unLoc $2) }
+ | '[:' parr ':]' { LL (unLoc $2) }
+ | '(' infixexp qop ')' { LL $ SectionL $2 $3 }
+ | '(' qopm infixexp ')' { LL $ SectionR $2 $3 }
+ | '_' { L1 EWildPat }
+
+ -- MetaHaskell Extension
+ | TH_ID_SPLICE { L1 $ HsSpliceE (mkHsSplice
+ (L1 $ HsVar (mkUnqual varName
+ (getTH_ID_SPLICE $1)))) } -- $x
+ | '$(' exp ')' { LL $ HsSpliceE (mkHsSplice $2) } -- $( exp )
+
+ | TH_VAR_QUOTE qvar { LL $ HsBracket (VarBr (unLoc $2)) }
+ | TH_VAR_QUOTE qcon { LL $ HsBracket (VarBr (unLoc $2)) }
+ | TH_TY_QUOTE tyvar { LL $ HsBracket (VarBr (unLoc $2)) }
+ | TH_TY_QUOTE gtycon { LL $ HsBracket (VarBr (unLoc $2)) }
+ | '[|' 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)) }
+
+ -- arrow notation extension
+ | '(|' aexp2 cmdargs '|)' { LL $ HsArrForm $2 Nothing (reverse $3) }
+
+cmdargs :: { [LHsCmdTop RdrName] }
+ : cmdargs acmd { $2 : $1 }
+ | {- empty -} { [] }
+
+acmd :: { LHsCmdTop RdrName }
+ : aexp2 { L1 $ HsCmdTop $1 [] placeHolderType undefined }
+
+cvtopbody :: { [LHsDecl RdrName] }
+ : '{' cvtopdecls0 '}' { $2 }
+ | vocurly cvtopdecls0 close { $2 }
+
+cvtopdecls0 :: { [LHsDecl RdrName] }
+ : {- empty -} { [] }
+ | cvtopdecls { $1 }
+
+texp :: { LHsExpr RdrName }
+ : exp { $1 }
+ | qopm infixexp { LL $ SectionR $1 $2 }
+ -- The second production is really here only for bang patterns
+ -- but
+
+texps :: { [LHsExpr RdrName] }
+ : texps ',' texp { $3 : $1 }
+ | texp { [$1] }
+
+
+-----------------------------------------------------------------------------
+-- List expressions
+
+-- The rules below are little bit contorted to keep lexps left-recursive while
+-- avoiding another shift/reduce-conflict.
+
+list :: { LHsExpr RdrName }
+ : texp { L1 $ ExplicitList placeHolderType [$1] }
+ | lexps { L1 $ ExplicitList placeHolderType (reverse (unLoc $1)) }
+ | texp '..' { LL $ ArithSeq noPostTcExpr (From $1) }
+ | texp ',' exp '..' { LL $ ArithSeq noPostTcExpr (FromThen $1 $3) }
+ | texp '..' exp { LL $ ArithSeq noPostTcExpr (FromTo $1 $3) }
+ | texp ',' exp '..' exp { LL $ ArithSeq noPostTcExpr (FromThenTo $1 $3 $5) }
+ | texp pquals { sL (comb2 $1 $>) $ mkHsDo ListComp (reverse (unLoc $2)) $1 }
+
+lexps :: { Located [LHsExpr RdrName] }
+ : lexps ',' texp { LL ($3 : unLoc $1) }
+ | texp ',' texp { LL [$3,$1] }
+
+-----------------------------------------------------------------------------
+-- List Comprehensions
+
+pquals :: { Located [LStmt RdrName] } -- Either a singleton ParStmt,
+ -- or a reversed list of Stmts
+ : pquals1 { case unLoc $1 of
+ [qs] -> L1 qs
+ qss -> L1 [L1 (ParStmt stmtss)]
+ where
+ stmtss = [ (reverse qs, undefined)
+ | qs <- qss ]
+ }
+
+pquals1 :: { Located [[LStmt RdrName]] }
+ : pquals1 '|' quals { LL (unLoc $3 : unLoc $1) }
+ | '|' quals { L (getLoc $2) [unLoc $2] }
+
+quals :: { Located [LStmt RdrName] }
+ : quals ',' qual { LL ($3 : unLoc $1) }
+ | qual { L1 [$1] }
+
+-----------------------------------------------------------------------------
+-- Parallel array expressions
+
+-- The rules below are little bit contorted; see the list case for details.
+-- Note that, in contrast to lists, we only have finite arithmetic sequences.
+-- Moreover, we allow explicit arrays with no element (represented by the nil
+-- constructor in the list case).
+
+parr :: { LHsExpr RdrName }
+ : { noLoc (ExplicitPArr placeHolderType []) }
+ | exp { 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 }
+
+-- We are reusing `lexps' and `pquals' from the list case.
+
+-----------------------------------------------------------------------------
+-- Case alternatives
+
+altslist :: { Located [LMatch RdrName] }
+ : '{' alts '}' { LL (reverse (unLoc $2)) }
+ | vocurly alts close { L (getLoc $2) (reverse (unLoc $2)) }
+
+alts :: { Located [LMatch RdrName] }
+ : alts1 { L1 (unLoc $1) }
+ | ';' alts { LL (unLoc $2) }
+
+alts1 :: { Located [LMatch RdrName] }
+ : alts1 ';' alt { LL ($3 : unLoc $1) }
+ | alts1 ';' { LL (unLoc $1) }
+ | alt { L1 [$1] }
+
+alt :: { LMatch RdrName }
+ : infixexp opt_sig alt_rhs {% checkPattern $1 >>= \p ->
+ return (LL (Match [p] $2 (unLoc $3))) }
+
+alt_rhs :: { Located (GRHSs RdrName) }
+ : ralt wherebinds { LL (GRHSs (unLoc $1) (unLoc $2)) }
+
+ralt :: { Located [LGRHS RdrName] }
+ : '->' exp { LL (unguardedRHS $2) }
+ | gdpats { L1 (reverse (unLoc $1)) }
+
+gdpats :: { Located [LGRHS RdrName] }
+ : gdpats gdpat { LL ($2 : unLoc $1) }
+ | gdpat { L1 [$1] }
+
+gdpat :: { LGRHS RdrName }
+ : '|' quals '->' exp { sL (comb2 $1 $>) $ GRHS (reverse (unLoc $2)) $4 }
+
+-----------------------------------------------------------------------------
+-- Statement sequences
+
+stmtlist :: { Located [LStmt RdrName] }
+ : '{' stmts '}' { LL (unLoc $2) }
+ | vocurly stmts close { $2 }
+
+-- do { ;; s ; s ; ; s ;; }
+-- The last Stmt should be an expression, but that's hard to enforce
+-- here, because we need too much lookahead if we see do { e ; }
+-- So we use ExprStmts throughout, and switch the last one over
+-- in ParseUtils.checkDo instead
+stmts :: { Located [LStmt RdrName] }
+ : stmt stmts_help { LL ($1 : unLoc $2) }
+ | ';' stmts { LL (unLoc $2) }
+ | {- empty -} { noLoc [] }
+
+stmts_help :: { Located [LStmt RdrName] } -- might be empty
+ : ';' stmts { LL (unLoc $2) }
+ | {- empty -} { noLoc [] }
+
+-- For typing stmts at the GHCi prompt, where
+-- the input may consist of just comments.
+maybe_stmt :: { Maybe (LStmt RdrName) }
+ : stmt { Just $1 }
+ | {- nothing -} { Nothing }
+
+stmt :: { LStmt RdrName }
+ : qual { $1 }
+ | 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) }
+ | exp { L1 $ mkExprStmt $1 }
+ | 'let' binds { LL $ LetStmt (unLoc $2) }
+
+-----------------------------------------------------------------------------
+-- Record Field Update/Construction
+
+fbinds :: { HsRecordBinds RdrName }
+ : fbinds1 { $1 }
+ | {- empty -} { [] }
+
+fbinds1 :: { HsRecordBinds RdrName }
+ : fbinds1 ',' fbind { $3 : $1 }
+ | fbind { [$1] }
+
+fbind :: { (Located RdrName, LHsExpr RdrName) }
+ : qvar '=' exp { ($1,$3) }
+
+-----------------------------------------------------------------------------
+-- Implicit Parameter Bindings
+
+dbinds :: { Located [LIPBind RdrName] }
+ : dbinds ';' dbind { LL ($3 : unLoc $1) }
+ | dbinds ';' { LL (unLoc $1) }
+ | dbind { L1 [$1] }
+-- | {- empty -} { [] }
+
+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))) }
+
+-----------------------------------------------------------------------------
+-- Deprecations
+
+depreclist :: { Located [RdrName] }
+depreclist : deprec_var { L1 [unLoc $1] }
+ | deprec_var ',' depreclist { LL (unLoc $1 : unLoc $3) }
+
+deprec_var :: { Located RdrName }
+deprec_var : var { $1 }
+ | con { $1 }
+
+-----------------------------------------
+-- Data constructors
+qcon :: { Located RdrName }
+ : qconid { $1 }
+ | '(' qconsym ')' { LL (unLoc $2) }
+ | sysdcon { L1 $ nameRdrName (dataConName (unLoc $1)) }
+-- The case of '[:' ':]' is part of the production `parr'
+
+con :: { Located RdrName }
+ : conid { $1 }
+ | '(' consym ')' { LL (unLoc $2) }
+ | sysdcon { L1 $ nameRdrName (dataConName (unLoc $1)) }
+
+sysdcon :: { Located DataCon } -- Wired in data constructors
+ : '(' ')' { LL unitDataCon }
+ | '(' commas ')' { LL $ tupleCon Boxed $2 }
+ | '[' ']' { LL nilDataCon }
+
+conop :: { Located RdrName }
+ : consym { $1 }
+ | '`' conid '`' { LL (unLoc $2) }
+
+qconop :: { Located RdrName }
+ : qconsym { $1 }
+ | '`' qconid '`' { LL (unLoc $2) }
+
+-----------------------------------------------------------------------------
+-- Type constructors
+
+gtycon :: { Located RdrName } -- A "general" qualified tycon
+ : oqtycon { $1 }
+ | '(' ')' { LL $ getRdrName unitTyCon }
+ | '(' commas ')' { LL $ getRdrName (tupleTyCon Boxed $2) }
+ | '(' '->' ')' { LL $ getRdrName funTyCon }
+ | '[' ']' { LL $ listTyCon_RDR }
+ | '[:' ':]' { LL $ parrTyCon_RDR }
+
+oqtycon :: { Located RdrName } -- An "ordinary" qualified tycon
+ : qtycon { $1 }
+ | '(' qtyconsym ')' { LL (unLoc $2) }
+
+qtyconop :: { Located RdrName } -- Qualified or unqualified
+ : qtyconsym { $1 }
+ | '`' qtycon '`' { LL (unLoc $2) }
+
+qtycon :: { Located RdrName } -- Qualified or unqualified
+ : QCONID { L1 $! mkQual tcClsName (getQCONID $1) }
+ | tycon { $1 }
+
+tycon :: { Located RdrName } -- Unqualified
+ : CONID { L1 $! mkUnqual tcClsName (getCONID $1) }
+
+qtyconsym :: { Located RdrName }
+ : QCONSYM { L1 $! mkQual tcClsName (getQCONSYM $1) }
+ | tyconsym { $1 }
+
+tyconsym :: { Located RdrName }
+ : CONSYM { L1 $! mkUnqual tcClsName (getCONSYM $1) }
+
+-----------------------------------------------------------------------------
+-- Operators
+
+op :: { Located RdrName } -- used in infix decls
+ : varop { $1 }
+ | conop { $1 }
+
+varop :: { Located RdrName }
+ : varsym { $1 }
+ | '`' varid '`' { LL (unLoc $2) }
+
+qop :: { LHsExpr RdrName } -- used in sections
+ : qvarop { L1 $ HsVar (unLoc $1) }
+ | qconop { L1 $ HsVar (unLoc $1) }
+
+qopm :: { LHsExpr RdrName } -- used in sections
+ : qvaropm { L1 $ HsVar (unLoc $1) }
+ | qconop { L1 $ HsVar (unLoc $1) }
+
+qvarop :: { Located RdrName }
+ : qvarsym { $1 }
+ | '`' qvarid '`' { LL (unLoc $2) }
+
+qvaropm :: { Located RdrName }
+ : qvarsym_no_minus { $1 }
+ | '`' qvarid '`' { LL (unLoc $2) }
+
+-----------------------------------------------------------------------------
+-- Type variables
+
+tyvar :: { Located RdrName }
+tyvar : tyvarid { $1 }
+ | '(' tyvarsym ')' { LL (unLoc $2) }
+
+tyvarop :: { Located RdrName }
+tyvarop : '`' tyvarid '`' { LL (unLoc $2) }
+ | tyvarsym { $1 }
+
+tyvarid :: { Located RdrName }
+ : VARID { L1 $! mkUnqual tvName (getVARID $1) }
+ | special_id { L1 $! mkUnqual tvName (unLoc $1) }
+ | 'unsafe' { L1 $! mkUnqual tvName FSLIT("unsafe") }
+ | 'safe' { L1 $! mkUnqual tvName FSLIT("safe") }
+ | 'threadsafe' { L1 $! mkUnqual tvName FSLIT("threadsafe") }
+
+tyvarsym :: { Located RdrName }
+-- Does not include "!", because that is used for strictness marks
+-- or ".", because that separates the quantified type vars from the rest
+-- or "*", because that's used for kinds
+tyvarsym : VARSYM { L1 $! mkUnqual tvName (getVARSYM $1) }
+
+-----------------------------------------------------------------------------
+-- Variables
+
+var :: { Located RdrName }
+ : varid { $1 }
+ | '(' varsym ')' { LL (unLoc $2) }
+
+qvar :: { Located RdrName }
+ : qvarid { $1 }
+ | '(' varsym ')' { LL (unLoc $2) }
+ | '(' qvarsym1 ')' { LL (unLoc $2) }
+-- We've inlined qvarsym here so that the decision about
+-- whether it's a qvar or a var can be postponed until
+-- *after* we see the close paren.
+
+qvarid :: { Located RdrName }
+ : varid { $1 }
+ | QVARID { L1 $ mkQual varName (getQVARID $1) }
+
+varid :: { Located RdrName }
+ : varid_no_unsafe { $1 }
+ | 'unsafe' { L1 $! mkUnqual varName FSLIT("unsafe") }
+ | 'safe' { L1 $! mkUnqual varName FSLIT("safe") }
+ | 'threadsafe' { L1 $! mkUnqual varName FSLIT("threadsafe") }
+
+varid_no_unsafe :: { Located RdrName }
+ : VARID { L1 $! mkUnqual varName (getVARID $1) }
+ | special_id { L1 $! mkUnqual varName (unLoc $1) }
+ | 'forall' { L1 $! mkUnqual varName FSLIT("forall") }
+
+qvarsym :: { Located RdrName }
+ : varsym { $1 }
+ | qvarsym1 { $1 }
+
+qvarsym_no_minus :: { Located RdrName }
+ : varsym_no_minus { $1 }
+ | qvarsym1 { $1 }
+
+qvarsym1 :: { Located RdrName }
+qvarsym1 : QVARSYM { L1 $ mkQual varName (getQVARSYM $1) }
+
+varsym :: { Located RdrName }
+ : varsym_no_minus { $1 }
+ | '-' { L1 $ mkUnqual varName FSLIT("-") }
+
+varsym_no_minus :: { Located RdrName } -- varsym not including '-'
+ : VARSYM { L1 $ mkUnqual varName (getVARSYM $1) }
+ | special_sym { L1 $ mkUnqual varName (unLoc $1) }
+
+
+-- 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
+special_id :: { Located FastString }
+special_id
+ : 'as' { L1 FSLIT("as") }
+ | 'qualified' { L1 FSLIT("qualified") }
+ | 'hiding' { L1 FSLIT("hiding") }
+ | 'export' { L1 FSLIT("export") }
+ | 'label' { L1 FSLIT("label") }
+ | 'dynamic' { L1 FSLIT("dynamic") }
+ | 'stdcall' { L1 FSLIT("stdcall") }
+ | 'ccall' { L1 FSLIT("ccall") }
+
+special_sym :: { Located FastString }
+special_sym : '!' { L1 FSLIT("!") }
+ | '.' { L1 FSLIT(".") }
+ | '*' { L1 FSLIT("*") }
+
+-----------------------------------------------------------------------------
+-- Data constructors
+
+qconid :: { Located RdrName } -- Qualified or unqualified
+ : conid { $1 }
+ | QCONID { L1 $ mkQual dataName (getQCONID $1) }
+
+conid :: { Located RdrName }
+ : CONID { L1 $ mkUnqual dataName (getCONID $1) }
+
+qconsym :: { Located RdrName } -- Qualified or unqualified
+ : consym { $1 }
+ | QCONSYM { L1 $ mkQual dataName (getQCONSYM $1) }
+
+consym :: { Located RdrName }
+ : CONSYM { L1 $ mkUnqual dataName (getCONSYM $1) }
+
+ -- ':' means only list cons
+ | ':' { L1 $ consDataCon_RDR }
+
+
+-----------------------------------------------------------------------------
+-- Literals
+
+literal :: { Located HsLit }
+ : CHAR { L1 $ HsChar $ getCHAR $1 }
+ | STRING { L1 $ HsString $ getSTRING $1 }
+ | PRIMINTEGER { L1 $ HsIntPrim $ getPRIMINTEGER $1 }
+ | PRIMCHAR { L1 $ HsCharPrim $ getPRIMCHAR $1 }
+ | PRIMSTRING { L1 $ HsStringPrim $ getPRIMSTRING $1 }
+ | PRIMFLOAT { L1 $ HsFloatPrim $ getPRIMFLOAT $1 }
+ | PRIMDOUBLE { L1 $ HsDoublePrim $ getPRIMDOUBLE $1 }
+
+-----------------------------------------------------------------------------
+-- Layout
+
+close :: { () }
+ : vccurly { () } -- context popped in lexer.
+ | error {% popContext }
+
+-----------------------------------------------------------------------------
+-- Miscellaneous (mostly renamings)
+
+modid :: { Located Module }
+ : CONID { L1 $ mkModuleFS (getCONID $1) }
+ | QCONID { L1 $ let (mod,c) = getQCONID $1 in
+ mkModuleFS
+ (mkFastString
+ (unpackFS mod ++ '.':unpackFS c))
+ }
+
+commas :: { Int }
+ : commas ',' { $1 + 1 }
+ | ',' { 2 }
+
+-----------------------------------------------------------------------------
+
+{
+happyError :: P a
+happyError = srcParseFail
+
+getVARID (L _ (ITvarid x)) = x
+getCONID (L _ (ITconid x)) = x
+getVARSYM (L _ (ITvarsym x)) = x
+getCONSYM (L _ (ITconsym x)) = x
+getQVARID (L _ (ITqvarid x)) = x
+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
+getRATIONAL (L _ (ITrational x)) = x
+getPRIMCHAR (L _ (ITprimchar x)) = x
+getPRIMSTRING (L _ (ITprimstring x)) = x
+getPRIMINTEGER (L _ (ITprimint x)) = x
+getPRIMFLOAT (L _ (ITprimfloat x)) = x
+getPRIMDOUBLE (L _ (ITprimdouble x)) = x
+getTH_ID_SPLICE (L _ (ITidEscape x)) = x
+getINLINE (L _ (ITinline_prag b)) = b
+getSPEC_INLINE (L _ (ITspec_inline_prag b)) = b
+
+-- Utilities for combining source spans
+comb2 :: Located a -> Located b -> SrcSpan
+comb2 = combineLocs
+
+comb3 :: Located a -> Located b -> Located c -> SrcSpan
+comb3 a b c = combineSrcSpans (getLoc a) (combineSrcSpans (getLoc b) (getLoc c))
+
+comb4 :: Located a -> Located b -> Located c -> Located d -> SrcSpan
+comb4 a b c d = combineSrcSpans (getLoc a) $ combineSrcSpans (getLoc b) $
+ combineSrcSpans (getLoc c) (getLoc d)
+
+-- strict constructor version:
+{-# INLINE sL #-}
+sL :: SrcSpan -> a -> Located a
+sL span a = span `seq` L span a
+
+-- Make a source location for the file. We're a bit lazy here and just
+-- make a point SrcSpan at line 1, column 0. Strictly speaking we should
+-- try to find the span of the whole file (ToDo).
+fileSrcSpan :: P SrcSpan
+fileSrcSpan = do
+ l <- getSrcLoc;
+ let loc = mkSrcLoc (srcLocFile l) 1 0;
+ return (mkSrcSpan loc loc)
+}