[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / compiler / parser / Lexer.x
index cd578b3..8304918 100644 (file)
 
 {
 module Lexer (
-   Token(..), Token__(..), lexer, mkPState, showPFailed,
-   P(..), ParseResult(..), setSrcLocFor, getSrcLoc, 
-   failMsgP, failLocMsgP, srcParseFail,
-   popContext, pushCurrentContext,
+   Token(..), lexer, mkPState, PState(..),
+   P(..), ParseResult(..), getSrcLoc, 
+   failLocMsgP, failSpanMsgP, srcParseFail,
+   popContext, pushCurrentContext, setLastToken, setSrcLoc,
+   getLexState, popLexState, pushLexState
   ) where
 
 #include "HsVersions.h"
@@ -39,7 +40,7 @@ import SrcLoc
 import UniqFM
 import CmdLineOpts
 import Ctype
-import Util            ( maybePrefixMatch )
+import Util            ( maybePrefixMatch, readRational )
 
 import DATA_BITS
 import Char
@@ -108,7 +109,8 @@ $white_no_nl+                               ;
 -- have to exclude those.
 -- The regex says: "munch all the characters after the dashes, as long as
 -- the first one is not a symbol".
-"--"\-* ([^$symbol] .*)?               ;
+"--"\-* [^$symbol] .*                  ;
+"--"\-* / { atEOL }                    ;
 
 -- 'bol' state: beginning of a line.  Slurp up all the whitespace (including
 -- blank lines) until we find a non-whitespace character, then do layout
@@ -123,6 +125,7 @@ $white_no_nl+                               ;
   \n                                   ;
   ^\# (line)?                          { begin line_prag1 }
   ^\# pragma .* \n                     ; -- GCC 3.3 CPP generated, apparently
+  ^\# \! .* \n                         ; -- #!, for scripts
   ()                                   { do_bol }
 }
 
@@ -151,15 +154,17 @@ $white_no_nl+                             ;
 
 -- single-line line pragmas, of the form
 --    # <line> "<file>" <extra-stuff> \n
-<line_prag1> $digit+                   { set_line line_prag1a }
-<line_prag1a> \" [$graphic \ ]* \"     { set_file line_prag1b }
+<line_prag1> $digit+                   { setLine line_prag1a }
+<line_prag1a> \" [$graphic \ ]* \"     { setFile line_prag1b }
 <line_prag1b> .*                       { pop }
 
 -- Haskell-style line pragmas, of the form
 --    {-# LINE <line> "<file>" #-}
-<line_prag2> $digit+                   { set_line line_prag2a }
-<line_prag2a> \" [$graphic \ ]* \"     { set_file line_prag2b }
-<line_prag2b> "#-}"                    { pop }
+<line_prag2> $digit+                   { setLine line_prag2a }
+<line_prag2a> \" [$graphic \ ]* \"     { setFile line_prag2b }
+<line_prag2b> "#-}"|"-}"               { pop }
+   -- NOTE: accept -} at the end of a LINE pragma, for compatibility
+   -- with older versions of GHC which generated these.
 
 <0,glaexts> {
   "{-#" $whitechar* (SPECIALI[SZ]E|speciali[sz]e)
@@ -173,6 +178,7 @@ $white_no_nl+                               ;
                                        { token ITdeprecated_prag }
   "{-#" $whitechar* (SCC|scc)          { token ITscc_prag }
   "{-#" $whitechar* (CORE|core)                { token ITcore_prag }
+  "{-#" $whitechar* (UNPACK|unpack)    { token ITunpack_prag }
   
   "{-#"                                { nested_comment }
 
@@ -297,9 +303,7 @@ unsafeAt arr i = arr ! i
 -- -----------------------------------------------------------------------------
 -- The token type
 
-data Token = T SrcSpan Token__
-
-data Token__
+data Token
   = ITas                       -- Haskell keywords
   | ITcase
   | ITclass
@@ -348,6 +352,7 @@ data Token__
   | ITline_prag
   | ITscc_prag
   | ITcore_prag                 -- hdaume: core annotations
+  | ITunpack_prag
   | ITclose_prag
 
   | ITdotdot                   -- reserved symbols
@@ -439,7 +444,7 @@ data Token__
   deriving Show -- debugging
 #endif
 
-isSpecial :: Token__ -> Bool
+isSpecial :: Token -> Bool
 -- If we see M.x, where x is a keyword, but
 -- is special, we treat is as just plain M.x, 
 -- not as a keyword.
@@ -541,30 +546,30 @@ reservedSymsFM = listToUFM $
 -- -----------------------------------------------------------------------------
 -- Lexer actions
 
-type Action = SrcSpan -> StringBuffer -> Int -> P Token
+type Action = SrcSpan -> StringBuffer -> Int -> P (Located Token)
 
-special :: Token__ -> Action
-special tok span _buf len = return (T span tok)
+special :: Token -> Action
+special tok span _buf len = return (L span tok)
 
-token, layout_token :: Token__ -> Action
-token t span buf len = return (T span t)
-layout_token t span buf len = pushLexState layout >> return (T span t)
+token, layout_token :: Token -> Action
+token t span buf len = return (L span t)
+layout_token t span buf len = pushLexState layout >> return (L span t)
 
-idtoken :: (StringBuffer -> Int -> Token__) -> Action
-idtoken f span buf len = return (T span $! (f buf len))
+idtoken :: (StringBuffer -> Int -> Token) -> Action
+idtoken f span buf len = return (L span $! (f buf len))
 
-skip_one_varid :: (FastString -> Token__) -> Action
+skip_one_varid :: (FastString -> Token) -> Action
 skip_one_varid f span buf len 
-  = return (T span $! f (lexemeToFastString (stepOn buf) (len-1)))
+  = return (L span $! f (lexemeToFastString (stepOn buf) (len-1)))
 
-strtoken :: (String -> Token__) -> Action
+strtoken :: (String -> Token) -> Action
 strtoken f span buf len = 
-  return (T span $! (f $! lexemeToString buf len))
+  return (L span $! (f $! lexemeToString buf len))
 
-init_strtoken :: Int -> (String -> Token__) -> Action
+init_strtoken :: Int -> (String -> Token) -> Action
 -- like strtoken, but drops the last N character(s)
 init_strtoken drop f span buf len = 
-  return (T span $! (f $! lexemeToString buf (len-drop)))
+  return (L span $! (f $! lexemeToString buf (len-drop)))
 
 begin :: Int -> Action
 begin code _span _str _len = do pushLexState code; lexToken
@@ -580,6 +585,8 @@ notFollowedBy char _ _ _ (_,buf) = atEnd buf || currentChar buf /= char
 notFollowedBySymbol _ _ _ (_,buf)
   = atEnd buf || currentChar buf `notElem` "!#$%&*+./<=>?@\\^|-~"
 
+atEOL _ _ _ (_,buf) = atEnd buf || currentChar buf == '\n'
+
 ifExtension pred bits _ _ _ = pred bits
 
 {-
@@ -608,16 +615,17 @@ nested_comment span _str _len = do
                    Just (c,input)    -> go n input
                c -> go n input
 
-        err input = do failLocMsgP (srcSpanStart span) (fst input) "unterminated `{-'"
+        err input = do failLocMsgP (srcSpanStart span) (fst input) 
+                       "unterminated `{-'"
 
 open_brace, close_brace :: Action
-open_brace  span _str _len = do 
+open_brace span _str _len = do 
   ctx <- getContext
   setContext (NoLayout:ctx)
-  return (T span ITocurly)
+  return (L span ITocurly)
 close_brace span _str _len = do 
   popContext
-  return (T span ITccurly)
+  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 
@@ -635,7 +643,7 @@ check_qvarid span buf len = do
        _other -> return token
   where
        (mod,var) = splitQualName buf len
-       token     = T span (ITqvarid (mod,var))
+       token     = L span (ITqvarid (mod,var))
 
        try_again = do
                setInput (srcSpanStart span,buf)
@@ -671,13 +679,13 @@ varid span buf len =
   case lookupUFM reservedWordsFM fs of
        Just (keyword,0)    -> do
                maybe_layout keyword
-               return (T span keyword)
+               return (L span keyword)
        Just (keyword,exts) -> do
                b <- extension (\i -> exts .&. i /= 0)
                if b then do maybe_layout keyword
-                            return (T span keyword)
-                    else return (T span (ITvarid fs))
-       _other -> return (T span (ITvarid fs))
+                            return (L span keyword)
+                    else return (L span (ITvarid fs))
+       _other -> return (L span (ITvarid fs))
   where
        fs = lexemeToFastString buf len
 
@@ -692,42 +700,36 @@ consym = sym ITconsym
 
 sym con span buf len = 
   case lookupUFM reservedSymsFM fs of
-       Just (keyword,0)    -> return (T span keyword)
+       Just (keyword,0)    -> return (L span keyword)
        Just (keyword,exts) -> do
                b <- extension (\i -> exts .&. i /= 0)
-               if b then return (T span keyword)
-                    else return (T span $! con fs)
-       _other -> return (T span $! con fs)
+               if b then return (L span keyword)
+                    else return (L span $! con fs)
+       _other -> return (L span $! con fs)
   where
        fs = lexemeToFastString buf len
 
 tok_decimal span buf len 
-  = return (T span (ITinteger  $! parseInteger buf len 10 oct_or_dec))
+  = return (L span (ITinteger  $! parseInteger buf len 10 octDecDigit))
 
 tok_octal span buf len 
-  = return (T span (ITinteger  $! parseInteger (stepOnBy 2 buf) (len-2) 8 oct_or_dec))
+  = return (L span (ITinteger  $! parseInteger (stepOnBy 2 buf) (len-2) 8 octDecDigit))
 
 tok_hexadecimal span buf len 
-  = return (T span (ITinteger  $! parseInteger (stepOnBy 2 buf) (len-2) 16 hex))
+  = return (L span (ITinteger  $! parseInteger (stepOnBy 2 buf) (len-2) 16 hexDigit))
 
 prim_decimal span buf len 
-  = return (T span (ITprimint  $! parseInteger buf (len-1) 10 oct_or_dec))
+  = return (L span (ITprimint  $! parseInteger buf (len-1) 10 octDecDigit))
 
 prim_octal span buf len 
-  = return (T span (ITprimint  $! parseInteger (stepOnBy 2 buf) (len-3) 8 oct_or_dec))
+  = return (L span (ITprimint  $! parseInteger (stepOnBy 2 buf) (len-3) 8 octDecDigit))
 
 prim_hexadecimal span buf len 
-  = return (T span (ITprimint  $! parseInteger (stepOnBy 2 buf) (len-3) 16 hex))
+  = return (L span (ITprimint  $! parseInteger (stepOnBy 2 buf) (len-3) 16 hexDigit))
 
-tok_float        str = ITrational $! readRational__ str
-prim_float       str = ITprimfloat  $! readRational__ str
-prim_double      str = ITprimdouble $! readRational__ str
-
-parseInteger :: StringBuffer -> Int -> Integer -> (Char->Int) -> Integer
-parseInteger buf len radix to_int 
-  = go 0 0
-  where go i x | i == len  = x
-              | otherwise = go (i+1) (x * radix + toInteger (to_int (lookAhead buf i)))
+tok_float        str = ITrational   $! readRational str
+prim_float       str = ITprimfloat  $! readRational str
+prim_double      str = ITprimdouble $! readRational str
 
 -- -----------------------------------------------------------------------------
 -- Layout processing
@@ -735,17 +737,17 @@ parseInteger buf len radix to_int
 -- we're at the first token on a line, insert layout tokens if necessary
 do_bol :: Action
 do_bol span _str _len = do
-       pos <- getOffside (srcSpanEndCol span)
+       pos <- getOffside (srcSpanEnd span)
        case pos of
            LT -> do
                 --trace "layout: inserting '}'" $ do
                popContext
                -- do NOT pop the lex state, we might have a ';' to insert
-               return (T span ITvccurly)
+               return (L span ITvccurly)
            EQ -> do
                 --trace "layout: inserting ';'" $ do
                popLexState
-               return (T span ITsemi)
+               return (L span ITsemi)
            GT -> do
                popLexState
                lexToken
@@ -780,30 +782,30 @@ new_layout_context strict span _buf _len = do
                -- token is indented to the left of the previous context.
                -- we must generate a {} sequence now.
                pushLexState layout_left
-               return (T span ITvocurly)
+               return (L span ITvocurly)
        other -> do
                setContext (Layout offset : ctx)
-               return (T span ITvocurly)
+               return (L span ITvocurly)
 
 do_layout_left span _buf _len = do
     popLexState
     pushLexState bol  -- we must be at the start of a line
-    return (T span ITvccurly)
+    return (L span ITvccurly)
 
 -- -----------------------------------------------------------------------------
 -- LINE pragmas
 
-set_line :: Int -> Action
-set_line code span buf len = do
-  let line = parseInteger buf len 10 oct_or_dec
+setLine :: Int -> Action
+setLine code span buf len = do
+  let line = parseInteger buf len 10 octDecDigit
   setSrcLoc (mkSrcLoc (srcSpanFile span) (fromIntegral line - 1) 0)
        -- subtract one: the line number refers to the *following* line
   popLexState
   pushLexState code
   lexToken
 
-set_file :: Int -> Action
-set_file code span buf len = do
+setFile :: Int -> Action
+setFile code span buf len = do
   let file = lexemeToFastString (stepOn buf) (len-2)
   setSrcLoc (mkSrcLoc file (srcSpanEndLine span) (srcSpanEndCol span))
   popLexState
@@ -819,9 +821,9 @@ lex_string_tok :: Action
 lex_string_tok span buf len = do
   tok <- lex_string ""
   end <- getSrcLoc 
-  return (T (mkSrcSpan (srcSpanStart span) end) tok)
+  return (L (mkSrcSpan (srcSpanStart span) end) tok)
 
-lex_string :: String -> P Token__
+lex_string :: String -> P Token
 lex_string s = do
   i <- getInput
   case alexGetChar i of
@@ -882,7 +884,7 @@ lex_char_tok span buf len = do      -- We've seen '
                  th_exts <- extension thEnabled
                  if th_exts then do
                        setInput i2
-                       return (T (mkSrcSpan loc end2)  ITtyQuote)
+                       return (L (mkSrcSpan loc end2)  ITtyQuote)
                   else lit_error
 
        Just ('\\', i2@(end2,_)) -> do  -- We've seen 'backslash 
@@ -905,24 +907,23 @@ lex_char_tok span buf len = do    -- We've seen '
                _other -> do            -- We've seen 'x not followed by quote
                                        -- If TH is on, just parse the quote only
                        th_exts <- extension thEnabled  
-                       if th_exts then return (T (mkSrcSpan loc (fst i1)) ITvarQuote)
+                       if th_exts then return (L (mkSrcSpan loc (fst i1)) ITvarQuote)
                                   else lit_error
 
-finish_char_tok :: SrcLoc -> Char -> P Token
+finish_char_tok :: SrcLoc -> Char -> P (Located Token)
 finish_char_tok loc ch -- We've already seen the closing quote
                        -- Just need to check for trailing #
   = do glaexts <- extension glaExtsEnabled
+       i@(end,_) <- getInput
        if glaexts then do
-               i@(end,_) <- getInput
                case alexGetChar i of
                        Just ('#',i@(end,_)) -> do
                                setInput i
-                               return (T (mkSrcSpan loc end) (ITprimchar ch))
+                               return (L (mkSrcSpan loc end) (ITprimchar ch))
                        _other ->
-                               return (T (mkSrcSpan loc end) (ITchar ch))
+                               return (L (mkSrcSpan loc end) (ITchar ch))
                else do
-                  end <- getSrcLoc
-                  return (T (mkSrcSpan loc end) (ITchar ch))
+                  return (L (mkSrcSpan loc end) (ITchar ch))
 
 lex_char :: P Char
 lex_char = do
@@ -951,9 +952,9 @@ lex_escape = do
                        then return (chr (ord c - ord '@'))
                        else lit_error
 
-       'x'   -> readNum is_hexdigit 16 hex
-       'o'   -> readNum is_octdigit  8 oct_or_dec
-       x | is_digit x -> readNum2 is_digit 10 oct_or_dec (oct_or_dec x)
+       'x'   -> readNum is_hexdigit 16 hexDigit
+       'o'   -> readNum is_octdigit  8 octDecDigit
+       x | is_digit x -> readNum2 is_digit 10 octDecDigit (octDecDigit x)
 
        c1 ->  do
           i <- getInput
@@ -994,22 +995,6 @@ readNum2 is_digit base conv i = do
                   then return (chr i)
                   else lit_error
 
-is_hexdigit c
-       =  is_digit c 
-       || (c >= 'a' && c <= 'f')
-       || (c >= 'A' && c <= 'F')
-
-hex c | is_digit c = ord c - ord '0'
-      | otherwise  = ord (to_lower c) - ord 'a' + 10
-
-oct_or_dec c = ord c - ord '0'
-
-is_octdigit c = c >= '0' && c <= '7'
-
-to_lower c 
-  | c >=  'A' && c <= 'Z' = chr (ord c - (ord 'A' - ord 'a'))
-  | otherwise = c
-
 silly_escape_chars = [
        ("NUL", '\NUL'),
        ("SOH", '\SOH'),
@@ -1057,54 +1042,6 @@ getCharOrFail =  do
        Just (c,i)  -> do setInput i; return c
 
 -- -----------------------------------------------------------------------------
--- Floats
-
-readRational :: ReadS Rational -- NB: doesn't handle leading "-"
-readRational r = do 
-     (n,d,s) <- readFix r
-     (k,t)   <- readExp s
-     return ((n%1)*10^^(k-d), t)
- where
-     readFix r = do
-       (ds,s)  <- lexDecDigits r
-       (ds',t) <- lexDotDigits s
-       return (read (ds++ds'), length ds', t)
-
-     readExp (e:s) | e `elem` "eE" = readExp' s
-     readExp s                    = return (0,s)
-
-     readExp' ('+':s) = readDec s
-     readExp' ('-':s) = do
-                       (k,t) <- readDec s
-                       return (-k,t)
-     readExp' s              = readDec s
-
-     readDec s = do
-        (ds,r) <- nonnull isDigit s
-        return (foldl1 (\n d -> n * 10 + d) [ ord d - ord '0' | d <- ds ],
-                r)
-
-     lexDecDigits = nonnull isDigit
-
-     lexDotDigits ('.':s) = return (span isDigit s)
-     lexDotDigits s       = return ("",s)
-
-     nonnull p s = do (cs@(_:_),t) <- return (span p s)
-                      return (cs,t)
-
-readRational__ :: String -> Rational -- NB: *does* handle a leading "-"
-readRational__ top_s
-  = case top_s of
-      '-' : xs -> - (read_me xs)
-      xs       -> read_me xs
-  where
-    read_me s
-      = case (do { (x,"") <- readRational s ; return x }) of
-         [x] -> x
-         []  -> error ("readRational__: no parse:"        ++ top_s)
-         _   -> error ("readRational__: ambiguous parse:" ++ top_s)
-
--- -----------------------------------------------------------------------------
 -- The Parse Monad
 
 data LayoutContext
@@ -1114,26 +1051,25 @@ data LayoutContext
 data ParseResult a
   = POk PState a
   | PFailed 
-       SrcSpan         -- The spam the error.  Might be used in environments
-                       -- which can show this span, e.g. by highlighting it.
+       SrcSpan         -- The start and end of the text span related to
+                       -- the error.  Might be used in environments which can 
+                       -- show this span, e.g. by highlighting it.
        Message         -- The error message
 
-showPFailed span err = hcat [ppr span, text ": ", err]
-
 data PState = PState { 
        buffer     :: StringBuffer,
-        last_span  :: SrcSpan,         -- span of previous token
-       last_len   :: !Int,
+        last_loc   :: SrcSpan, -- pos of previous token
+       last_len   :: !Int,     -- len of previous token
         loc        :: SrcLoc,   -- current loc (end of prev token + 1)
        extsBitmap :: !Int,     -- bitmap that determines permitted extensions
        context    :: [LayoutContext],
        lex_state  :: [Int]
      }
-       -- last_span is used when generating error messages,
-       -- and in pushCurrentContext only.
-       -- last_len is used when generating error messages, and is
-       -- needed because we need to back up the buffer pointer by that
-       -- number of characters for outputing the token in the error message.
+       -- last_loc and last_len are used when generating error messages,
+       -- and in pushCurrentContext only.  Sigh, if only Happy passed the
+       -- current token to happyError, we could at least get rid of last_len.
+       -- Getting rid of last_loc would require finding another way to 
+       -- implement pushCurrentContext (which is only called from one place).
 
 newtype P a = P { unP :: PState -> ParseResult a }
 
@@ -1152,14 +1088,17 @@ thenP :: P a -> (a -> P b) -> P b
                PFailed span err -> PFailed span err
 
 failP :: String -> P a
-failP msg = P $ \s -> PFailed (last_span s) (text msg)
+failP msg = P $ \s -> PFailed (last_loc s) (text msg)
 
 failMsgP :: String -> P a
-failMsgP msg = P $ \s -> PFailed (last_span s) (text msg)
+failMsgP msg = P $ \s -> PFailed (last_loc s) (text msg)
 
 failLocMsgP :: SrcLoc -> SrcLoc -> String -> P a
 failLocMsgP loc1 loc2 str = P $ \s -> PFailed (mkSrcSpan loc1 loc2) (text str)
 
+failSpanMsgP :: SrcSpan -> String -> P a
+failSpanMsgP span msg = P $ \s -> PFailed span (text msg)
+
 extension :: (Int -> Bool) -> P Bool
 extension p = P $ \s -> POk s (p $! extsBitmap s)
 
@@ -1169,19 +1108,11 @@ getExts = P $ \s -> POk s (extsBitmap s)
 setSrcLoc :: SrcLoc -> P ()
 setSrcLoc new_loc = P $ \s -> POk s{loc=new_loc} ()
 
--- tmp, for supporting stuff in RdrHsSyn.  The scope better not include
--- any calls to the lexer, because it assumes things about the SrcLoc.
-setSrcLocFor :: SrcLoc -> P a -> P a
-setSrcLocFor new_loc scope = P $ \s@PState{ loc = old_loc } -> 
-  case unP scope s{loc=new_loc} of
-       PFailed span msg -> PFailed span msg
-       POk _ r -> POk s r
-
 getSrcLoc :: P SrcLoc
 getSrcLoc = P $ \s@(PState{ loc=loc }) -> POk s loc
 
 setLastToken :: SrcSpan -> Int -> P ()
-setLastToken span len = P $ \s -> POk s{ last_span=span, last_len=len } ()
+setLastToken loc len = P $ \s -> POk s{ last_loc=loc, last_len=len } ()
 
 type AlexInput = (SrcLoc,StringBuffer)
 
@@ -1237,7 +1168,7 @@ mkPState :: StringBuffer -> SrcLoc -> DynFlags -> PState
 mkPState buf loc flags  = 
   PState {
       buffer    = buf,
-      last_span  = mkSrcSpan loc loc,
+      last_loc   = mkSrcSpan loc loc,
       last_len   = 0,
       loc        = loc,
       extsBitmap = fromIntegral bitmap,
@@ -1265,24 +1196,24 @@ setContext ctx = P $ \s -> POk s{context=ctx} ()
 
 popContext :: P ()
 popContext = P $ \ s@(PState{ buffer = buf, context = ctx, 
-                         loc = loc, last_len = len, last_span = last_span }) ->
+                          loc = loc, last_len = len, last_loc = last_loc }) ->
   case ctx of
        (_:tl) -> POk s{ context = tl } ()
-       []     -> PFailed last_span (srcParseErr buf len)
+       []     -> PFailed last_loc (srcParseErr buf len)
 
 -- Push a new layout context at the indentation of the last token read.
 -- This is only used at the outer level of a module when the 'module'
 -- keyword is missing.
 pushCurrentContext :: P ()
-pushCurrentContext = P $ \ s@PState{ last_span=span, context=ctx } ->
-  POk s{ context = Layout (srcSpanStartCol span) : ctx} ()
+pushCurrentContext = P $ \ s@PState{ last_loc=loc, context=ctx } ->
+  POk s{ context = Layout (srcSpanStartCol loc) : ctx} ()
 
-getOffside :: Int -> P Ordering
-getOffside col = P $ \s@PState{context=stk} ->
+getOffside :: SrcLoc -> P Ordering
+getOffside loc = P $ \s@PState{context=stk} ->
                let ord = case stk of
-                       (Layout n:_) -> compare col n
+                       (Layout n:_) -> compare (srcLocCol loc) n
                        _            -> GT
-               in POk s $! ord
+               in POk s ord
 
 -- ---------------------------------------------------------------------------
 -- Construct a parse error
@@ -1304,8 +1235,8 @@ srcParseErr buf len
 -- detected during parsing.
 srcParseFail :: P a
 srcParseFail = P $ \PState{ buffer = buf, last_len = len,      
-                               last_span = last_span, loc = loc } ->
-    PFailed last_span (srcParseErr buf len)
+                           last_loc = last_loc } ->
+    PFailed last_loc (srcParseErr buf len)
 
 -- A lexical error is reported at a particular position in the source file,
 -- not over a token range.  TODO: this is slightly wrong, because we record
@@ -1314,19 +1245,20 @@ srcParseFail = P $ \PState{ buffer = buf, last_len = len,
 lexError :: String -> P a
 lexError str = do
   loc <- getSrcLoc
-  failLocMsgP loc loc str
+  i@(end,_) <- getInput
+  failLocMsgP loc end str
 
 -- -----------------------------------------------------------------------------
 -- This is the top-level function: called from the parser each time a
 -- new token is to be read from the input.
 
-lexer :: (Token -> P a) -> P a
+lexer :: (Located Token -> P a) -> P a
 lexer cont = do
-  tok@(T _ tok__) <- lexToken
+  tok@(L _ tok__) <- lexToken
   --trace ("token: " ++ show tok__) $ do
   cont tok
 
-lexToken :: P Token
+lexToken :: P (Located Token)
 lexToken = do
   inp@(loc1,buf) <- getInput
   sc <- getLexState
@@ -1334,7 +1266,7 @@ lexToken = do
   case alexScanUser exts inp sc of
     AlexEOF -> do let span = mkSrcSpan loc1 loc1
                  setLastToken span 0
-                 return (T span ITeof)
+                 return (L span ITeof)
     AlexError (loc2,_) -> do failLocMsgP loc1 loc2 "lexical error"
     AlexSkip inp2 _ -> do
        setInput inp2
@@ -1342,6 +1274,6 @@ lexToken = do
     AlexToken inp2@(end,buf2) len t -> do
        setInput inp2
        let span = mkSrcSpan loc1 end
-       (setLastToken $! span) $! len
+       span `seq` setLastToken span len
        t span buf len
 }