FIX #1215: GHC fails to respect the maximal munch rule while lexing "qualified reserv...
authorSimon Marlow <simonmar@microsoft.com>
Tue, 24 Jul 2007 13:04:17 +0000 (13:04 +0000)
committerSimon Marlow <simonmar@microsoft.com>
Tue, 24 Jul 2007 13:04:17 +0000 (13:04 +0000)
I didn't actually fix this to respect Haskell 98, instead I changed it
to follow the proposal for Haskell':

http://hackage.haskell.org/cgi-bin/haskell-prime/trac.cgi/wiki/QualifiedIdentifiers

Rationale:

  - We didn't respect Haskell 98 with respect to qualified symbols either
  - The Haskell' change makes things much cleaner
  - Obeying the Haskell 98 spec literally has some unintended
    consequences (e.g. M.where must lex as "M.wher" "e")
  - Any programs that compiled before this change and do not compile
    after it were illegal according to Haskell 98 anyway.

compiler/parser/Lexer.x

index a6f7224..7165709 100644 (file)
@@ -334,19 +334,12 @@ $tab+         { warn Opt_WarnTabs (text "Tab character") }
 }
 
 <0,option_prags> {
-  @qual @varid                 { check_qvarid }
+  @qual @varid                 { idtoken qvarid }
   @qual @conid                 { idtoken qconid }
   @varid                       { varid }
   @conid                       { idtoken conid }
 }
 
--- after an illegal qvarid, such as 'M.let', 
--- we back up and try again in the bad_qvarid state:
-<bad_qvarid> {
-  @conid                       { pop_and (idtoken conid) }
-  @qual @conid                 { pop_and (idtoken qconid) }
-}
-
 <0> {
   @qual @varid "#"+ / { ifExtension magicHashEnabled } { idtoken qvarid }
   @qual @conid "#"+ / { ifExtension magicHashEnabled } { idtoken qconid }
@@ -871,30 +864,6 @@ close_brace span _str _len = do
   popContext
   return (L span ITccurly)
 
--- We have to be careful not to count M.<varid> as a qualified name
--- when <varid> is a keyword.  We hack around this by catching 
--- the offending tokens afterward, and re-lexing in a different state.
-check_qvarid span buf len = do
-  case lookupUFM reservedWordsFM var of
-       Just (keyword,exts)
-         | not (isSpecial keyword) ->
-         if exts == 0 
-            then try_again
-            else do
-               b <- extension (\i -> exts .&. i /= 0)
-               if b then try_again
-                    else return token
-       _other -> return token
-  where
-       (mod,var) = splitQualName buf len
-       token     = L span (ITqvarid (mod,var))
-
-       try_again = do
-               (AI _ offs _) <- getInput       
-               setInput (AI (srcSpanStart span) (offs-len) buf)
-               pushLexState bad_qvarid
-               lexToken
-
 qvarid buf len = ITqvarid $! splitQualName buf len
 qconid buf len = ITqconid $! splitQualName buf len