X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Fparser%2FParser.y;h=a1f02831e0da73da2da25b21abf3817c9b94479f;hb=111cee3f1ad93816cb828e38b38521d85c3bcebb;hp=606181bcf611c53aa3f9783d2cb8516084481624;hpb=f4517c17523143b3ac4a99a5853c0a0a164b1f71;p=ghc-hetmet.git diff --git a/ghc/compiler/parser/Parser.y b/ghc/compiler/parser/Parser.y index 606181b..a1f0283 100644 --- a/ghc/compiler/parser/Parser.y +++ b/ghc/compiler/parser/Parser.y @@ -1,6 +1,6 @@ {- ----------------------------------------------------------------------------- -$Id: Parser.y,v 1.11 1999/07/26 16:06:28 simonpj Exp $ +$Id: Parser.y,v 1.28 2000/03/23 17:45:22 simonpj Exp $ Haskell grammar. @@ -19,7 +19,7 @@ import Lex import ParseUtil import RdrName import PrelMods ( mAIN_Name ) -import OccName ( varName, dataName, tcClsName, tvName ) +import OccName ( varName, ipName, dataName, tcClsName, tvName ) import SrcLoc ( SrcLoc ) import Module import CallConv @@ -28,6 +28,7 @@ import BasicTypes ( Fixity(..), FixityDirection(..), NewOrData(..) ) import Panic import GlaExts +import FastString ( tailFS ) #include "HsVersions.h" } @@ -35,6 +36,7 @@ import GlaExts {- ----------------------------------------------------------------------------- Conflicts: 14 shift/reduce + (note: it's currently 21 -- JRL, 31/1/2000) 8 for abiguity in 'if x then y else z + 1' (shift parses as 'if x then y else (z + 1)', as per longest-parse rule) @@ -93,6 +95,9 @@ Conflicts: 14 shift/reduce 'label' { ITlabel } 'dynamic' { ITdynamic } 'unsafe' { ITunsafe } + 'with' { ITwith } + 'stdcall' { ITstdcallconv } + 'ccall' { ITccallconv } '_ccall_' { ITccall (False, False, False) } '_ccall_GC_' { ITccall (False, False, True) } '_casm_' { ITccall (False, True, False) } @@ -103,6 +108,7 @@ Conflicts: 14 shift/reduce '{-# INLINE' { ITinline_prag } '{-# NOINLINE' { ITnoinline_prag } '{-# RULES' { ITrules_prag } + '{-# DEPRECATED' { ITdeprecated_prag } '#-}' { ITclose_prag } {- @@ -172,6 +178,8 @@ Conflicts: 14 shift/reduce QVARSYM { ITqvarsym $$ } QCONSYM { ITqconsym $$ } + IPVARID { ITipvarid $$ } -- GHC extension + PRAGMA { ITpragma $$ } CHAR { ITchar $$ } @@ -183,7 +191,7 @@ Conflicts: 14 shift/reduce PRIMSTRING { ITprimstring $$ } PRIMINTEGER { ITprimint $$ } PRIMFLOAT { ITprimfloat $$ } - PRIMDOUBLE { ITprimdouble $$ } + PRIMDOUBLE { ITprimdouble $$ } CLITLIT { ITlitlit $$ } UNKNOWN { ITunknown $$ } @@ -197,11 +205,22 @@ Conflicts: 14 shift/reduce ----------------------------------------------------------------------------- -- 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 :: { RdrNameHsModule } - : srcloc 'module' modid maybeexports 'where' body - { HsModule $3 Nothing $4 (fst $6) (snd $6) $1 } - | srcloc body - { HsModule mAIN_Name Nothing Nothing (fst $2) (snd $2) $1 } + : srcloc 'module' modid maybemoddeprec maybeexports 'where' body + { HsModule $3 Nothing $5 (fst $7) (snd $7) $4 $1 } + | srcloc body + { HsModule mAIN_Name Nothing Nothing (fst $2) (snd $2) Nothing $1 } + +maybemoddeprec :: { Maybe DeprecTxt } + : '{-# DEPRECATED' STRING '#-}' { Just $2 } + | {- empty -} { Nothing } body :: { ([RdrNameImportDecl], [RdrNameHsDecl]) } : '{' top '}' { $2 } @@ -322,14 +341,14 @@ topdecl :: { RdrBinding } (TyData NewType cs c ts [$5] $6 NoDataPragmas $1))) } - | srcloc 'class' ctype where + | srcloc 'class' ctype fds where {% checkDataHeader $3 `thenP` \(cs,c,ts) -> let (binds,sigs) = cvMonoBindsAndSigs cvClassOpSig - (groupBindings $4) + (groupBindings $5) in returnP (RdrHsDecl (TyClD - (mkClassDecl cs c ts sigs binds + (mkClassDecl cs c ts $4 sigs binds NoClassPragmas $1))) } | srcloc 'instance' inst_type where @@ -344,13 +363,13 @@ topdecl :: { RdrBinding } | srcloc 'foreign' 'import' callconv ext_name unsafe_flag varid_no_unsafe '::' sigtype - { RdrHsDecl (ForD (ForeignDecl $7 (FoImport $6) $9 $5 $4 $1)) } + { RdrHsDecl (ForD (ForeignDecl $7 (FoImport $6) $9 (mkExtName $5 $7) $4 $1)) } | srcloc 'foreign' 'export' callconv ext_name varid '::' sigtype - { RdrHsDecl (ForD (ForeignDecl $6 FoExport $8 $5 $4 $1)) } + { RdrHsDecl (ForD (ForeignDecl $6 FoExport $8 (mkExtName $5 $6) $4 $1)) } | srcloc 'foreign' 'label' ext_name varid '::' sigtype - { RdrHsDecl (ForD (ForeignDecl $5 FoLabel $7 $4 + { RdrHsDecl (ForD (ForeignDecl $5 FoLabel $7 (mkExtName $4 $5) defaultCallConv $1)) } | decl { $1 } @@ -362,17 +381,21 @@ decls :: { [RdrBinding] } | {- empty -} { [] } decl :: { RdrBinding } - : signdecl { $1 } - | fixdecl { $1 } - | valdef { RdrValBinding $1 } - | '{-# INLINE' srcloc qvar '#-}' { RdrSig (InlineSig $3 $2) } - | '{-# NOINLINE' srcloc qvar '#-}' { RdrSig (NoInlineSig $3 $2) } + : fixdecl { $1 } + | valdef { $1 } + | '{-# INLINE' srcloc opt_phase qvar '#-}' { RdrSig (InlineSig $4 $3 $2) } + | '{-# NOINLINE' srcloc opt_phase qvar '#-}' { RdrSig (NoInlineSig $4 $3 $2) } | '{-# SPECIALISE' srcloc qvar '::' sigtypes '#-}' { foldr1 RdrAndBindings (map (\t -> RdrSig (SpecSig $3 t $2)) $5) } | '{-# SPECIALISE' srcloc 'instance' inst_type '#-}' { RdrSig (SpecInstSig $4 $2) } | '{-# RULES' rules '#-}' { $2 } + | '{-# DEPRECATED' deprecations '#-}' { $2 } + +opt_phase :: { Maybe Int } + : INTEGER { Just (fromInteger $1) } + | {- empty -} { Nothing } sigtypes :: { [RdrNameHsType] } : sigtype { [ $1 ] } @@ -398,31 +421,12 @@ fixdecl :: { RdrBinding } (Fixity $3 $2) $1)) | n <- $4 ] } -signdecl :: { RdrBinding } - : vars srcloc '::' sigtype { foldr1 RdrAndBindings - [ RdrSig (Sig n $4 $2) | n <- $1 ] } - sigtype :: { RdrNameHsType } - : ctype { case $1 of - HsForAllTy _ _ _ -> $1 - other -> HsForAllTy Nothing [] $1 } - -{- - 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: - - { (+) :: ... } only var - { (+) x y = ... } could (incorrectly) be qvar - - We re-use expressions for patterns, so a qvar would be allowed in patterns - instead of a var only (which would be correct). But deciding what the + is, - would require more lookahead. So let's check for ourselves... --} + : ctype { mkHsForAllTy Nothing [] $1 } -vars :: { [RdrName] } - : vars ',' var { $3 : $1 } - | qvar { [ $1 ] } +sig_vars :: { [RdrName] } + : sig_vars ',' var { $3 : $1 } + | var { [ $1 ] } ----------------------------------------------------------------------------- -- Transformation Rules @@ -443,35 +447,57 @@ rule_forall :: { [RdrNameRuleBndr] } rule_var_list :: { [RdrNameRuleBndr] } : rule_var { [$1] } - | rule_var ',' rule_var_list { $1 : $3 } + | rule_var rule_var_list { $1 : $2 } rule_var :: { RdrNameRuleBndr } : varid { RuleBndr $1 } - | varid '::' ctype { RuleBndrSig $1 $3 } + | '(' varid '::' ctype ')' { RuleBndrSig $2 $4 } + +----------------------------------------------------------------------------- +-- Deprecations + +deprecations :: { RdrBinding } + : deprecations ';' deprecation { $1 `RdrAndBindings` $3 } + | deprecations ';' { $1 } + | deprecation { $1 } + | {- empty -} { RdrNullBind } + +-- SUP: TEMPORARY HACK, not checking for `module Foo' +deprecation :: { RdrBinding } + : srcloc exportlist STRING + { foldr1 RdrAndBindings [ RdrSig (DeprecSig (Deprecation n $3) $1) | n <- $2 ] } ----------------------------------------------------------------------------- -- Foreign import/export callconv :: { Int } - : VARID {% checkCallConv $1 } + : 'stdcall' { stdCallConv } + | 'ccall' { cCallConv } | {- empty -} { defaultCallConv } unsafe_flag :: { Bool } : 'unsafe' { True } | {- empty -} { False } -ext_name :: { ExtName } - : 'dynamic' { Dynamic } - | STRING { ExtName $1 Nothing } - | STRING STRING { ExtName $2 (Just $1) } +ext_name :: { Maybe ExtName } + : 'dynamic' { Just Dynamic } + | STRING { Just (ExtName $1 Nothing) } + | STRING STRING { Just (ExtName $2 (Just $1)) } + | {- empty -} { Nothing } ----------------------------------------------------------------------------- -- Types -{- ToDo: forall stuff -} +-- A ctype is a for-all type +ctype :: { RdrNameHsType } + : 'forall' tyvars '.' ctype { mkHsForAllTy (Just $2) [] $4 } + | context type { mkHsForAllTy Nothing $1 $2 } + -- A type of form (context => type) is an *implicit* HsForAllTy + | type { $1 } type :: { RdrNameHsType } : btype '->' type { MonoFunTy $1 $3 } + | ipvar '::' type { MonoIParamTy $1 $3 } | btype { $1 } btype :: { RdrNameHsType } @@ -500,13 +526,6 @@ gtycon :: { RdrName } inst_type :: { RdrNameHsType } : ctype {% checkInstType $1 } -ctype :: { RdrNameHsType } - : 'forall' tyvars '.' context type - { HsForAllTy (Just $2) $4 $5 } - | 'forall' tyvars '.' type { HsForAllTy (Just $2) [] $4 } - | context type { HsForAllTy Nothing $1 $2 } - | type { $1 } - types0 :: { [RdrNameHsType] } : types { $1 } | {- empty -} { [] } @@ -522,6 +541,21 @@ tyvars :: { [RdrNameHsTyVar] } : tyvars tyvar { UserTyVar $2 : $1 } | {- empty -} { [] } +fds :: { [([RdrName], [RdrName])] } + : {- empty -} { [] } + | '|' fds1 { reverse $2 } + +fds1 :: { [([RdrName], [RdrName])] } + : fds1 ',' fd { $3 : $1 } + | fd { [$1] } + +fd :: { ([RdrName], [RdrName]) } + : varids0 '->' varids0 { (reverse $1, reverse $3) } + +varids0 :: { [RdrName] } + : {- empty -} { [] } + | varids0 tyvar { $2 : $1 } + ----------------------------------------------------------------------------- -- Datatype declarations @@ -531,9 +565,9 @@ constrs :: { [RdrNameConDecl] } constr :: { RdrNameConDecl } : srcloc forall context constr_stuff - { ConDecl (fst $4) $2 $3 (snd $4) $1 } + { mkConDecl (fst $4) $2 $3 (snd $4) $1 } | srcloc forall constr_stuff - { ConDecl (fst $3) $2 [] (snd $3) $1 } + { mkConDecl (fst $3) $2 [] (snd $3) $1 } forall :: { [RdrNameHsTyVar] } : 'forall' tyvars '.' { $2 } @@ -548,9 +582,9 @@ constr_stuff :: { (RdrName, RdrNameConDetails) } | con '{' fielddecls '}' { ($1, RecCon (reverse $3)) } newconstr :: { RdrNameConDecl } - : srcloc conid atype { ConDecl $2 [] [] (NewCon $3 Nothing) $1 } + : srcloc conid atype { mkConDecl $2 [] [] (NewCon $3 Nothing) $1 } | srcloc conid '{' var '::' type '}' - { ConDecl $2 [] [] (NewCon $6 (Just $4)) $1 } + { mkConDecl $2 [] [] (NewCon $6 (Just $4)) $1 } scontype :: { (RdrName, [RdrNameBangType]) } : btype {% splitForConApp $1 [] } @@ -573,10 +607,10 @@ fielddecls :: { [([RdrName],RdrNameBangType)] } | fielddecl { [$1] } fielddecl :: { ([RdrName],RdrNameBangType) } - : vars '::' stype { (reverse $1, $3) } + : sig_vars '::' stype { (reverse $1, $3) } stype :: { RdrNameBangType } - : type { Unbanged $1 } + : ctype { Unbanged $1 } | '!' atype { Banged $2 } deriving :: { Maybe [RdrName] } @@ -592,9 +626,32 @@ dclasses :: { [RdrName] } ----------------------------------------------------------------------------- -- Value definitions -valdef :: { RdrNameMonoBinds } - : infixexp {-ToDo: opt_sig-} srcloc rhs - {% checkValDef $1 Nothing $3 $2 } +{- 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. +-} + +valdef :: { RdrBinding } + : infixexp srcloc opt_sig rhs {% checkValDef $1 $3 $4 $2 } + | infixexp srcloc '::' sigtype {% checkValSig $1 $4 $2 } + | var ',' sig_vars srcloc '::' sigtype { foldr1 RdrAndBindings + [ RdrSig (Sig n $6 $4) | n <- $1:$3 ] + } rhs :: { RdrNameGRHSs } : '=' srcloc exp wherebinds { GRHSs (unguardedRHS $3 $2) @@ -606,14 +663,14 @@ gdrhs :: { [RdrNameGRHS] } | gdrh { [$1] } gdrh :: { RdrNameGRHS } - : '|' srcloc quals '=' exp { GRHS (reverse - (ExprStmt $5 $2 : $3)) $2 } + : '|' srcloc quals '=' exp { GRHS (reverse (ExprStmt $5 $2 : $3)) $2 } ----------------------------------------------------------------------------- -- Expressions exp :: { RdrNameHsExpr } : infixexp '::' sigtype { ExprWithTySig $1 $3 } + | infixexp 'with' dbinding { HsWith $1 $3 } | infixexp { $1 } infixexp :: { RdrNameHsExpr } @@ -632,10 +689,10 @@ exp10 :: { RdrNameHsExpr } | '-' fexp { NegApp $2 (error "NegApp") } | srcloc 'do' stmtlist { HsDo DoStmt $3 $1 } - | '_ccall_' ccallid aexps0 { CCall $2 $3 False False cbot } - | '_ccall_GC_' ccallid aexps0 { CCall $2 $3 True False cbot } - | '_casm_' CLITLIT aexps0 { CCall $2 $3 False True cbot } - | '_casm_GC_' CLITLIT aexps0 { CCall $2 $3 True True cbot } + | '_ccall_' ccallid aexps0 { HsCCall $2 $3 False False cbot } + | '_ccall_GC_' ccallid aexps0 { HsCCall $2 $3 True False cbot } + | '_casm_' CLITLIT aexps0 { HsCCall $2 $3 False True cbot } + | '_casm_GC_' CLITLIT aexps0 { HsCCall $2 $3 True True cbot } | '_scc_' STRING exp { if opt_SccProfilingOn then HsSCC $2 $3 @@ -664,6 +721,7 @@ aexp :: { RdrNameHsExpr } aexp1 :: { RdrNameHsExpr } : qvar { HsVar $1 } + | ipvar { HsIPVar $1 } | gcon { HsVar $1 } | literal { HsLit $1 } | '(' exp ')' { HsPar $2 } @@ -724,12 +782,14 @@ altslist :: { [RdrNameMatch] } : '{' alts '}' { reverse $2 } | layout_on alts close { reverse $2 } +alts :: { [RdrNameMatch] } + : alts1 { $1 } + | ';' alts { $2 } -alts :: { [RdrNameMatch] } - : alts ';' alt { $3 : $1 } - | alts ';' { $1 } +alts1 :: { [RdrNameMatch] } + : alts1 ';' alt { $3 : $1 } + | alts1 ';' { $1 } | alt { [$1] } - | {- empty -} { [] } alt :: { RdrNameMatch } : infixexp opt_sig ralt wherebinds @@ -739,7 +799,7 @@ alt :: { RdrNameMatch } opt_sig :: { Maybe RdrNameHsType } : {- empty -} { Nothing } - | '::' type { Just $2 } + | '::' sigtype { Just $2 } opt_asig :: { Maybe RdrNameHsType } : {- empty -} { Nothing } @@ -760,20 +820,21 @@ gdpat :: { RdrNameGRHS } -- Statement sequences stmtlist :: { [RdrNameStmt] } - : '{' stmts '}' { $2 } - | layout_on_for_do stmts close { $2 } + : '{' stmts '}' { reverse $2 } + | layout_on_for_do stmts close { reverse $2 } + +-- Stmt list should really end in an expression, but it's not +-- convenient to enforce this here, so we throw out erroneous +-- statement sequences in the renamer instead. --- Stmt list must end in an expression --- thought the H98 report doesn't currently say so in the syntax stmts :: { [RdrNameStmt] } - : stmts1 srcloc exp { reverse (ExprStmt $3 $2 : $1) } + : ';' stmts1 { $2 } + | stmts1 { $1 } --- A list of zero or more stmts, ending in semicolon --- Returned in *reverse* order stmts1 :: { [RdrNameStmt] } - : stmts1 stmt ';' { $2 : $1 } - | stmts1 ';' { $1 } - | { [] } + : stmts1 ';' stmt { $3 : $1 } + | stmts1 ';' { $1 } + | stmt { [$1] } stmt :: { RdrNameStmt } : srcloc infixexp '<-' exp {% checkPattern $2 `thenP` \p -> @@ -794,6 +855,22 @@ fbind :: { (RdrName, RdrNameHsExpr, Bool) } : qvar '=' exp { ($1,$3,False) } ----------------------------------------------------------------------------- +-- Implicit Parameter Bindings + +dbinding :: { [(RdrName, RdrNameHsExpr)] } + : '{' dbinds '}' { $2 } + | layout_on dbinds close { $2 } + +dbinds :: { [(RdrName, RdrNameHsExpr)] } + : dbinds ';' dbind { $3 : $1 } + | dbinds ';' { $1 } + | dbind { [$1] } + | {- empty -} { [] } + +dbind :: { (RdrName, RdrNameHsExpr) } +dbind : ipvar '=' exp { ($1, $3) } + +----------------------------------------------------------------------------- -- Variables, Constructors and Operators. gcon :: { RdrName } @@ -808,7 +885,14 @@ var :: { RdrName } qvar :: { RdrName } : qvarid { $1 } - | '(' qvarsym ')' { $2 } + | '(' varsym ')' { $2 } + | '(' qvarsym1 ')' { $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. + +ipvar :: { RdrName } + : IPVARID { (mkSrcUnqual ipName (tailFS $1)) } con :: { RdrName } : conid { $1 } @@ -871,6 +955,8 @@ varid :: { RdrName } | 'label' { label_var_RDR } | 'dynamic' { dynamic_var_RDR } | 'unsafe' { unsafe_var_RDR } + | 'stdcall' { stdcall_var_RDR } + | 'ccall' { ccall_var_RDR } varid_no_unsafe :: { RdrName } : VARID { mkSrcUnqual varName $1 } @@ -881,6 +967,8 @@ varid_no_unsafe :: { RdrName } | 'export' { export_var_RDR } | 'label' { label_var_RDR } | 'dynamic' { dynamic_var_RDR } + | 'stdcall' { stdcall_var_RDR } + | 'ccall' { ccall_var_RDR } ----------------------------------------------------------------------------- -- ConIds @@ -977,10 +1065,12 @@ tyvar :: { RdrName } | 'as' { as_tyvar_RDR } | 'qualified' { qualified_tyvar_RDR } | 'hiding' { hiding_tyvar_RDR } - | 'export' { export_var_RDR } - | 'label' { label_var_RDR } - | 'dynamic' { dynamic_var_RDR } - | 'unsafe' { unsafe_var_RDR } + | 'export' { export_tyvar_RDR } + | 'label' { label_tyvar_RDR } + | 'dynamic' { dynamic_tyvar_RDR } + | 'unsafe' { unsafe_tyvar_RDR } + | 'stdcall' { stdcall_tyvar_RDR } + | 'ccall' { ccall_tyvar_RDR } -- NOTE: no 'forall' -----------------------------------------------------------------------------