ExtraCommas

Simon Peyton Jones simonpj at microsoft.com
Fri Sep 26 15:46:32 UTC 2014


|  What I think you are proposing is to capture commas in a different way
|  altogether before this stage, and I do not understand how or where

No. I'm proposing this. Insetad of

data HsRecFields id 
  = HsRecFields { rec_flds   :: [HsRecField id arg],
                  rec_dotdot :: Maybe Int 

have this:

data HsRecFields id 
  = HsRecFields { rec_flds   :: HsCommaList (HsRecField id arg),
                  rec_dotdot :: Maybe Int


data HsCommaList a
  = Empty
  | ExtraComma (HsCommaList a)
  | Cons a (HsCommaList a)

So that HsCommaList a is very like [a] but can express precisely where the extra commas appear.

Now adapt the parser to produce a (HsCommaList (HsRecField RdrName (LHsExpr RdrName))), rather than a list of those things.

The renamer then complains if it finds any ExtraComma constructors, unless the -XExtraCommas is specified.

Does that help?

Simon

|  -----Original Message-----
|  From: Alexander Berntsen [mailto:alexander at plaimi.net]
|  Sent: 23 September 2014 10:40
|  To: Simon Peyton Jones
|  Subject: Re: ExtraCommas
|  
|  -----BEGIN PGP SIGNED MESSAGE-----
|  Hash: SHA256
|  
|  On 23/09/14 11:28, Simon Peyton Jones wrote:
|  > My advice was only: parse commas *always* as if they were part of
|  the
|  > language. (So the parser has no conditinoals.) Reject them later (in
|  > the renamer) if the language extension is not enabled.
|  I don't understand this. From my limited understanding commas are
|  lexed, and then I can, in the parser, pattern match on things. Here's
|  a very specific example, record field update/construction:
|  
|  fbinds  :: { ([HsRecField RdrName (LHsExpr RdrName)], Bool) }
|          : fbinds1                   { $1 }
|          | {- empty -}               { ([], False) }
|  
|  fbinds1 :: { ([HsRecField RdrName (LHsExpr RdrName)], Bool) }
|          : fbind ',' fbinds1         { case $3 of (flds, dd) ->
|                                          ($1 : flds, dd) }
|          | fbind                     { ([$1], False) }
|          | '..'                      { ([],   True) }
|  
|  What's happening here is that fbinds uses a helper fbinds1, to capture
|  both fbinds1 & emptys. So to add support for leading/trailing commas,
|  what I did is simply pattern match on them:
|  
|  fbinds  :: { ([HsRecField RdrName (LHsExpr RdrName)], Bool) }
|          : ',' fbinds1               { $2 }
|          | fbinds1                   { $1 }
|  
|  fbinds1 :: { ([HsRecField RdrName (LHsExpr RdrName)], Bool) }
|          : fbind ',' fbinds1         { case $3 of
|                                          (flds, dd) -> ($1 : flds, dd)
|  }
|          | fbind                     { ([$1], False) }
|          | '..'                      { ([],   True)  }
|          | {- empty -}               { ([], False) }
|  
|  You can observe that I am now using fbinds to capture ',' fbinds1, and
|  have moved the empty match to fbinds1 itself.
|  
|  This is the general pattern I have used for all of my patches so far.
|  
|  
|  What I think you are proposing is to capture commas in a different way
|  altogether before this stage, and I do not understand how or where
|  this is meant to happen. And it also sounds like your suggestion will
|  mean I need to handle the case where extra commas are *not* supposed
|  to be handwaved, like tuples. So please elaborate, if you can.
|  
|  > Happy to talk. I'm simonpj0 on skype.
|  Do you happen to use any non-proprietary tool or at least protocol?
|  - --
|  Alexander
|  alexander at plaimi.net
|  https://secure.plaimi.net/~alexander
|  -----BEGIN PGP SIGNATURE-----
|  Version: GnuPG v2
|  Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
|  
|  iF4EAREIAAYFAlQhP9sACgkQRtClrXBQc7U0+gD/TvT+9iVA6JqiopTfeYEc7NU2
|  USD2bf+bKwhy9MNUjssA/3YUjA3PVYRpw1RFoRQF15zBFF6WDH5PQbS/8/5q7h+P
|  =saJc
|  -----END PGP SIGNATURE-----


More information about the ghc-devs mailing list