packages feed

haskell-src-exts 1.13.4 → 1.13.5

raw patch · 9 files changed

+1373/−1301 lines, 9 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Language.Haskell.Exts.Lexer: ANN :: Token
+ Language.Haskell.Exts.Lexer: At :: Token
+ Language.Haskell.Exts.Lexer: BackQuote :: Token
+ Language.Haskell.Exts.Lexer: Backslash :: Token
+ Language.Haskell.Exts.Lexer: Bar :: Token
+ Language.Haskell.Exts.Lexer: CORE :: Token
+ Language.Haskell.Exts.Lexer: Character :: (Char, String) -> Token
+ Language.Haskell.Exts.Lexer: CharacterHash :: (Char, String) -> Token
+ Language.Haskell.Exts.Lexer: Colon :: Token
+ Language.Haskell.Exts.Lexer: Comma :: Token
+ Language.Haskell.Exts.Lexer: ConId :: String -> Token
+ Language.Haskell.Exts.Lexer: ConSym :: String -> Token
+ Language.Haskell.Exts.Lexer: DEPRECATED :: Token
+ Language.Haskell.Exts.Lexer: DVarId :: [String] -> Token
+ Language.Haskell.Exts.Lexer: Dot :: Token
+ Language.Haskell.Exts.Lexer: DotDot :: Token
+ Language.Haskell.Exts.Lexer: DoubleArrow :: Token
+ Language.Haskell.Exts.Lexer: DoubleColon :: Token
+ Language.Haskell.Exts.Lexer: DoubleTokHash :: (Rational, String) -> Token
+ Language.Haskell.Exts.Lexer: EOF :: Token
+ Language.Haskell.Exts.Lexer: Equals :: Token
+ Language.Haskell.Exts.Lexer: Exclamation :: Token
+ Language.Haskell.Exts.Lexer: FloatTok :: (Rational, String) -> Token
+ Language.Haskell.Exts.Lexer: FloatTokHash :: (Rational, String) -> Token
+ Language.Haskell.Exts.Lexer: GENERATED :: Token
+ Language.Haskell.Exts.Lexer: IDupVarId :: (String) -> Token
+ Language.Haskell.Exts.Lexer: ILinVarId :: (String) -> Token
+ Language.Haskell.Exts.Lexer: INLINE :: Bool -> Token
+ Language.Haskell.Exts.Lexer: INLINE_CONLIKE :: Token
+ Language.Haskell.Exts.Lexer: IntTok :: (Integer, String) -> Token
+ Language.Haskell.Exts.Lexer: IntTokHash :: (Integer, String) -> Token
+ Language.Haskell.Exts.Lexer: KW_As :: Token
+ Language.Haskell.Exts.Lexer: KW_By :: Token
+ Language.Haskell.Exts.Lexer: KW_CCall :: Token
+ Language.Haskell.Exts.Lexer: KW_CPlusPlus :: Token
+ Language.Haskell.Exts.Lexer: KW_Case :: Token
+ Language.Haskell.Exts.Lexer: KW_Class :: Token
+ Language.Haskell.Exts.Lexer: KW_Data :: Token
+ Language.Haskell.Exts.Lexer: KW_Default :: Token
+ Language.Haskell.Exts.Lexer: KW_Deriving :: Token
+ Language.Haskell.Exts.Lexer: KW_Do :: Token
+ Language.Haskell.Exts.Lexer: KW_DotNet :: Token
+ Language.Haskell.Exts.Lexer: KW_Else :: Token
+ Language.Haskell.Exts.Lexer: KW_Export :: Token
+ Language.Haskell.Exts.Lexer: KW_Family :: Token
+ Language.Haskell.Exts.Lexer: KW_Forall :: Token
+ Language.Haskell.Exts.Lexer: KW_Foreign :: Token
+ Language.Haskell.Exts.Lexer: KW_Group :: Token
+ Language.Haskell.Exts.Lexer: KW_Hiding :: Token
+ Language.Haskell.Exts.Lexer: KW_If :: Token
+ Language.Haskell.Exts.Lexer: KW_Import :: Token
+ Language.Haskell.Exts.Lexer: KW_In :: Token
+ Language.Haskell.Exts.Lexer: KW_Infix :: Token
+ Language.Haskell.Exts.Lexer: KW_InfixL :: Token
+ Language.Haskell.Exts.Lexer: KW_InfixR :: Token
+ Language.Haskell.Exts.Lexer: KW_Instance :: Token
+ Language.Haskell.Exts.Lexer: KW_Js :: Token
+ Language.Haskell.Exts.Lexer: KW_Jvm :: Token
+ Language.Haskell.Exts.Lexer: KW_Let :: Token
+ Language.Haskell.Exts.Lexer: KW_MDo :: Token
+ Language.Haskell.Exts.Lexer: KW_Module :: Token
+ Language.Haskell.Exts.Lexer: KW_NewType :: Token
+ Language.Haskell.Exts.Lexer: KW_Of :: Token
+ Language.Haskell.Exts.Lexer: KW_Proc :: Token
+ Language.Haskell.Exts.Lexer: KW_Qualified :: Token
+ Language.Haskell.Exts.Lexer: KW_Rec :: Token
+ Language.Haskell.Exts.Lexer: KW_Safe :: Token
+ Language.Haskell.Exts.Lexer: KW_StdCall :: Token
+ Language.Haskell.Exts.Lexer: KW_Then :: Token
+ Language.Haskell.Exts.Lexer: KW_Threadsafe :: Token
+ Language.Haskell.Exts.Lexer: KW_Type :: Token
+ Language.Haskell.Exts.Lexer: KW_Unsafe :: Token
+ Language.Haskell.Exts.Lexer: KW_Using :: Token
+ Language.Haskell.Exts.Lexer: KW_Where :: Token
+ Language.Haskell.Exts.Lexer: LANGUAGE :: Token
+ Language.Haskell.Exts.Lexer: LeftArrow :: Token
+ Language.Haskell.Exts.Lexer: LeftArrowTail :: Token
+ Language.Haskell.Exts.Lexer: LeftCurly :: Token
+ Language.Haskell.Exts.Lexer: LeftCurlyBar :: Token
+ Language.Haskell.Exts.Lexer: LeftDblArrowTail :: Token
+ Language.Haskell.Exts.Lexer: LeftHashParen :: Token
+ Language.Haskell.Exts.Lexer: LeftParen :: Token
+ Language.Haskell.Exts.Lexer: LeftSquare :: Token
+ Language.Haskell.Exts.Lexer: Loc :: SrcSpan -> a -> Loc a
+ Language.Haskell.Exts.Lexer: Minus :: Token
+ Language.Haskell.Exts.Lexer: OPTIONS :: (Maybe String, String) -> Token
+ Language.Haskell.Exts.Lexer: PragmaEnd :: Token
+ Language.Haskell.Exts.Lexer: QConId :: (String, String) -> Token
+ Language.Haskell.Exts.Lexer: QConSym :: (String, String) -> Token
+ Language.Haskell.Exts.Lexer: QVarId :: (String, String) -> Token
+ Language.Haskell.Exts.Lexer: QVarSym :: (String, String) -> Token
+ Language.Haskell.Exts.Lexer: RPCAt :: Token
+ Language.Haskell.Exts.Lexer: RPGuardClose :: Token
+ Language.Haskell.Exts.Lexer: RPGuardOpen :: Token
+ Language.Haskell.Exts.Lexer: RULES :: Token
+ Language.Haskell.Exts.Lexer: RightArrow :: Token
+ Language.Haskell.Exts.Lexer: RightArrowTail :: Token
+ Language.Haskell.Exts.Lexer: RightCurly :: Token
+ Language.Haskell.Exts.Lexer: RightCurlyBar :: Token
+ Language.Haskell.Exts.Lexer: RightDblArrowTail :: Token
+ Language.Haskell.Exts.Lexer: RightHashParen :: Token
+ Language.Haskell.Exts.Lexer: RightParen :: Token
+ Language.Haskell.Exts.Lexer: RightSquare :: Token
+ Language.Haskell.Exts.Lexer: SCC :: Token
+ Language.Haskell.Exts.Lexer: SOURCE :: Token
+ Language.Haskell.Exts.Lexer: SPECIALISE :: Token
+ Language.Haskell.Exts.Lexer: SPECIALISE_INLINE :: Bool -> Token
+ Language.Haskell.Exts.Lexer: SemiColon :: Token
+ Language.Haskell.Exts.Lexer: Star :: Token
+ Language.Haskell.Exts.Lexer: StringHash :: (String, String) -> Token
+ Language.Haskell.Exts.Lexer: StringTok :: (String, String) -> Token
+ Language.Haskell.Exts.Lexer: THCloseQuote :: Token
+ Language.Haskell.Exts.Lexer: THDecQuote :: Token
+ Language.Haskell.Exts.Lexer: THExpQuote :: Token
+ Language.Haskell.Exts.Lexer: THIdEscape :: (String) -> Token
+ Language.Haskell.Exts.Lexer: THParenEscape :: Token
+ Language.Haskell.Exts.Lexer: THPatQuote :: Token
+ Language.Haskell.Exts.Lexer: THQuasiQuote :: (String, String) -> Token
+ Language.Haskell.Exts.Lexer: THTyQuote :: Token
+ Language.Haskell.Exts.Lexer: THTypQuote :: Token
+ Language.Haskell.Exts.Lexer: THVarQuote :: Token
+ Language.Haskell.Exts.Lexer: Tilde :: Token
+ Language.Haskell.Exts.Lexer: UNPACK :: Token
+ Language.Haskell.Exts.Lexer: Underscore :: Token
+ Language.Haskell.Exts.Lexer: VRightCurly :: Token
+ Language.Haskell.Exts.Lexer: VarId :: String -> Token
+ Language.Haskell.Exts.Lexer: VarSym :: String -> Token
+ Language.Haskell.Exts.Lexer: WARNING :: Token
+ Language.Haskell.Exts.Lexer: WordTokHash :: (Integer, String) -> Token
+ Language.Haskell.Exts.Lexer: XChildTagOpen :: Token
+ Language.Haskell.Exts.Lexer: XCloseTagOpen :: Token
+ Language.Haskell.Exts.Lexer: XCodeTagClose :: Token
+ Language.Haskell.Exts.Lexer: XCodeTagOpen :: Token
+ Language.Haskell.Exts.Lexer: XEmptyTagClose :: Token
+ Language.Haskell.Exts.Lexer: XPCDATA :: String -> Token
+ Language.Haskell.Exts.Lexer: XRPatClose :: Token
+ Language.Haskell.Exts.Lexer: XRPatOpen :: Token
+ Language.Haskell.Exts.Lexer: XStdTagClose :: Token
+ Language.Haskell.Exts.Lexer: XStdTagOpen :: Token
+ Language.Haskell.Exts.Lexer: data Loc a
+ Language.Haskell.Exts.Lexer: data Token
+ Language.Haskell.Exts.Lexer: lexTokenStream :: String -> ParseResult [Loc Token]
+ Language.Haskell.Exts.Lexer: lexTokenStreamWithMode :: ParseMode -> String -> ParseResult [Loc Token]
+ Language.Haskell.Exts.Lexer: loc :: Loc a -> SrcSpan
+ Language.Haskell.Exts.Lexer: unLoc :: Loc a -> a

Files

CHANGELOG view
@@ -1,5 +1,14 @@ ** 1.13.x
 
+1.13.4 --> 1.13.5
+===============
+
+* Expose Language.Haskell.Exts.Lexer, which implements
+  a standalone token stream lexer. The module is
+  re-exported both by Language.Haskell.Exts and by 
+  Language.Haskell.Exts.Annotated.
+
+
 1.13.3 --> 1.13.4
 ===============
 
dist/build/Language/Haskell/Exts/InternalParser.hs view
@@ -37,7 +37,7 @@ import Language.Haskell.Exts.Annotated.Syntax hiding ( Type(..), Exp(..), Asst(..), XAttr(..), FieldUpdate(..) ) import Language.Haskell.Exts.Annotated.Syntax ( Type, Exp, Asst ) import Language.Haskell.Exts.ParseMonad-import Language.Haskell.Exts.Lexer+import Language.Haskell.Exts.InternalLexer import Language.Haskell.Exts.ParseUtils import Language.Haskell.Exts.Annotated.Fixity import Language.Haskell.Exts.SrcLoc
haskell-src-exts.cabal view
@@ -1,5 +1,5 @@ Name:                   haskell-src-exts-Version:                1.13.4+Version:                1.13.5 License:                BSD3 License-File:           LICENSE Author:                 Niklas Broberg@@ -116,6 +116,7 @@     Exposed-modules:      Language.Haskell.Exts,+                        Language.Haskell.Exts.Lexer,                         Language.Haskell.Exts.Parser,                         Language.Haskell.Exts.Pretty,                         Language.Haskell.Exts.Syntax,@@ -136,7 +137,7 @@                                                  Language.Haskell.Exts.ParseMonad,                         Language.Haskell.Exts.ParseSyntax,-                        Language.Haskell.Exts.Lexer,+                        Language.Haskell.Exts.InternalLexer,                         Language.Haskell.Exts.ParseUtils,                         Language.Haskell.Exts.InternalParser   Hs-source-dirs:       src
src/Language/Haskell/Exts.hs view
@@ -17,6 +17,7 @@     -- * Re-exported modules       module Language.Haskell.Exts.Syntax     , module Language.Haskell.Exts.Build+    , module Language.Haskell.Exts.Lexer     , module Language.Haskell.Exts.Parser     , module Language.Haskell.Exts.Pretty     , module Language.Haskell.Exts.Extension@@ -38,6 +39,7 @@ import Language.Haskell.Exts.Build import Language.Haskell.Exts.Syntax import Language.Haskell.Exts.Parser+import Language.Haskell.Exts.Lexer import Language.Haskell.Exts.Pretty import Language.Haskell.Exts.Extension import Language.Haskell.Exts.Fixity
src/Language/Haskell/Exts/Annotated.hs view
@@ -18,6 +18,7 @@       module Language.Haskell.Exts.Annotated.Syntax     , module Language.Haskell.Exts.Annotated.Build     , module Language.Haskell.Exts.Parser+    , module Language.Haskell.Exts.Lexer     , module Language.Haskell.Exts.Pretty     , module Language.Haskell.Exts.Annotated.Fixity     , module Language.Haskell.Exts.Annotated.ExactPrint@@ -47,6 +48,7 @@ import Language.Haskell.Exts.Annotated.Build import Language.Haskell.Exts.Annotated.Syntax import Language.Haskell.Exts.Parser ( Parseable(..), ParseResult(..), fromParseResult, ParseMode(..), defaultParseMode )+import Language.Haskell.Exts.Lexer ( lexTokenStream, lexTokenStreamWithMode, Token(..) ) import Language.Haskell.Exts.Pretty import Language.Haskell.Exts.Annotated.Fixity import Language.Haskell.Exts.Annotated.ExactPrint
+ src/Language/Haskell/Exts/InternalLexer.hs view
@@ -0,0 +1,1297 @@+{-# OPTIONS_HADDOCK hide #-}+-----------------------------------------------------------------------------+-- |+-- Module      :  Language.Haskell.Exts.Annotated.InternalLexer+-- Copyright   :  (c) The GHC Team, 1997-2000+--                (c) Niklas Broberg, 2004-2009+-- License     :  BSD-style (see the file LICENSE.txt)+--+-- Maintainer  :  Niklas Broberg, d00nibro@chalmers.se+-- Stability   :  stable+-- Portability :  portable+--+-- Lexer for Haskell, with some extensions.+--+-----------------------------------------------------------------------------++-- ToDo: Introduce different tokens for decimal, octal and hexadecimal (?)+-- ToDo: FloatTok should have three parts (integer part, fraction, exponent) (?)+-- ToDo: Use a lexical analyser generator (lx?)++module Language.Haskell.Exts.InternalLexer (Token(..), showToken, lexer, topLexer) where++import Language.Haskell.Exts.ParseMonad+import Language.Haskell.Exts.SrcLoc+import Language.Haskell.Exts.Comments+import Language.Haskell.Exts.Extension+import Language.Haskell.Exts.ExtScheme++import Data.Char+import Data.Ratio+import Data.List (intersperse)+import Control.Monad (when)++-- import Debug.Trace (trace)++data Token+        = VarId String+        | QVarId (String,String)+        | IDupVarId (String)        -- duplicable implicit parameter+        | ILinVarId (String)        -- linear implicit parameter+        | ConId String+        | QConId (String,String)+        | DVarId [String]       -- to enable varid's with '-' in them+        | VarSym String+        | ConSym String+        | QVarSym (String,String)+        | QConSym (String,String)+        | IntTok (Integer, String)+        | FloatTok (Rational, String)+        | Character (Char, String)+        | StringTok (String, String)+        | IntTokHash (Integer, String)        -- 1#+        | WordTokHash (Integer, String)       -- 1##+        | FloatTokHash (Rational, String)     -- 1.0#+        | DoubleTokHash (Rational, String)    -- 1.0##+        | CharacterHash (Char, String)        -- c#+        | StringHash (String, String)         -- "Hello world!"#++-- Symbols++        | LeftParen+        | RightParen+        | LeftHashParen+        | RightHashParen+        | LeftCurlyBar+        | RightCurlyBar+        | SemiColon+        | LeftCurly+        | RightCurly+        | VRightCurly           -- a virtual close brace+        | LeftSquare+        | RightSquare+        | Comma+        | Underscore+        | BackQuote++-- Reserved operators++        | Dot           -- reserved for use with 'forall x . x'+        | DotDot+        | Colon+        | DoubleColon+        | Equals+        | Backslash+        | Bar+        | LeftArrow+        | RightArrow+        | At+        | Tilde+        | DoubleArrow+        | Minus+        | Exclamation+        | Star+        | LeftArrowTail         -- >-+        | RightArrowTail        -- -<+        | LeftDblArrowTail      -- >>-+        | RightDblArrowTail     -- -<<++-- Template Haskell+        | THExpQuote            -- [| or [e|+        | THPatQuote            -- [p|+        | THDecQuote            -- [d|+        | THTypQuote            -- [t|+        | THCloseQuote          -- |]+        | THIdEscape (String)   -- dollar x+        | THParenEscape         -- dollar (+        | THVarQuote            -- 'x (but without the x)+        | THTyQuote             -- ''T (but without the T)+        | THQuasiQuote (String,String)  -- [$...|...]++-- HaRP+        | RPGuardOpen       -- (|+        | RPGuardClose      -- |)+        | RPCAt             -- @:++-- Hsx+        | XCodeTagOpen      -- <%+        | XCodeTagClose     -- %>+        | XStdTagOpen       -- <+        | XStdTagClose      -- >+        | XCloseTagOpen     -- </+        | XEmptyTagClose    -- />+        | XChildTagOpen     -- <%> (note that close doesn't exist, it's XCloseTagOpen followed by XCodeTagClose)+        | XPCDATA String+        | XRPatOpen             -- <[+        | XRPatClose            -- ]>++-- Pragmas++        | PragmaEnd                     -- #-}+        | RULES+        | INLINE Bool+        | INLINE_CONLIKE+        | SPECIALISE+        | SPECIALISE_INLINE Bool+        | SOURCE+        | DEPRECATED+        | WARNING+        | SCC+        | GENERATED+        | CORE+        | UNPACK+        | OPTIONS (Maybe String,String)+--        | CFILES  String+--        | INCLUDE String+        | LANGUAGE+        | ANN++-- Reserved Ids++        | KW_As+        | KW_By         -- transform list comprehensions+        | KW_Case+        | KW_Class+        | KW_Data+        | KW_Default+        | KW_Deriving+        | KW_Do+        | KW_MDo+        | KW_Else+        | KW_Family     -- indexed type families+        | KW_Forall     -- universal/existential types+        | KW_Group      -- transform list comprehensions+        | KW_Hiding+        | KW_If+        | KW_Import+        | KW_In+        | KW_Infix+        | KW_InfixL+        | KW_InfixR+        | KW_Instance+        | KW_Let+        | KW_Module+        | KW_NewType+        | KW_Of+        | KW_Proc       -- arrows+        | KW_Rec        -- arrows+        | KW_Then+        | KW_Type+        | KW_Using      -- transform list comprehensions+        | KW_Where+        | KW_Qualified++                -- FFI+        | KW_Foreign+        | KW_Export+        | KW_Safe+        | KW_Unsafe+        | KW_Threadsafe+        | KW_StdCall+        | KW_CCall+        | KW_CPlusPlus+        | KW_DotNet+        | KW_Jvm+        | KW_Js++        | EOF+        deriving (Eq,Show)++reserved_ops :: [(String,(Token, Maybe ExtScheme))]+reserved_ops = [+ ( "..", (DotDot,       Nothing) ),+ ( ":",  (Colon,        Nothing) ),+ ( "::", (DoubleColon,  Nothing) ),+ ( "=",  (Equals,       Nothing) ),+ ( "\\", (Backslash,    Nothing) ),+ ( "|",  (Bar,          Nothing) ),+ ( "<-", (LeftArrow,    Nothing) ),+ ( "->", (RightArrow,   Nothing) ),+ ( "@",  (At,           Nothing) ),+ ( "@:", (RPCAt,        Just (Any [RegularPatterns])) ),+ ( "~",  (Tilde,        Nothing) ),+ ( "=>", (DoubleArrow,  Nothing) ),+ ( "*",  (Star,         Just (Any [KindSignatures])) ),+ -- Arrows notation+ ( "-<",  (LeftArrowTail,       Just (Any [Arrows])) ),+ ( ">-",  (RightArrowTail,      Just (Any [Arrows])) ),+ ( "-<<", (LeftDblArrowTail,    Just (Any [Arrows])) ),+ ( ">>-", (RightDblArrowTail,   Just (Any [Arrows])) ),+ -- Unicode notation+ ( "\x2190",    (LeftArrow,     Just (Any  [UnicodeSyntax])) ),+ ( "\x2192",    (RightArrow,    Just (Any  [UnicodeSyntax])) ),+ ( "\x21d2",    (DoubleArrow,   Just (Any  [UnicodeSyntax])) ),+ ( "\x2237",    (DoubleColon,   Just (Any  [UnicodeSyntax])) ),+ ( "\x2919",    (LeftArrowTail,     Just (All [UnicodeSyntax, Arrows])) ),+ ( "\x291a",    (RightArrowTail,    Just (All [UnicodeSyntax, Arrows])) ),+ ( "\x291b",    (LeftDblArrowTail,  Just (All [UnicodeSyntax, Arrows])) ),+ ( "\x291c",    (RightDblArrowTail, Just (All [UnicodeSyntax, Arrows])) ),+ ( "\x2605",    (Star,              Just (All [UnicodeSyntax, KindSignatures])) )+ ]++special_varops :: [(String,(Token, Maybe ExtScheme))]+special_varops = [+ -- the dot is only a special symbol together with forall, but can still be used as function composition+ ( ".",  (Dot,          Just (Any [ExplicitForAll, ExistentialQuantification])) ),+ ( "-",  (Minus,        Nothing) ),+ ( "!",  (Exclamation,  Nothing) )+ ]++reserved_ids :: [(String,(Token, Maybe ExtScheme))]+reserved_ids = [+ ( "_",         (Underscore,    Nothing) ),+ ( "by",        (KW_By,         Just (Any [TransformListComp])) ),+ ( "case",      (KW_Case,       Nothing) ),+ ( "class",     (KW_Class,      Nothing) ),+ ( "data",      (KW_Data,       Nothing) ),+ ( "default",   (KW_Default,    Nothing) ),+ ( "deriving",  (KW_Deriving,   Nothing) ),+ ( "do",        (KW_Do,         Nothing) ),+ ( "else",      (KW_Else,       Nothing) ),+ ( "family",    (KW_Family,     Just (Any [TypeFamilies])) ),        -- indexed type families+ ( "forall",    (KW_Forall,     Just (Any [ExplicitForAll, ExistentialQuantification])) ),    -- universal/existential quantification+ ( "group",     (KW_Group,      Just (Any [TransformListComp])) ),+ ( "if",        (KW_If,         Nothing) ),+ ( "import",    (KW_Import,     Nothing) ),+ ( "in",        (KW_In,         Nothing) ),+ ( "infix",     (KW_Infix,      Nothing) ),+ ( "infixl",    (KW_InfixL,     Nothing) ),+ ( "infixr",    (KW_InfixR,     Nothing) ),+ ( "instance",  (KW_Instance,   Nothing) ),+ ( "let",       (KW_Let,        Nothing) ),+ ( "mdo",       (KW_MDo,        Just (Any [RecursiveDo])) ),+ ( "module",    (KW_Module,     Nothing) ),+ ( "newtype",   (KW_NewType,    Nothing) ),+ ( "of",        (KW_Of,         Nothing) ),+ ( "proc",      (KW_Proc,       Just (Any [Arrows])) ),+ ( "rec",       (KW_Rec,        Just (Any [Arrows])) ),+ ( "then",      (KW_Then,       Nothing) ),+ ( "type",      (KW_Type,       Nothing) ),+ ( "using",     (KW_Using,      Just (Any [TransformListComp])) ),+ ( "where",     (KW_Where,      Nothing) ),++-- FFI+ ( "foreign",   (KW_Foreign,    Just (Any [ForeignFunctionInterface])) ),++-- Unicode+ ( "\x2200",    (KW_Forall,     Just (All [UnicodeSyntax, ExplicitForAll])) )+ ]+++special_varids :: [(String,(Token, Maybe ExtScheme))]+special_varids = [+ ( "as",        (KW_As,         Nothing) ),+ ( "qualified", (KW_Qualified,  Nothing) ),+ ( "hiding",    (KW_Hiding,     Nothing) ),++-- FFI+ ( "export",     (KW_Export,        Just (Any [ForeignFunctionInterface])) ),+ ( "safe",       (KW_Safe,          Just (Any [ForeignFunctionInterface])) ),+ ( "unsafe",     (KW_Unsafe,        Just (Any [ForeignFunctionInterface])) ),+ ( "threadsafe", (KW_Threadsafe,    Just (Any [ForeignFunctionInterface])) ),+ ( "stdcall",    (KW_StdCall,       Just (Any [ForeignFunctionInterface])) ),+ ( "ccall",      (KW_CCall,         Just (Any [ForeignFunctionInterface])) ),+ ( "cplusplus",  (KW_CPlusPlus,     Just (Any [ForeignFunctionInterface])) ),+ ( "dotnet",     (KW_DotNet,        Just (Any [ForeignFunctionInterface])) ),+ ( "jvm",        (KW_Jvm,           Just (Any [ForeignFunctionInterface])) ),+ ( "js",         (KW_Js,            Just (Any [ForeignFunctionInterface])) )+ ]++pragmas :: [(String,Token)]+pragmas = [+ ( "rules",             RULES           ),+ ( "inline",            INLINE True     ),+ ( "noinline",          INLINE False    ),+ ( "notinline",         INLINE False    ),+ ( "specialise",        SPECIALISE      ),+ ( "specialize",        SPECIALISE      ),+ ( "source",            SOURCE          ),+ ( "deprecated",        DEPRECATED      ),+ ( "warning",           WARNING         ),+ ( "ann",               ANN             ),+ ( "scc",               SCC             ),+ ( "generated",         GENERATED       ),+ ( "core",              CORE            ),+ ( "unpack",            UNPACK          ),+ ( "language",          LANGUAGE        ),+ ( "options",           OPTIONS undefined ) -- we'll tweak it before use - promise!+-- ( "cfiles",            CFILES  undefined ), -- same here...+-- ( "include",           INCLUDE undefined )  -- ...and here!+ ]++isIdent, isHSymbol :: Char -> Bool+isIdent   c = isAlpha c || isDigit c || c == '\'' || c == '_'++isHSymbol c = c `elem` ":!#%&*./?@\\-" || ((isSymbol c || isPunctuation c) && not (c `elem` "(),;[]`{}_\"'"))++matchChar :: Char -> String -> Lex a ()+matchChar c msg = do+    s <- getInput+    if null s || head s /= c then fail msg else discard 1++-- The top-level lexer.+-- We need to know whether we are at the beginning of the line to decide+-- whether to insert layout tokens.++lexer :: (Loc Token -> P a) -> P a+lexer = runL topLexer++topLexer :: Lex a (Loc Token)+topLexer = do+    b <- pullCtxtFlag+    if b then -- trace (show cf ++ ": " ++ show VRightCurly) $+              setBOL >> getSrcLocL >>= \l -> return (Loc (mkSrcSpan l l) VRightCurly) -- the lex context state flags that we must do an empty {} - UGLY+     else do+        bol <- checkBOL+        (bol, ws) <- lexWhiteSpace bol+        -- take care of whitespace in PCDATA+        ec <- getExtContext+        case ec of+         -- if there was no linebreak, and we are lexing PCDATA,+         -- then we want to care about the whitespace.+         -- We don't bother to test for XmlSyntax, since we+         -- couldn't end up in ChildCtxt otherwise.+         Just ChildCtxt | not bol && ws -> getSrcLocL >>= \l -> return $ Loc (mkSrcSpan l l) $ XPCDATA " "+         _ -> do startToken+                 sl <- getSrcLocL+                 t <- if bol then lexBOL    -- >>= \t -> trace ("BOL: " ++ show t) (return t)+                             else lexToken  -- >>= \t -> trace (show t) (return t)+                 el <- getSrcLocL+                 return $ Loc (mkSrcSpan sl el) t++lexWhiteSpace :: Bool -> Lex a (Bool, Bool)+lexWhiteSpace bol = do+    s <- getInput+    ignL <- ignoreLinePragmasL+    case s of+        -- If we find a recognised pragma, we don't want to treat it as a comment.+        '{':'-':'#':rest | isRecognisedPragma rest -> return (bol, False)+                         | isLinePragma rest && not ignL -> do +                            (l, fn) <- lexLinePragma+                            setSrcLineL l+                            setLineFilenameL fn+                            lexWhiteSpace True+        '{':'-':_ -> do+            loc <- getSrcLocL+            discard 2+            (bol, c) <- lexNestedComment bol ""+            loc2 <- getSrcLocL+            pushComment $ Comment True (mkSrcSpan loc loc2) (reverse c)+            (bol, _) <- lexWhiteSpace bol+            return (bol, True)+        '-':'-':s | all (== '-') (takeWhile isHSymbol s) -> do+            loc    <- getSrcLocL+            discard 2+            dashes <- lexWhile (== '-')+            rest   <- lexWhile (/= '\n')+            s' <- getInput+            loc2 <- getSrcLocL+            let com = Comment False (mkSrcSpan loc loc2) $ dashes ++ rest+            case s' of+                [] -> pushComment com >> return (False, True)+                _ -> do+                    pushComment com+                    lexNewline+                    lexWhiteSpace True+                    return (True, True)+        '\n':_ -> do+            lexNewline+            lexWhiteSpace True+            return (True, True)+        '\t':_ -> do+            lexTab+            (bol, _) <- lexWhiteSpace bol+            return (bol, True)+        c:_ | isSpace c -> do+            discard 1+            (bol, _) <- lexWhiteSpace bol+            return (bol, True)+        _ -> return (bol, False)++isRecognisedPragma, isLinePragma :: String -> Bool+isRecognisedPragma str = let pragma = map toLower . takeWhile isAlphaNum . dropWhile isSpace $ str+                          in case lookup pragma pragmas of+                              Nothing -> False+                              _       -> True++isLinePragma str = let pragma = map toLower . takeWhile isAlphaNum . dropWhile isSpace $ str+                    in case pragma of+                        "line"  -> True+                        _       -> False++lexLinePragma :: Lex a (Int, String)+lexLinePragma = do+    discard 3   -- {-#+    lexWhile isSpace+    discard 4   -- LINE+    lexWhile isSpace+    i <- lexWhile isDigit+    when (null i) $ fail "Improperly formatted LINE pragma"+    lexWhile isSpace+    matchChar '"' "Improperly formatted LINE pragma"+    fn <- lexWhile (/= '"')+    matchChar '"' "Impossible - lexLinePragma"+    lexWhile isSpace+    mapM (flip matchChar "Improperly formatted LINE pragma") "#-}"+    lexNewline+    return (read i, fn)++lexNestedComment :: Bool -> String -> Lex a (Bool, String)+lexNestedComment bol str = do+    s <- getInput+    case s of+        '-':'}':_ -> discard 2 >> return (bol, str)+        '{':'-':_ -> do+            discard 2+            (bol, c) <- lexNestedComment bol ("-{" ++ str) -- rest of the subcomment+            lexNestedComment bol ("}-" ++ c  ) -- rest of this comment+        '\t':_    -> lexTab >> lexNestedComment bol ('\t':str)+        '\n':_    -> lexNewline >> lexNestedComment True ('\n':str)+        c:_       -> discard 1 >> lexNestedComment bol (c:str)+        []        -> fail "Unterminated nested comment"++-- When we are lexing the first token of a line, check whether we need to+-- insert virtual semicolons or close braces due to layout.++lexBOL :: Lex a Token+lexBOL = do+    pos <- getOffside+    -- trace ("Off: " ++ (show pos)) $ do+    case pos of+        LT -> do+                -- trace "layout: inserting '}'\n" $+            -- Set col to 0, indicating that we're still at the+            -- beginning of the line, in case we need a semi-colon too.+            -- Also pop the context here, so that we don't insert+            -- another close brace before the parser can pop it.+            setBOL+            popContextL "lexBOL"+            return VRightCurly+        EQ ->+            -- trace "layout: inserting ';'\n" $+            return SemiColon+        GT -> lexToken++lexToken :: Lex a Token+lexToken = do+    ec <- getExtContext+    -- we don't bother to check XmlSyntax since we couldn't+    -- have ended up in a non-Nothing context if it wasn't+    -- enabled.+    case ec of+     Just HarpCtxt     -> lexHarpToken+     Just TagCtxt      -> lexTagCtxt+     Just CloseTagCtxt -> lexCloseTagCtxt+     Just ChildCtxt    -> lexChildCtxt+     Just CodeTagCtxt  -> lexCodeTagCtxt+     _         -> lexStdToken+++lexChildCtxt :: Lex a Token+lexChildCtxt = do+    -- if we ever end up here, then XmlSyntax must be on.+    s <- getInput+    case s of+        '<':'%':'>':_ -> do discard 3+                            pushExtContextL ChildCtxt+                            return XChildTagOpen+        '<':'%':_ -> do discard 2+                        pushExtContextL CodeTagCtxt+                        return XCodeTagOpen+        '<':'/':_ -> do discard 2+                        popExtContextL "lexChildCtxt"+                        pushExtContextL CloseTagCtxt+                        return XCloseTagOpen+        '<':'[':_ -> do discard 2+                        pushExtContextL HarpCtxt+                        return XRPatOpen+        '<':_     -> do discard 1+                        pushExtContextL TagCtxt+                        return XStdTagOpen+        _     -> lexPCDATA+++lexPCDATA :: Lex a Token+lexPCDATA = do+    -- if we ever end up here, then XmlSyntax must be on.+    s <- getInput+    case s of+        [] -> return EOF+        _  -> case s of+            '\n':_ -> do+                x <- lexNewline >> lexPCDATA+                case x of+                 XPCDATA p -> return $ XPCDATA $ '\n':p+                 EOF -> return EOF+            '<':_ -> return $ XPCDATA ""+            _ -> do let pcd = takeWhile (\c -> not $ elem c "<\n") s+                        l = length pcd+                    discard l+                    x <- lexPCDATA+                    case x of+                     XPCDATA pcd' -> return $ XPCDATA $ pcd ++ pcd'+                     EOF -> return EOF+++lexCodeTagCtxt :: Lex a Token+lexCodeTagCtxt = do+    -- if we ever end up here, then XmlSyntax must be on.+    s <- getInput+    case s of+        '%':'>':_ -> do discard 2+                        popExtContextL "lexCodeTagContext"+                        return XCodeTagClose+        _     -> lexStdToken++lexCloseTagCtxt :: Lex a Token+lexCloseTagCtxt = do+    -- if we ever end up here, then XmlSyntax must be on.+    s <- getInput+    case s of+        '%':'>':_ -> do discard 2+                        popExtContextL "lexCloseTagCtxt"+                        return XCodeTagClose+        '>':_     -> do discard 1+                        popExtContextL "lexCloseTagCtxt"+                        return XStdTagClose+        _     -> lexStdToken++lexTagCtxt :: Lex a Token+lexTagCtxt = do+    -- if we ever end up here, then XmlSyntax must be on.+    s <- getInput+    case s of+        '/':'>':_ -> do discard 2+                        popExtContextL "lexTagCtxt: Empty tag"+                        return XEmptyTagClose+        '>':_     -> do discard 1+                        popExtContextL "lexTagCtxt: Standard tag"+                        pushExtContextL ChildCtxt+                        return XStdTagClose+        _     -> lexStdToken++lexHarpToken :: Lex a Token+lexHarpToken = do+    -- if we ever end up here, then RegularPatterns must be on.+    s <- getInput+    case s of+        ']':'>':_ -> do discard 2+                        popExtContextL "lexHarpToken"+                        return XRPatClose+        _     -> lexStdToken++lexStdToken :: Lex a Token+lexStdToken = do+    s <- getInput+    exts <- getExtensionsL+    case s of+        [] -> return EOF++        '0':c:d:_ | toLower c == 'o' && isOctDigit d -> do+                        discard 2+                        (n, str) <- lexOctal+                        return (IntTok (n, '0':c:str))+                  | toLower c == 'x' && isHexDigit d -> do+                        discard 2+                        (n, str) <- lexHexadecimal+                        return (IntTok (n, '0':c:str))++        -- implicit parameters+        '?':c:_ | isLower c && ImplicitParams `elem` exts -> do+                        discard 1+                        id <- lexWhile isIdent+                        return $ IDupVarId id++        '%':c:_ | isLower c && ImplicitParams `elem` exts -> do+                        discard 1+                        id <- lexWhile isIdent+                        return $ ILinVarId id+        -- end implicit parameters++        -- harp+--        '(':'|':c:_  | isHSymbol c -> discard 1 >> return LeftParen+        '(':'|':c:_ | RegularPatterns `elem` exts && not (isHSymbol c) ->+                     do discard 2+                        return RPGuardOpen+        '|':')':_ | RegularPatterns `elem` exts ->+                     do discard 2+                        return RPGuardClose+        {- This is handled by the reserved_ops above.+        '@':':':_ | RegularPatterns `elem` exts ->+                     do discard 2+                        return RPCAt -}++        -- template haskell+        '[':'|':_ | TemplateHaskell `elem` exts -> do+                discard 2+                return $ THExpQuote++        '[':c:'|':_ | c == 'e' && TemplateHaskell `elem` exts -> do+                        discard 3+                        return $ THExpQuote+                    | c == 'p' && TemplateHaskell `elem` exts -> do+                        discard 3+                        return THPatQuote+                    | c == 'd' && TemplateHaskell `elem` exts -> do+                        discard 3+                        return THDecQuote+                    | c == 't' && TemplateHaskell `elem` exts -> do+                        discard 3+                        return THTypQuote+        '[':'$':c:_ | isLower c && QuasiQuotes `elem` exts ->+                        discard 2 >> lexQuasiQuote++        '[':c:s | isLower c && QuasiQuotes `elem` exts && case dropWhile isIdent s of { '|':_ -> True;_->False} ->+                        discard 1 >> lexQuasiQuote++        '|':']':_ | TemplateHaskell `elem` exts -> do+                        discard 2+                        return THCloseQuote++        '$':c:_ | isLower c && TemplateHaskell `elem` exts -> do+                        discard 1+                        id <- lexWhile isIdent+                        return $ THIdEscape id+                | c == '(' && TemplateHaskell `elem` exts -> do+                        discard 2+                        return THParenEscape+        -- end template haskell++        -- hsx+        '<':'%':c:_ | XmlSyntax `elem` exts -> do +                        case c of+                         '>' -> do discard 3+                                   pushExtContextL ChildCtxt+                                   return XChildTagOpen+                         _   -> do discard 2+                                   pushExtContextL CodeTagCtxt+                                   return XCodeTagOpen+        '<':c:_ | isAlpha c && XmlSyntax `elem` exts -> do+                        discard 1+                        pushExtContextL TagCtxt+                        return XStdTagOpen+        -- end hsx++        '(':'#':c:_ | UnboxedTuples `elem` exts && not (isHSymbol c) -> do discard 2 >> return LeftHashParen++        '#':')':_ | UnboxedTuples `elem` exts -> do discard 2 >> return RightHashParen++        '{':'|':_ | Generics `elem` exts -> do discard 2 >> return LeftCurlyBar++        '|':'}':_ | Generics `elem` exts -> do discard 2 >> return RightCurlyBar++        -- pragmas++        '{':'-':'#':_ -> do discard 3 >> lexPragmaStart++        '#':'-':'}':_ -> do discard 3 >> return PragmaEnd++        c:_ | isDigit c -> lexDecimalOrFloat++            | isUpper c -> lexConIdOrQual ""++            | isLower c || c == '_' -> do+                    idents <- lexIdents+                    case idents of+                     [ident] -> case lookup ident (reserved_ids ++ special_varids) of+                                 Just (keyword, scheme) -> do+                                    -- check if an extension keyword is enabled+                                    if isEnabled scheme exts+                                     then flagKW keyword >> return keyword+                                     else return $ VarId ident+                                 Nothing -> return $ VarId ident+                     _ -> return $ DVarId idents++            | isHSymbol c -> do+                    sym <- lexWhile isHSymbol+                    return $ case lookup sym (reserved_ops ++ special_varops) of+                              Just (t , scheme) ->+                                -- check if an extension op is enabled+                                if isEnabled scheme exts+                                 then t+                                 else case c of+                                        ':' -> ConSym sym+                                        _   -> VarSym sym+                              Nothing -> case c of+                                          ':' -> ConSym sym+                                          _   -> VarSym sym++            | otherwise -> do+                    discard 1+                    case c of++                        -- First the special symbols+                        '(' ->  return LeftParen+                        ')' ->  return RightParen+                        ',' ->  return Comma+                        ';' ->  return SemiColon+                        '[' ->  return LeftSquare+                        ']' ->  return RightSquare+                        '`' ->  return BackQuote+                        '{' -> do+                            pushContextL NoLayout+                            return LeftCurly+                        '}' -> do+                            popContextL "lexStdToken"+                            return RightCurly++                        '\'' -> lexCharacter+                        '"' ->  lexString++                        _ ->    fail ("Illegal character \'" ++ show c ++ "\'\n")++      where lexIdents :: Lex a [String]+            lexIdents = do+                ident <- lexWhile isIdent+                s <- getInput+                exts <- getExtensionsL+                case s of+                 -- This is the only way we can get more than one ident in the list+                 -- and it requires XmlSyntax to be on.+                 '-':c:_ | XmlSyntax `elem` exts && isAlpha c -> do+                        discard 1+                        idents <- lexIdents+                        return $ ident : idents+                 '#':_ | MagicHash `elem` exts -> do+                        discard 1+                        return [ident ++ "#"]+                 _ -> return [ident]++            lexQuasiQuote :: Lex a Token+            lexQuasiQuote = do+                -- We've seen and dropped [$ already+                ident <- lexWhile isIdent+                matchChar '|' "Malformed quasi-quote quoter"+                body <- lexQQBody+                return $ THQuasiQuote (ident, body)++            lexQQBody :: Lex a String+            lexQQBody = do+                s <- getInput+                case s of+                  '\\':']':_ -> do discard 2+                                   str <- lexQQBody+                                   return (']':str)+                  '\\':'|':_ -> do discard 2+                                   str <- lexQQBody+                                   return ('|':str)+                  '|':']':_  -> discard 2 >> return ""+                  '|':_ -> do discard 1+                              str <- lexQQBody+                              return ('|':str)+                  ']':_ -> do discard 1+                              str <- lexQQBody+                              return (']':str)+                  '\\':_ -> do discard 1+                               str <- lexQQBody+                               return ('\\':str)+                  '\n':_ -> do lexNewline+                               str <- lexQQBody+                               return ('\n':str)+                  []     -> fail "Unexpected end of input while lexing quasi-quoter"+                  _ -> do str <- lexWhile (not . (`elem` "\\|\n"))+                          rest <- lexQQBody+                          return (str++rest)++lexPragmaStart :: Lex a Token+lexPragmaStart = do+    lexWhile isSpace+    pr <- lexWhile isAlphaNum+    case lookup (map toLower pr) pragmas of+     Just (INLINE True) -> do+            s <- getInput+            case map toLower s of+             '_':'c':'o':'n':'l':'i':'k':'e':_  -> do+                      discard 8+                      return $ INLINE_CONLIKE+             _ -> return $ INLINE True+     Just SPECIALISE -> do+            s <- getInput+            case dropWhile isSpace $ map toLower s of+             'i':'n':'l':'i':'n':'e':_ -> do+                      lexWhile isSpace+                      discard 6+                      return $ SPECIALISE_INLINE True+             'n':'o':'i':'n':'l':'i':'n':'e':_ -> do+                        lexWhile isSpace+                        discard 8+                        return $ SPECIALISE_INLINE False+             'n':'o':'t':'i':'n':'l':'i':'n':'e':_ -> do+                        lexWhile isSpace+                        discard 9+                        return $ SPECIALISE_INLINE False+             _ -> return SPECIALISE++     Just (OPTIONS _) -> do     -- see, I promised we'd mask out the 'undefined'+            s <- getInput+            case s of+             '_':_  -> do+                discard 1+                com <- lexWhile isIdent+                rest <- lexRawPragma+                return $ OPTIONS (Just com, rest)+             x:_ | isSpace x -> do+                rest <- lexRawPragma+                return $ OPTIONS (Nothing, rest)+             _ -> fail "Malformed Options pragma"+{-     Just (CFILES _) -> do+            rest <- lexRawPragma+            return $ CFILES rest+     Just (INCLUDE _) -> do+            rest <- lexRawPragma+            return $ INCLUDE rest -}+     Just p ->  return p++     _      -> fail "Internal error: Unrecognised recognised pragma"+                  -- do rawStr <- lexRawPragma+                  -- return $ PragmaUnknown (pr, rawStr) -- no support for unrecognized pragmas, treat as comment+                  -- discard 3 -- #-}+                  -- topLexer -- we just discard it as a comment for now and restart -}++lexRawPragma :: Lex a String+lexRawPragma = do+    rpr <- lexRawPragmaAux+    return $ dropWhile isSpace rpr+ where lexRawPragmaAux = do+        rpr <- lexWhile (/='#')+        s <- getInput+        case s of+         '#':'-':'}':_  -> return rpr+         "" -> fail "End-of-file inside pragma"+         _ -> do+            discard 1+            rpr' <- lexRawPragma+            return $ rpr ++ '#':rpr'++lexDecimalOrFloat :: Lex a Token+lexDecimalOrFloat = do+    ds <- lexWhile isDigit+    rest <- getInput+    exts <- getExtensionsL+    case rest of+        ('.':d:_) | isDigit d -> do+                discard 1+                frac <- lexWhile isDigit+                let num = parseInteger 10 (ds ++ frac)+                    decimals = toInteger (length frac)+                (exponent, estr) <- do+                    rest2 <- getInput+                    case rest2 of+                        'e':_ -> lexExponent+                        'E':_ -> lexExponent+                        _     -> return (0,"")+                con <- lexHash FloatTok FloatTokHash (Right DoubleTokHash)+                return $ con ((num%1) * 10^^(exponent - decimals), ds ++ '.':frac ++ estr)+        e:_ | toLower e == 'e' -> do+                (exponent, estr) <- lexExponent+                con <- lexHash FloatTok FloatTokHash (Right DoubleTokHash)+                return $ con ((parseInteger 10 ds%1) * 10^^exponent, ds ++ estr)+        '#':'#':_ | MagicHash `elem` exts -> discard 2 >> return (WordTokHash (parseInteger 10 ds, ds))+        '#':_     | MagicHash `elem` exts -> discard 1 >> return (IntTokHash  (parseInteger 10 ds, ds))+        _         ->              return (IntTok      (parseInteger 10 ds, ds))++    where+    lexExponent :: Lex a (Integer, String)+    lexExponent = do+        (e:r) <- getInput+        discard 1   -- 'e' or 'E'+        case r of+         '+':d:_ | isDigit d -> do+            discard 1+            (n, str) <- lexDecimal+            return (n, e:'+':str)+         '-':d:_ | isDigit d -> do+            discard 1+            (n, str) <- lexDecimal+            return (negate n, e:'-':str)+         d:_ | isDigit d -> lexDecimal >>= \(n,str) -> return (n, e:str)+         _ -> fail "Float with missing exponent"++lexHash :: (b -> Token) -> (b -> Token) -> Either String (b -> Token) -> Lex a (b -> Token)+lexHash a b c = do+    exts <- getExtensionsL+    if MagicHash `elem` exts+     then do+        r <- getInput+        case r of+         '#':'#':_ -> case c of+                       Right c -> discard 2 >> return c+                       Left s  -> fail s+         '#':_     -> discard 1 >> return b+         _         ->              return a+     else return a++lexConIdOrQual :: String -> Lex a Token+lexConIdOrQual qual = do+        con <- lexWhile isIdent+        let conid | null qual = ConId con+                  | otherwise = QConId (qual,con)+            qual' | null qual = con+                  | otherwise = qual ++ '.':con+        just_a_conid <- alternative (return conid)+        rest <- getInput+        exts <- getExtensionsL+        case rest of+          '.':c:_+             | isLower c || c == '_' -> do  -- qualified varid?+                    discard 1+                    ident <- lexWhile isIdent+                    s <- getInput+                    exts <- getExtensionsL+                    ident' <- case s of+                               '#':_ | MagicHash `elem` exts -> discard 1 >> return (ident ++ "#")+                               _ -> return ident+                    case lookup ident' reserved_ids of+                       -- cannot qualify a reserved word+                       Just (_,scheme) | isEnabled scheme exts  -> just_a_conid+                       _ -> return (QVarId (qual', ident'))++             | isUpper c -> do      -- qualified conid?+                    discard 1+                    lexConIdOrQual qual'++             | isHSymbol c -> do    -- qualified symbol?+                    discard 1+                    sym <- lexWhile isHSymbol+                    exts <- getExtensionsL+                    case lookup sym reserved_ops of+                        -- cannot qualify a reserved operator+                        Just (_,scheme) | isEnabled scheme exts -> just_a_conid+                        _        -> return $ case c of+                                              ':' -> QConSym (qual', sym)+                                              _   -> QVarSym (qual', sym)++          '#':cs+            | null cs || +              not (isHSymbol $ head cs) && +              not (isIdent $ head cs) && MagicHash `elem` exts -> do+                discard 1+                case conid of+                 ConId con -> return $ ConId $ con ++ "#"+                 QConId (q,con) -> return $ QConId (q,con ++ "#")+          _ ->  return conid -- not a qualified thing++lexCharacter :: Lex a Token+lexCharacter = do   -- We need to keep track of not only character constants but also TH 'x and ''T+        -- We've seen ' so far+        s <- getInput+        exts <- getExtensionsL+        case s of+         '\'':_ | TemplateHaskell `elem` exts -> discard 1 >> return THTyQuote+         '\\':_ -> do+                    (c,raw) <- lexEscape+                    matchQuote+                    con <- lexHash Character CharacterHash+                            (Left "Double hash not available for character literals")+                    return (con (c, '\\':raw))+         c:'\'':_ -> do+                    discard 2+                    con <- lexHash Character CharacterHash+                            (Left "Double hash not available for character literals")+                    return (con (c, [c]))+         _ | TemplateHaskell `elem` exts -> return THVarQuote+         _ -> fail "Improper character constant or misplaced \'"++    where matchQuote = matchChar '\'' "Improperly terminated character constant"+++lexString :: Lex a Token+lexString = loop ("","")+    where+    loop (s,raw) = do+        r <- getInput+        exts <- getExtensionsL+        case r of+            '\\':'&':_ -> do+                    discard 2+                    loop (s, '&':'\\':raw)+            '\\':c:_ | isSpace c -> do+                        discard 1+                        wcs <- lexWhiteChars+                        matchChar '\\' "Illegal character in string gap"+                        loop (s, '\\':reverse wcs ++ '\\':raw)+                     | otherwise -> do+                        (ce, str) <- lexEscape+                        loop (ce:s, reverse str ++ '\\':raw)+            '"':'#':_ | MagicHash `elem` exts -> do+                        discard 2+                        return (StringHash (reverse s, reverse raw))+            '"':_ -> do+                discard 1+                return (StringTok (reverse s, reverse raw))+            c:_ | c /= '\n' -> do+                discard 1+                loop (c:s, c:raw)+            _ ->   fail "Improperly terminated string"++    lexWhiteChars :: Lex a String+    lexWhiteChars = do+        s <- getInput+        case s of+            '\n':_ -> do+                    lexNewline+                    wcs <- lexWhiteChars+                    return $ '\n':wcs+            '\t':_ -> do+                    lexTab+                    wcs <- lexWhiteChars+                    return $ '\t':wcs+            c:_ | isSpace c -> do+                    discard 1+                    wcs <- lexWhiteChars+                    return $ c:wcs+            _ -> return ""++lexEscape :: Lex a (Char, String)+lexEscape = do+    discard 1+    r <- getInput+    case r of++-- Production charesc from section B.2 (Note: \& is handled by caller)++        'a':_           -> discard 1 >> return ('\a', "a")+        'b':_           -> discard 1 >> return ('\b', "b")+        'f':_           -> discard 1 >> return ('\f', "f")+        'n':_           -> discard 1 >> return ('\n', "n")+        'r':_           -> discard 1 >> return ('\r', "r")+        't':_           -> discard 1 >> return ('\t', "t")+        'v':_           -> discard 1 >> return ('\v', "v")+        '\\':_          -> discard 1 >> return ('\\', "\\")+        '"':_           -> discard 1 >> return ('\"', "\"")+        '\'':_          -> discard 1 >> return ('\'', "\'")++-- Production ascii from section B.2++        '^':c:_         -> discard 2 >> cntrl c+        'N':'U':'L':_   -> discard 3 >> return ('\NUL', "NUL")+        'S':'O':'H':_   -> discard 3 >> return ('\SOH', "SOH")+        'S':'T':'X':_   -> discard 3 >> return ('\STX', "STX")+        'E':'T':'X':_   -> discard 3 >> return ('\ETX', "ETX")+        'E':'O':'T':_   -> discard 3 >> return ('\EOT', "EOT")+        'E':'N':'Q':_   -> discard 3 >> return ('\ENQ', "ENQ")+        'A':'C':'K':_   -> discard 3 >> return ('\ACK', "ACK")+        'B':'E':'L':_   -> discard 3 >> return ('\BEL', "BEL")+        'B':'S':_       -> discard 2 >> return ('\BS',  "BS")+        'H':'T':_       -> discard 2 >> return ('\HT',  "HT")+        'L':'F':_       -> discard 2 >> return ('\LF',  "LF")+        'V':'T':_       -> discard 2 >> return ('\VT',  "VT")+        'F':'F':_       -> discard 2 >> return ('\FF',  "FF")+        'C':'R':_       -> discard 2 >> return ('\CR',  "CR")+        'S':'O':_       -> discard 2 >> return ('\SO',  "SO")+        'S':'I':_       -> discard 2 >> return ('\SI',  "SI")+        'D':'L':'E':_   -> discard 3 >> return ('\DLE', "DLE")+        'D':'C':'1':_   -> discard 3 >> return ('\DC1', "DC1")+        'D':'C':'2':_   -> discard 3 >> return ('\DC2', "DC2")+        'D':'C':'3':_   -> discard 3 >> return ('\DC3', "DC3")+        'D':'C':'4':_   -> discard 3 >> return ('\DC4', "DC4")+        'N':'A':'K':_   -> discard 3 >> return ('\NAK', "NAK")+        'S':'Y':'N':_   -> discard 3 >> return ('\SYN', "SYN")+        'E':'T':'B':_   -> discard 3 >> return ('\ETB', "ETB")+        'C':'A':'N':_   -> discard 3 >> return ('\CAN', "CAN")+        'E':'M':_       -> discard 2 >> return ('\EM',  "EM")+        'S':'U':'B':_   -> discard 3 >> return ('\SUB', "SUB")+        'E':'S':'C':_   -> discard 3 >> return ('\ESC', "ESC")+        'F':'S':_       -> discard 2 >> return ('\FS',  "FS")+        'G':'S':_       -> discard 2 >> return ('\GS',  "GS")+        'R':'S':_       -> discard 2 >> return ('\RS',  "RS")+        'U':'S':_       -> discard 2 >> return ('\US',  "US")+        'S':'P':_       -> discard 2 >> return ('\SP',  "SP")+        'D':'E':'L':_   -> discard 3 >> return ('\DEL', "DEL")++-- Escaped numbers++        'o':c:_ | isOctDigit c -> do+                    discard 1+                    (n, raw) <- lexOctal+                    n <- checkChar n+                    return (n, 'o':raw)+        'x':c:_ | isHexDigit c -> do+                    discard 1+                    (n, raw) <- lexHexadecimal+                    n <- checkChar n+                    return (n, 'x':raw)+        c:_ | isDigit c -> do+                    (n, raw) <- lexDecimal+                    n <- checkChar n+                    return (n, raw)++        _       -> fail "Illegal escape sequence"++    where+    checkChar n | n <= 0x10FFFF = return (chr (fromInteger n))+    checkChar _                 = fail "Character constant out of range"++-- Production cntrl from section B.2++    cntrl :: Char -> Lex a (Char, String)+    cntrl c | c >= '@' && c <= '_' = return (chr (ord c - ord '@'), '^':c:[])+    cntrl _                        = fail "Illegal control character"++-- assumes at least one octal digit+lexOctal :: Lex a (Integer, String)+lexOctal = do+    ds <- lexWhile isOctDigit+    return (parseInteger 8 ds, ds)++-- assumes at least one hexadecimal digit+lexHexadecimal :: Lex a (Integer, String)+lexHexadecimal = do+    ds <- lexWhile isHexDigit+    return (parseInteger 16 ds, ds)++-- assumes at least one decimal digit+lexDecimal :: Lex a (Integer, String)+lexDecimal = do+    ds <- lexWhile isDigit+    return (parseInteger 10 ds, ds)++-- Stolen from Hugs's Prelude+parseInteger :: Integer -> String -> Integer+parseInteger radix ds =+    foldl1 (\n d -> n * radix + d) (map (toInteger . digitToInt) ds)++flagKW :: Token -> Lex a ()+flagKW t = when (t `elem` [KW_Do, KW_MDo]) flagDo++------------------------------------------------------------------+-- "Pretty" printing for tokens++showToken :: Token -> String+showToken t = case t of+  VarId s           -> s+  QVarId (q,s)      -> q ++ '.':s+  IDupVarId s       -> '?':s+  ILinVarId s       -> '%':s+  ConId s           -> s+  QConId (q,s)      -> q ++ '.':s+  DVarId ss         -> concat $ intersperse "-" ss+  VarSym s          -> s+  ConSym s          -> s+  QVarSym (q,s)     -> q ++ '.':s+  QConSym (q,s)     -> q ++ '.':s+  IntTok (_, s)         -> s+  FloatTok (_, s)       -> s+  Character (_, s)      -> '\'':s ++ "'"+  StringTok (_, s)      -> '"':s ++ "\""+  IntTokHash (_, s)     -> s ++ "#"+  WordTokHash (_, s)    -> s ++ "##"+  FloatTokHash (_, s)   -> s ++ "#"+  DoubleTokHash (_, s)  -> s ++ "##"+  CharacterHash (_, s)  -> '\'':s ++ "'#"+  StringHash (_, s)     -> '"':s ++ "\"#"+  LeftParen         -> "("+  RightParen        -> ")"+  LeftHashParen     -> "(#"+  RightHashParen    -> "#)"+  LeftCurlyBar      -> "{|"+  RightCurlyBar     -> "|}"+  SemiColon         -> ";"+  LeftCurly         -> "{"+  RightCurly        -> "}"+  VRightCurly       -> "virtual }"+  LeftSquare        -> "["+  RightSquare       -> "]"+  Comma             -> ","+  Underscore        -> "_"+  BackQuote         -> "`"+  Dot               -> "."+  DotDot            -> ".."+  Colon             -> ":"+  DoubleColon       -> "::"+  Equals            -> "="+  Backslash         -> "\\"+  Bar               -> "|"+  LeftArrow         -> "<-"+  RightArrow        -> "->"+  At                -> "@"+  Tilde             -> "~"+  DoubleArrow       -> "=>"+  Minus             -> "-"+  Exclamation       -> "!"+  Star              -> "*"+  LeftArrowTail     -> ">-"+  RightArrowTail    -> "-<"+  LeftDblArrowTail  -> ">>-"+  RightDblArrowTail -> "-<<"+  THExpQuote        -> "[|"+  THPatQuote        -> "[p|"+  THDecQuote        -> "[d|"+  THTypQuote        -> "[t|"+  THCloseQuote      -> "|]"+  THIdEscape s      -> '$':s+  THParenEscape     -> "$("+  THVarQuote        -> "'"+  THTyQuote         -> "''"+  THQuasiQuote (n,q) -> "[$" ++ n ++ "|" ++ q ++ "]"+  RPGuardOpen       -> "(|"+  RPGuardClose      -> "|)"+  RPCAt             -> "@:"+  XCodeTagOpen      -> "<%"+  XCodeTagClose     -> "%>"+  XStdTagOpen       -> "<"+  XStdTagClose      -> ">"+  XCloseTagOpen     -> "</"+  XEmptyTagClose    -> "/>"+  XPCDATA s         -> "PCDATA " ++ s+  XRPatOpen         -> "<["+  XRPatClose        -> "]>"+  PragmaEnd         -> "#-}"+  RULES             -> "{-# RULES"+  INLINE b          -> "{-# " ++ if b then "INLINE" else "NOINLINE"+  INLINE_CONLIKE    -> "{-# " ++ "INLINE_CONLIKE"+  SPECIALISE        -> "{-# SPECIALISE"+  SPECIALISE_INLINE b -> "{-# SPECIALISE " ++ if b then "INLINE" else "NOINLINE"+  SOURCE            -> "{-# SOURCE"+  DEPRECATED        -> "{-# DEPRECATED"+  WARNING           -> "{-# WARNING"+  SCC               -> "{-# SCC"+  GENERATED         -> "{-# GENERATED"+  CORE              -> "{-# CORE"+  UNPACK            -> "{-# UNPACK"+  OPTIONS (mt,s)    -> "{-# OPTIONS" ++ maybe "" (':':) mt ++ " ..."+--  CFILES  s         -> "{-# CFILES ..."+--  INCLUDE s         -> "{-# INCLUDE ..."+  LANGUAGE          -> "{-# LANGUAGE"+  ANN               -> "{-# ANN"+  KW_As         -> "as"+  KW_By         -> "by"+  KW_Case       -> "case"+  KW_Class      -> "class"+  KW_Data       -> "data"+  KW_Default    -> "default"+  KW_Deriving   -> "deriving"+  KW_Do         -> "do"+  KW_MDo        -> "mdo"+  KW_Else       -> "else"+  KW_Family     -> "family"+  KW_Forall     -> "forall"+  KW_Group      -> "group"+  KW_Hiding     -> "hiding"+  KW_If         -> "if"+  KW_Import     -> "import"+  KW_In         -> "in"+  KW_Infix      -> "infix"+  KW_InfixL     -> "infixl"+  KW_InfixR     -> "infixr"+  KW_Instance   -> "instance"+  KW_Let        -> "let"+  KW_Module     -> "module"+  KW_NewType    -> "newtype"+  KW_Of         -> "of"+  KW_Proc       -> "proc"+  KW_Rec        -> "rec"+  KW_Then       -> "then"+  KW_Type       -> "type"+  KW_Using      -> "using"+  KW_Where      -> "where"+  KW_Qualified  -> "qualified"+  KW_Foreign    -> "foreign"+  KW_Export     -> "export"+  KW_Safe       -> "safe"+  KW_Unsafe     -> "unsafe"+  KW_Threadsafe -> "threadsafe"+  KW_StdCall    -> "stdcall"+  KW_CCall      -> "ccall"++  EOF           -> "EOF"
src/Language/Haskell/Exts/InternalParser.ly view
@@ -39,7 +39,7 @@ > import Language.Haskell.Exts.Annotated.Syntax hiding ( Type(..), Exp(..), Asst(..), XAttr(..), FieldUpdate(..) ) > import Language.Haskell.Exts.Annotated.Syntax ( Type, Exp, Asst ) > import Language.Haskell.Exts.ParseMonad-> import Language.Haskell.Exts.Lexer+> import Language.Haskell.Exts.InternalLexer > import Language.Haskell.Exts.ParseUtils > import Language.Haskell.Exts.Annotated.Fixity > import Language.Haskell.Exts.SrcLoc
src/Language/Haskell/Exts/Lexer.hs view
@@ -1,1297 +1,43 @@-{-# OPTIONS_HADDOCK hide #-}--------------------------------------------------------------------------------- |--- Module      :  Language.Haskell.Exts.Annotated.Lexer--- Copyright   :  (c) The GHC Team, 1997-2000---                (c) Niklas Broberg, 2004-2009--- License     :  BSD-style (see the file LICENSE.txt)------ Maintainer  :  Niklas Broberg, d00nibro@chalmers.se--- Stability   :  stable--- Portability :  portable------ Lexer for Haskell, with some extensions.------------------------------------------------------------------------------------- ToDo: Introduce different tokens for decimal, octal and hexadecimal (?)--- ToDo: FloatTok should have three parts (integer part, fraction, exponent) (?)--- ToDo: Use a lexical analyser generator (lx?)--module Language.Haskell.Exts.Lexer (Token(..), showToken, lexer) where--import Language.Haskell.Exts.ParseMonad-import Language.Haskell.Exts.SrcLoc-import Language.Haskell.Exts.Comments-import Language.Haskell.Exts.Extension-import Language.Haskell.Exts.ExtScheme--import Data.Char-import Data.Ratio-import Data.List (intersperse)-import Control.Monad (when)---- import Debug.Trace (trace)--data Token-        = VarId String-        | QVarId (String,String)-        | IDupVarId (String)        -- duplicable implicit parameter-        | ILinVarId (String)        -- linear implicit parameter-        | ConId String-        | QConId (String,String)-        | DVarId [String]       -- to enable varid's with '-' in them-        | VarSym String-        | ConSym String-        | QVarSym (String,String)-        | QConSym (String,String)-        | IntTok (Integer, String)-        | FloatTok (Rational, String)-        | Character (Char, String)-        | StringTok (String, String)-        | IntTokHash (Integer, String)        -- 1#-        | WordTokHash (Integer, String)       -- 1##-        | FloatTokHash (Rational, String)     -- 1.0#-        | DoubleTokHash (Rational, String)    -- 1.0##-        | CharacterHash (Char, String)        -- c#-        | StringHash (String, String)         -- "Hello world!"#---- Symbols--        | LeftParen-        | RightParen-        | LeftHashParen-        | RightHashParen-        | LeftCurlyBar-        | RightCurlyBar-        | SemiColon-        | LeftCurly-        | RightCurly-        | VRightCurly           -- a virtual close brace-        | LeftSquare-        | RightSquare-        | Comma-        | Underscore-        | BackQuote---- Reserved operators--        | Dot           -- reserved for use with 'forall x . x'-        | DotDot-        | Colon-        | DoubleColon-        | Equals-        | Backslash-        | Bar-        | LeftArrow-        | RightArrow-        | At-        | Tilde-        | DoubleArrow-        | Minus-        | Exclamation-        | Star-        | LeftArrowTail         -- >--        | RightArrowTail        -- -<-        | LeftDblArrowTail      -- >>--        | RightDblArrowTail     -- -<<---- Template Haskell-        | THExpQuote            -- [| or [e|-        | THPatQuote            -- [p|-        | THDecQuote            -- [d|-        | THTypQuote            -- [t|-        | THCloseQuote          -- |]-        | THIdEscape (String)   -- dollar x-        | THParenEscape         -- dollar (-        | THVarQuote            -- 'x (but without the x)-        | THTyQuote             -- ''T (but without the T)-        | THQuasiQuote (String,String)  -- [$...|...]---- HaRP-        | RPGuardOpen       -- (|-        | RPGuardClose      -- |)-        | RPCAt             -- @:---- Hsx-        | XCodeTagOpen      -- <%-        | XCodeTagClose     -- %>-        | XStdTagOpen       -- <-        | XStdTagClose      -- >-        | XCloseTagOpen     -- </-        | XEmptyTagClose    -- />-        | XChildTagOpen     -- <%> (note that close doesn't exist, it's XCloseTagOpen followed by XCodeTagClose)-        | XPCDATA String-        | XRPatOpen             -- <[-        | XRPatClose            -- ]>---- Pragmas--        | PragmaEnd                     -- #-}-        | RULES-        | INLINE Bool-        | INLINE_CONLIKE-        | SPECIALISE-        | SPECIALISE_INLINE Bool-        | SOURCE-        | DEPRECATED-        | WARNING-        | SCC-        | GENERATED-        | CORE-        | UNPACK-        | OPTIONS (Maybe String,String)---        | CFILES  String---        | INCLUDE String-        | LANGUAGE-        | ANN---- Reserved Ids--        | KW_As-        | KW_By         -- transform list comprehensions-        | KW_Case-        | KW_Class-        | KW_Data-        | KW_Default-        | KW_Deriving-        | KW_Do-        | KW_MDo-        | KW_Else-        | KW_Family     -- indexed type families-        | KW_Forall     -- universal/existential types-        | KW_Group      -- transform list comprehensions-        | KW_Hiding-        | KW_If-        | KW_Import-        | KW_In-        | KW_Infix-        | KW_InfixL-        | KW_InfixR-        | KW_Instance-        | KW_Let-        | KW_Module-        | KW_NewType-        | KW_Of-        | KW_Proc       -- arrows-        | KW_Rec        -- arrows-        | KW_Then-        | KW_Type-        | KW_Using      -- transform list comprehensions-        | KW_Where-        | KW_Qualified--                -- FFI-        | KW_Foreign-        | KW_Export-        | KW_Safe-        | KW_Unsafe-        | KW_Threadsafe-        | KW_StdCall-        | KW_CCall-        | KW_CPlusPlus-        | KW_DotNet-        | KW_Jvm-        | KW_Js--        | EOF-        deriving (Eq,Show)--reserved_ops :: [(String,(Token, Maybe ExtScheme))]-reserved_ops = [- ( "..", (DotDot,       Nothing) ),- ( ":",  (Colon,        Nothing) ),- ( "::", (DoubleColon,  Nothing) ),- ( "=",  (Equals,       Nothing) ),- ( "\\", (Backslash,    Nothing) ),- ( "|",  (Bar,          Nothing) ),- ( "<-", (LeftArrow,    Nothing) ),- ( "->", (RightArrow,   Nothing) ),- ( "@",  (At,           Nothing) ),- ( "@:", (RPCAt,        Just (Any [RegularPatterns])) ),- ( "~",  (Tilde,        Nothing) ),- ( "=>", (DoubleArrow,  Nothing) ),- ( "*",  (Star,         Just (Any [KindSignatures])) ),- -- Arrows notation- ( "-<",  (LeftArrowTail,       Just (Any [Arrows])) ),- ( ">-",  (RightArrowTail,      Just (Any [Arrows])) ),- ( "-<<", (LeftDblArrowTail,    Just (Any [Arrows])) ),- ( ">>-", (RightDblArrowTail,   Just (Any [Arrows])) ),- -- Unicode notation- ( "\x2190",    (LeftArrow,     Just (Any  [UnicodeSyntax])) ),- ( "\x2192",    (RightArrow,    Just (Any  [UnicodeSyntax])) ),- ( "\x21d2",    (DoubleArrow,   Just (Any  [UnicodeSyntax])) ),- ( "\x2237",    (DoubleColon,   Just (Any  [UnicodeSyntax])) ),- ( "\x2919",    (LeftArrowTail,     Just (All [UnicodeSyntax, Arrows])) ),- ( "\x291a",    (RightArrowTail,    Just (All [UnicodeSyntax, Arrows])) ),- ( "\x291b",    (LeftDblArrowTail,  Just (All [UnicodeSyntax, Arrows])) ),- ( "\x291c",    (RightDblArrowTail, Just (All [UnicodeSyntax, Arrows])) ),- ( "\x2605",    (Star,              Just (All [UnicodeSyntax, KindSignatures])) )- ]--special_varops :: [(String,(Token, Maybe ExtScheme))]-special_varops = [- -- the dot is only a special symbol together with forall, but can still be used as function composition- ( ".",  (Dot,          Just (Any [ExplicitForAll, ExistentialQuantification])) ),- ( "-",  (Minus,        Nothing) ),- ( "!",  (Exclamation,  Nothing) )- ]--reserved_ids :: [(String,(Token, Maybe ExtScheme))]-reserved_ids = [- ( "_",         (Underscore,    Nothing) ),- ( "by",        (KW_By,         Just (Any [TransformListComp])) ),- ( "case",      (KW_Case,       Nothing) ),- ( "class",     (KW_Class,      Nothing) ),- ( "data",      (KW_Data,       Nothing) ),- ( "default",   (KW_Default,    Nothing) ),- ( "deriving",  (KW_Deriving,   Nothing) ),- ( "do",        (KW_Do,         Nothing) ),- ( "else",      (KW_Else,       Nothing) ),- ( "family",    (KW_Family,     Just (Any [TypeFamilies])) ),        -- indexed type families- ( "forall",    (KW_Forall,     Just (Any [ExplicitForAll, ExistentialQuantification])) ),    -- universal/existential quantification- ( "group",     (KW_Group,      Just (Any [TransformListComp])) ),- ( "if",        (KW_If,         Nothing) ),- ( "import",    (KW_Import,     Nothing) ),- ( "in",        (KW_In,         Nothing) ),- ( "infix",     (KW_Infix,      Nothing) ),- ( "infixl",    (KW_InfixL,     Nothing) ),- ( "infixr",    (KW_InfixR,     Nothing) ),- ( "instance",  (KW_Instance,   Nothing) ),- ( "let",       (KW_Let,        Nothing) ),- ( "mdo",       (KW_MDo,        Just (Any [RecursiveDo])) ),- ( "module",    (KW_Module,     Nothing) ),- ( "newtype",   (KW_NewType,    Nothing) ),- ( "of",        (KW_Of,         Nothing) ),- ( "proc",      (KW_Proc,       Just (Any [Arrows])) ),- ( "rec",       (KW_Rec,        Just (Any [Arrows])) ),- ( "then",      (KW_Then,       Nothing) ),- ( "type",      (KW_Type,       Nothing) ),- ( "using",     (KW_Using,      Just (Any [TransformListComp])) ),- ( "where",     (KW_Where,      Nothing) ),---- FFI- ( "foreign",   (KW_Foreign,    Just (Any [ForeignFunctionInterface])) ),---- Unicode- ( "\x2200",    (KW_Forall,     Just (All [UnicodeSyntax, ExplicitForAll])) )- ]---special_varids :: [(String,(Token, Maybe ExtScheme))]-special_varids = [- ( "as",        (KW_As,         Nothing) ),- ( "qualified", (KW_Qualified,  Nothing) ),- ( "hiding",    (KW_Hiding,     Nothing) ),---- FFI- ( "export",     (KW_Export,        Just (Any [ForeignFunctionInterface])) ),- ( "safe",       (KW_Safe,          Just (Any [ForeignFunctionInterface])) ),- ( "unsafe",     (KW_Unsafe,        Just (Any [ForeignFunctionInterface])) ),- ( "threadsafe", (KW_Threadsafe,    Just (Any [ForeignFunctionInterface])) ),- ( "stdcall",    (KW_StdCall,       Just (Any [ForeignFunctionInterface])) ),- ( "ccall",      (KW_CCall,         Just (Any [ForeignFunctionInterface])) ),- ( "cplusplus",  (KW_CPlusPlus,     Just (Any [ForeignFunctionInterface])) ),- ( "dotnet",     (KW_DotNet,        Just (Any [ForeignFunctionInterface])) ),- ( "jvm",        (KW_Jvm,           Just (Any [ForeignFunctionInterface])) ),- ( "js",         (KW_Js,            Just (Any [ForeignFunctionInterface])) )- ]--pragmas :: [(String,Token)]-pragmas = [- ( "rules",             RULES           ),- ( "inline",            INLINE True     ),- ( "noinline",          INLINE False    ),- ( "notinline",         INLINE False    ),- ( "specialise",        SPECIALISE      ),- ( "specialize",        SPECIALISE      ),- ( "source",            SOURCE          ),- ( "deprecated",        DEPRECATED      ),- ( "warning",           WARNING         ),- ( "ann",               ANN             ),- ( "scc",               SCC             ),- ( "generated",         GENERATED       ),- ( "core",              CORE            ),- ( "unpack",            UNPACK          ),- ( "language",          LANGUAGE        ),- ( "options",           OPTIONS undefined ) -- we'll tweak it before use - promise!--- ( "cfiles",            CFILES  undefined ), -- same here...--- ( "include",           INCLUDE undefined )  -- ...and here!- ]--isIdent, isHSymbol :: Char -> Bool-isIdent   c = isAlpha c || isDigit c || c == '\'' || c == '_'--isHSymbol c = c `elem` ":!#%&*./?@\\-" || ((isSymbol c || isPunctuation c) && not (c `elem` "(),;[]`{}_\"'"))--matchChar :: Char -> String -> Lex a ()-matchChar c msg = do-    s <- getInput-    if null s || head s /= c then fail msg else discard 1---- The top-level lexer.--- We need to know whether we are at the beginning of the line to decide--- whether to insert layout tokens.--lexer :: (Loc Token -> P a) -> P a-lexer = runL topLexer--topLexer :: Lex a (Loc Token)-topLexer = do-    b <- pullCtxtFlag-    if b then -- trace (show cf ++ ": " ++ show VRightCurly) $-              setBOL >> getSrcLocL >>= \l -> return (Loc (mkSrcSpan l l) VRightCurly) -- the lex context state flags that we must do an empty {} - UGLY-     else do-        bol <- checkBOL-        (bol, ws) <- lexWhiteSpace bol-        -- take care of whitespace in PCDATA-        ec <- getExtContext-        case ec of-         -- if there was no linebreak, and we are lexing PCDATA,-         -- then we want to care about the whitespace.-         -- We don't bother to test for XmlSyntax, since we-         -- couldn't end up in ChildCtxt otherwise.-         Just ChildCtxt | not bol && ws -> getSrcLocL >>= \l -> return $ Loc (mkSrcSpan l l) $ XPCDATA " "-         _ -> do startToken-                 sl <- getSrcLocL-                 t <- if bol then lexBOL    -- >>= \t -> trace ("BOL: " ++ show t) (return t)-                             else lexToken  -- >>= \t -> trace (show t) (return t)-                 el <- getSrcLocL-                 return $ Loc (mkSrcSpan sl el) t--lexWhiteSpace :: Bool -> Lex a (Bool, Bool)-lexWhiteSpace bol = do-    s <- getInput-    ignL <- ignoreLinePragmasL-    case s of-        -- If we find a recognised pragma, we don't want to treat it as a comment.-        '{':'-':'#':rest | isRecognisedPragma rest -> return (bol, False)-                         | isLinePragma rest && not ignL -> do -                            (l, fn) <- lexLinePragma-                            setSrcLineL l-                            setLineFilenameL fn-                            lexWhiteSpace True-        '{':'-':_ -> do-            loc <- getSrcLocL-            discard 2-            (bol, c) <- lexNestedComment bol ""-            loc2 <- getSrcLocL-            pushComment $ Comment True (mkSrcSpan loc loc2) (reverse c)-            (bol, _) <- lexWhiteSpace bol-            return (bol, True)-        '-':'-':s | all (== '-') (takeWhile isHSymbol s) -> do-            loc    <- getSrcLocL-            discard 2-            dashes <- lexWhile (== '-')-            rest   <- lexWhile (/= '\n')-            s' <- getInput-            loc2 <- getSrcLocL-            let com = Comment False (mkSrcSpan loc loc2) $ dashes ++ rest-            case s' of-                [] -> pushComment com >> return (False, True)-                _ -> do-                    pushComment com-                    lexNewline-                    lexWhiteSpace True-                    return (True, True)-        '\n':_ -> do-            lexNewline-            lexWhiteSpace True-            return (True, True)-        '\t':_ -> do-            lexTab-            (bol, _) <- lexWhiteSpace bol-            return (bol, True)-        c:_ | isSpace c -> do-            discard 1-            (bol, _) <- lexWhiteSpace bol-            return (bol, True)-        _ -> return (bol, False)--isRecognisedPragma, isLinePragma :: String -> Bool-isRecognisedPragma str = let pragma = map toLower . takeWhile isAlphaNum . dropWhile isSpace $ str-                          in case lookup pragma pragmas of-                              Nothing -> False-                              _       -> True--isLinePragma str = let pragma = map toLower . takeWhile isAlphaNum . dropWhile isSpace $ str-                    in case pragma of-                        "line"  -> True-                        _       -> False--lexLinePragma :: Lex a (Int, String)-lexLinePragma = do-    discard 3   -- {-#-    lexWhile isSpace-    discard 4   -- LINE-    lexWhile isSpace-    i <- lexWhile isDigit-    when (null i) $ fail "Improperly formatted LINE pragma"-    lexWhile isSpace-    matchChar '"' "Improperly formatted LINE pragma"-    fn <- lexWhile (/= '"')-    matchChar '"' "Impossible - lexLinePragma"-    lexWhile isSpace-    mapM (flip matchChar "Improperly formatted LINE pragma") "#-}"-    lexNewline-    return (read i, fn)--lexNestedComment :: Bool -> String -> Lex a (Bool, String)-lexNestedComment bol str = do-    s <- getInput-    case s of-        '-':'}':_ -> discard 2 >> return (bol, str)-        '{':'-':_ -> do-            discard 2-            (bol, c) <- lexNestedComment bol ("-{" ++ str) -- rest of the subcomment-            lexNestedComment bol ("}-" ++ c  ) -- rest of this comment-        '\t':_    -> lexTab >> lexNestedComment bol ('\t':str)-        '\n':_    -> lexNewline >> lexNestedComment True ('\n':str)-        c:_       -> discard 1 >> lexNestedComment bol (c:str)-        []        -> fail "Unterminated nested comment"---- When we are lexing the first token of a line, check whether we need to--- insert virtual semicolons or close braces due to layout.--lexBOL :: Lex a Token-lexBOL = do-    pos <- getOffside-    -- trace ("Off: " ++ (show pos)) $ do-    case pos of-        LT -> do-                -- trace "layout: inserting '}'\n" $-            -- Set col to 0, indicating that we're still at the-            -- beginning of the line, in case we need a semi-colon too.-            -- Also pop the context here, so that we don't insert-            -- another close brace before the parser can pop it.-            setBOL-            popContextL "lexBOL"-            return VRightCurly-        EQ ->-            -- trace "layout: inserting ';'\n" $-            return SemiColon-        GT -> lexToken--lexToken :: Lex a Token-lexToken = do-    ec <- getExtContext-    -- we don't bother to check XmlSyntax since we couldn't-    -- have ended up in a non-Nothing context if it wasn't-    -- enabled.-    case ec of-     Just HarpCtxt     -> lexHarpToken-     Just TagCtxt      -> lexTagCtxt-     Just CloseTagCtxt -> lexCloseTagCtxt-     Just ChildCtxt    -> lexChildCtxt-     Just CodeTagCtxt  -> lexCodeTagCtxt-     _         -> lexStdToken---lexChildCtxt :: Lex a Token-lexChildCtxt = do-    -- if we ever end up here, then XmlSyntax must be on.-    s <- getInput-    case s of-        '<':'%':'>':_ -> do discard 3-                            pushExtContextL ChildCtxt-                            return XChildTagOpen-        '<':'%':_ -> do discard 2-                        pushExtContextL CodeTagCtxt-                        return XCodeTagOpen-        '<':'/':_ -> do discard 2-                        popExtContextL "lexChildCtxt"-                        pushExtContextL CloseTagCtxt-                        return XCloseTagOpen-        '<':'[':_ -> do discard 2-                        pushExtContextL HarpCtxt-                        return XRPatOpen-        '<':_     -> do discard 1-                        pushExtContextL TagCtxt-                        return XStdTagOpen-        _     -> lexPCDATA---lexPCDATA :: Lex a Token-lexPCDATA = do-    -- if we ever end up here, then XmlSyntax must be on.-    s <- getInput-    case s of-        [] -> return EOF-        _  -> case s of-            '\n':_ -> do-                x <- lexNewline >> lexPCDATA-                case x of-                 XPCDATA p -> return $ XPCDATA $ '\n':p-                 EOF -> return EOF-            '<':_ -> return $ XPCDATA ""-            _ -> do let pcd = takeWhile (\c -> not $ elem c "<\n") s-                        l = length pcd-                    discard l-                    x <- lexPCDATA-                    case x of-                     XPCDATA pcd' -> return $ XPCDATA $ pcd ++ pcd'-                     EOF -> return EOF---lexCodeTagCtxt :: Lex a Token-lexCodeTagCtxt = do-    -- if we ever end up here, then XmlSyntax must be on.-    s <- getInput-    case s of-        '%':'>':_ -> do discard 2-                        popExtContextL "lexCodeTagContext"-                        return XCodeTagClose-        _     -> lexStdToken--lexCloseTagCtxt :: Lex a Token-lexCloseTagCtxt = do-    -- if we ever end up here, then XmlSyntax must be on.-    s <- getInput-    case s of-        '%':'>':_ -> do discard 2-                        popExtContextL "lexCloseTagCtxt"-                        return XCodeTagClose-        '>':_     -> do discard 1-                        popExtContextL "lexCloseTagCtxt"-                        return XStdTagClose-        _     -> lexStdToken--lexTagCtxt :: Lex a Token-lexTagCtxt = do-    -- if we ever end up here, then XmlSyntax must be on.-    s <- getInput-    case s of-        '/':'>':_ -> do discard 2-                        popExtContextL "lexTagCtxt: Empty tag"-                        return XEmptyTagClose-        '>':_     -> do discard 1-                        popExtContextL "lexTagCtxt: Standard tag"-                        pushExtContextL ChildCtxt-                        return XStdTagClose-        _     -> lexStdToken--lexHarpToken :: Lex a Token-lexHarpToken = do-    -- if we ever end up here, then RegularPatterns must be on.-    s <- getInput-    case s of-        ']':'>':_ -> do discard 2-                        popExtContextL "lexHarpToken"-                        return XRPatClose-        _     -> lexStdToken--lexStdToken :: Lex a Token-lexStdToken = do-    s <- getInput-    exts <- getExtensionsL-    case s of-        [] -> return EOF--        '0':c:d:_ | toLower c == 'o' && isOctDigit d -> do-                        discard 2-                        (n, str) <- lexOctal-                        return (IntTok (n, '0':c:str))-                  | toLower c == 'x' && isHexDigit d -> do-                        discard 2-                        (n, str) <- lexHexadecimal-                        return (IntTok (n, '0':c:str))--        -- implicit parameters-        '?':c:_ | isLower c && ImplicitParams `elem` exts -> do-                        discard 1-                        id <- lexWhile isIdent-                        return $ IDupVarId id--        '%':c:_ | isLower c && ImplicitParams `elem` exts -> do-                        discard 1-                        id <- lexWhile isIdent-                        return $ ILinVarId id-        -- end implicit parameters--        -- harp---        '(':'|':c:_  | isHSymbol c -> discard 1 >> return LeftParen-        '(':'|':c:_ | RegularPatterns `elem` exts && not (isHSymbol c) ->-                     do discard 2-                        return RPGuardOpen-        '|':')':_ | RegularPatterns `elem` exts ->-                     do discard 2-                        return RPGuardClose-        {- This is handled by the reserved_ops above.-        '@':':':_ | RegularPatterns `elem` exts ->-                     do discard 2-                        return RPCAt -}--        -- template haskell-        '[':'|':_ | TemplateHaskell `elem` exts -> do-                discard 2-                return $ THExpQuote--        '[':c:'|':_ | c == 'e' && TemplateHaskell `elem` exts -> do-                        discard 3-                        return $ THExpQuote-                    | c == 'p' && TemplateHaskell `elem` exts -> do-                        discard 3-                        return THPatQuote-                    | c == 'd' && TemplateHaskell `elem` exts -> do-                        discard 3-                        return THDecQuote-                    | c == 't' && TemplateHaskell `elem` exts -> do-                        discard 3-                        return THTypQuote-        '[':'$':c:_ | isLower c && QuasiQuotes `elem` exts ->-                        discard 2 >> lexQuasiQuote--        '[':c:s | isLower c && QuasiQuotes `elem` exts && case dropWhile isIdent s of { '|':_ -> True;_->False} ->-                        discard 1 >> lexQuasiQuote--        '|':']':_ | TemplateHaskell `elem` exts -> do-                        discard 2-                        return THCloseQuote--        '$':c:_ | isLower c && TemplateHaskell `elem` exts -> do-                        discard 1-                        id <- lexWhile isIdent-                        return $ THIdEscape id-                | c == '(' && TemplateHaskell `elem` exts -> do-                        discard 2-                        return THParenEscape-        -- end template haskell--        -- hsx-        '<':'%':c:_ | XmlSyntax `elem` exts -> do -                        case c of-                         '>' -> do discard 3-                                   pushExtContextL ChildCtxt-                                   return XChildTagOpen-                         _   -> do discard 2-                                   pushExtContextL CodeTagCtxt-                                   return XCodeTagOpen-        '<':c:_ | isAlpha c && XmlSyntax `elem` exts -> do-                        discard 1-                        pushExtContextL TagCtxt-                        return XStdTagOpen-        -- end hsx--        '(':'#':c:_ | UnboxedTuples `elem` exts && not (isHSymbol c) -> do discard 2 >> return LeftHashParen--        '#':')':_ | UnboxedTuples `elem` exts -> do discard 2 >> return RightHashParen--        '{':'|':_ | Generics `elem` exts -> do discard 2 >> return LeftCurlyBar--        '|':'}':_ | Generics `elem` exts -> do discard 2 >> return RightCurlyBar--        -- pragmas--        '{':'-':'#':_ -> do discard 3 >> lexPragmaStart--        '#':'-':'}':_ -> do discard 3 >> return PragmaEnd--        c:_ | isDigit c -> lexDecimalOrFloat--            | isUpper c -> lexConIdOrQual ""--            | isLower c || c == '_' -> do-                    idents <- lexIdents-                    case idents of-                     [ident] -> case lookup ident (reserved_ids ++ special_varids) of-                                 Just (keyword, scheme) -> do-                                    -- check if an extension keyword is enabled-                                    if isEnabled scheme exts-                                     then flagKW keyword >> return keyword-                                     else return $ VarId ident-                                 Nothing -> return $ VarId ident-                     _ -> return $ DVarId idents--            | isHSymbol c -> do-                    sym <- lexWhile isHSymbol-                    return $ case lookup sym (reserved_ops ++ special_varops) of-                              Just (t , scheme) ->-                                -- check if an extension op is enabled-                                if isEnabled scheme exts-                                 then t-                                 else case c of-                                        ':' -> ConSym sym-                                        _   -> VarSym sym-                              Nothing -> case c of-                                          ':' -> ConSym sym-                                          _   -> VarSym sym--            | otherwise -> do-                    discard 1-                    case c of--                        -- First the special symbols-                        '(' ->  return LeftParen-                        ')' ->  return RightParen-                        ',' ->  return Comma-                        ';' ->  return SemiColon-                        '[' ->  return LeftSquare-                        ']' ->  return RightSquare-                        '`' ->  return BackQuote-                        '{' -> do-                            pushContextL NoLayout-                            return LeftCurly-                        '}' -> do-                            popContextL "lexStdToken"-                            return RightCurly--                        '\'' -> lexCharacter-                        '"' ->  lexString--                        _ ->    fail ("Illegal character \'" ++ show c ++ "\'\n")--      where lexIdents :: Lex a [String]-            lexIdents = do-                ident <- lexWhile isIdent-                s <- getInput-                exts <- getExtensionsL-                case s of-                 -- This is the only way we can get more than one ident in the list-                 -- and it requires XmlSyntax to be on.-                 '-':c:_ | XmlSyntax `elem` exts && isAlpha c -> do-                        discard 1-                        idents <- lexIdents-                        return $ ident : idents-                 '#':_ | MagicHash `elem` exts -> do-                        discard 1-                        return [ident ++ "#"]-                 _ -> return [ident]--            lexQuasiQuote :: Lex a Token-            lexQuasiQuote = do-                -- We've seen and dropped [$ already-                ident <- lexWhile isIdent-                matchChar '|' "Malformed quasi-quote quoter"-                body <- lexQQBody-                return $ THQuasiQuote (ident, body)--            lexQQBody :: Lex a String-            lexQQBody = do-                s <- getInput-                case s of-                  '\\':']':_ -> do discard 2-                                   str <- lexQQBody-                                   return (']':str)-                  '\\':'|':_ -> do discard 2-                                   str <- lexQQBody-                                   return ('|':str)-                  '|':']':_  -> discard 2 >> return ""-                  '|':_ -> do discard 1-                              str <- lexQQBody-                              return ('|':str)-                  ']':_ -> do discard 1-                              str <- lexQQBody-                              return (']':str)-                  '\\':_ -> do discard 1-                               str <- lexQQBody-                               return ('\\':str)-                  '\n':_ -> do lexNewline-                               str <- lexQQBody-                               return ('\n':str)-                  []     -> fail "Unexpected end of input while lexing quasi-quoter"-                  _ -> do str <- lexWhile (not . (`elem` "\\|\n"))-                          rest <- lexQQBody-                          return (str++rest)--lexPragmaStart :: Lex a Token-lexPragmaStart = do-    lexWhile isSpace-    pr <- lexWhile isAlphaNum-    case lookup (map toLower pr) pragmas of-     Just (INLINE True) -> do-            s <- getInput-            case map toLower s of-             '_':'c':'o':'n':'l':'i':'k':'e':_  -> do-                      discard 8-                      return $ INLINE_CONLIKE-             _ -> return $ INLINE True-     Just SPECIALISE -> do-            s <- getInput-            case dropWhile isSpace $ map toLower s of-             'i':'n':'l':'i':'n':'e':_ -> do-                      lexWhile isSpace-                      discard 6-                      return $ SPECIALISE_INLINE True-             'n':'o':'i':'n':'l':'i':'n':'e':_ -> do-                        lexWhile isSpace-                        discard 8-                        return $ SPECIALISE_INLINE False-             'n':'o':'t':'i':'n':'l':'i':'n':'e':_ -> do-                        lexWhile isSpace-                        discard 9-                        return $ SPECIALISE_INLINE False-             _ -> return SPECIALISE--     Just (OPTIONS _) -> do     -- see, I promised we'd mask out the 'undefined'-            s <- getInput-            case s of-             '_':_  -> do-                discard 1-                com <- lexWhile isIdent-                rest <- lexRawPragma-                return $ OPTIONS (Just com, rest)-             x:_ | isSpace x -> do-                rest <- lexRawPragma-                return $ OPTIONS (Nothing, rest)-             _ -> fail "Malformed Options pragma"-{-     Just (CFILES _) -> do-            rest <- lexRawPragma-            return $ CFILES rest-     Just (INCLUDE _) -> do-            rest <- lexRawPragma-            return $ INCLUDE rest -}-     Just p ->  return p--     _      -> fail "Internal error: Unrecognised recognised pragma"-                  -- do rawStr <- lexRawPragma-                  -- return $ PragmaUnknown (pr, rawStr) -- no support for unrecognized pragmas, treat as comment-                  -- discard 3 -- #-}-                  -- topLexer -- we just discard it as a comment for now and restart -}--lexRawPragma :: Lex a String-lexRawPragma = do-    rpr <- lexRawPragmaAux-    return $ dropWhile isSpace rpr- where lexRawPragmaAux = do-        rpr <- lexWhile (/='#')-        s <- getInput-        case s of-         '#':'-':'}':_  -> return rpr-         "" -> fail "End-of-file inside pragma"-         _ -> do-            discard 1-            rpr' <- lexRawPragma-            return $ rpr ++ '#':rpr'--lexDecimalOrFloat :: Lex a Token-lexDecimalOrFloat = do-    ds <- lexWhile isDigit-    rest <- getInput-    exts <- getExtensionsL-    case rest of-        ('.':d:_) | isDigit d -> do-                discard 1-                frac <- lexWhile isDigit-                let num = parseInteger 10 (ds ++ frac)-                    decimals = toInteger (length frac)-                (exponent, estr) <- do-                    rest2 <- getInput-                    case rest2 of-                        'e':_ -> lexExponent-                        'E':_ -> lexExponent-                        _     -> return (0,"")-                con <- lexHash FloatTok FloatTokHash (Right DoubleTokHash)-                return $ con ((num%1) * 10^^(exponent - decimals), ds ++ '.':frac ++ estr)-        e:_ | toLower e == 'e' -> do-                (exponent, estr) <- lexExponent-                con <- lexHash FloatTok FloatTokHash (Right DoubleTokHash)-                return $ con ((parseInteger 10 ds%1) * 10^^exponent, ds ++ estr)-        '#':'#':_ | MagicHash `elem` exts -> discard 2 >> return (WordTokHash (parseInteger 10 ds, ds))-        '#':_     | MagicHash `elem` exts -> discard 1 >> return (IntTokHash  (parseInteger 10 ds, ds))-        _         ->              return (IntTok      (parseInteger 10 ds, ds))--    where-    lexExponent :: Lex a (Integer, String)-    lexExponent = do-        (e:r) <- getInput-        discard 1   -- 'e' or 'E'-        case r of-         '+':d:_ | isDigit d -> do-            discard 1-            (n, str) <- lexDecimal-            return (n, e:'+':str)-         '-':d:_ | isDigit d -> do-            discard 1-            (n, str) <- lexDecimal-            return (negate n, e:'-':str)-         d:_ | isDigit d -> lexDecimal >>= \(n,str) -> return (n, e:str)-         _ -> fail "Float with missing exponent"--lexHash :: (b -> Token) -> (b -> Token) -> Either String (b -> Token) -> Lex a (b -> Token)-lexHash a b c = do-    exts <- getExtensionsL-    if MagicHash `elem` exts-     then do-        r <- getInput-        case r of-         '#':'#':_ -> case c of-                       Right c -> discard 2 >> return c-                       Left s  -> fail s-         '#':_     -> discard 1 >> return b-         _         ->              return a-     else return a--lexConIdOrQual :: String -> Lex a Token-lexConIdOrQual qual = do-        con <- lexWhile isIdent-        let conid | null qual = ConId con-                  | otherwise = QConId (qual,con)-            qual' | null qual = con-                  | otherwise = qual ++ '.':con-        just_a_conid <- alternative (return conid)-        rest <- getInput-        exts <- getExtensionsL-        case rest of-          '.':c:_-             | isLower c || c == '_' -> do  -- qualified varid?-                    discard 1-                    ident <- lexWhile isIdent-                    s <- getInput-                    exts <- getExtensionsL-                    ident' <- case s of-                               '#':_ | MagicHash `elem` exts -> discard 1 >> return (ident ++ "#")-                               _ -> return ident-                    case lookup ident' reserved_ids of-                       -- cannot qualify a reserved word-                       Just (_,scheme) | isEnabled scheme exts  -> just_a_conid-                       _ -> return (QVarId (qual', ident'))--             | isUpper c -> do      -- qualified conid?-                    discard 1-                    lexConIdOrQual qual'--             | isHSymbol c -> do    -- qualified symbol?-                    discard 1-                    sym <- lexWhile isHSymbol-                    exts <- getExtensionsL-                    case lookup sym reserved_ops of-                        -- cannot qualify a reserved operator-                        Just (_,scheme) | isEnabled scheme exts -> just_a_conid-                        _        -> return $ case c of-                                              ':' -> QConSym (qual', sym)-                                              _   -> QVarSym (qual', sym)--          '#':cs-            | null cs || -              not (isHSymbol $ head cs) && -              not (isIdent $ head cs) && MagicHash `elem` exts -> do-                discard 1-                case conid of-                 ConId con -> return $ ConId $ con ++ "#"-                 QConId (q,con) -> return $ QConId (q,con ++ "#")-          _ ->  return conid -- not a qualified thing--lexCharacter :: Lex a Token-lexCharacter = do   -- We need to keep track of not only character constants but also TH 'x and ''T-        -- We've seen ' so far-        s <- getInput-        exts <- getExtensionsL-        case s of-         '\'':_ | TemplateHaskell `elem` exts -> discard 1 >> return THTyQuote-         '\\':_ -> do-                    (c,raw) <- lexEscape-                    matchQuote-                    con <- lexHash Character CharacterHash-                            (Left "Double hash not available for character literals")-                    return (con (c, '\\':raw))-         c:'\'':_ -> do-                    discard 2-                    con <- lexHash Character CharacterHash-                            (Left "Double hash not available for character literals")-                    return (con (c, [c]))-         _ | TemplateHaskell `elem` exts -> return THVarQuote-         _ -> fail "Improper character constant or misplaced \'"--    where matchQuote = matchChar '\'' "Improperly terminated character constant"---lexString :: Lex a Token-lexString = loop ("","")-    where-    loop (s,raw) = do-        r <- getInput-        exts <- getExtensionsL-        case r of-            '\\':'&':_ -> do-                    discard 2-                    loop (s, '&':'\\':raw)-            '\\':c:_ | isSpace c -> do-                        discard 1-                        wcs <- lexWhiteChars-                        matchChar '\\' "Illegal character in string gap"-                        loop (s, '\\':reverse wcs ++ '\\':raw)-                     | otherwise -> do-                        (ce, str) <- lexEscape-                        loop (ce:s, reverse str ++ '\\':raw)-            '"':'#':_ | MagicHash `elem` exts -> do-                        discard 2-                        return (StringHash (reverse s, reverse raw))-            '"':_ -> do-                discard 1-                return (StringTok (reverse s, reverse raw))-            c:_ | c /= '\n' -> do-                discard 1-                loop (c:s, c:raw)-            _ ->   fail "Improperly terminated string"--    lexWhiteChars :: Lex a String-    lexWhiteChars = do-        s <- getInput-        case s of-            '\n':_ -> do-                    lexNewline-                    wcs <- lexWhiteChars-                    return $ '\n':wcs-            '\t':_ -> do-                    lexTab-                    wcs <- lexWhiteChars-                    return $ '\t':wcs-            c:_ | isSpace c -> do-                    discard 1-                    wcs <- lexWhiteChars-                    return $ c:wcs-            _ -> return ""--lexEscape :: Lex a (Char, String)-lexEscape = do-    discard 1-    r <- getInput-    case r of---- Production charesc from section B.2 (Note: \& is handled by caller)--        'a':_           -> discard 1 >> return ('\a', "a")-        'b':_           -> discard 1 >> return ('\b', "b")-        'f':_           -> discard 1 >> return ('\f', "f")-        'n':_           -> discard 1 >> return ('\n', "n")-        'r':_           -> discard 1 >> return ('\r', "r")-        't':_           -> discard 1 >> return ('\t', "t")-        'v':_           -> discard 1 >> return ('\v', "v")-        '\\':_          -> discard 1 >> return ('\\', "\\")-        '"':_           -> discard 1 >> return ('\"', "\"")-        '\'':_          -> discard 1 >> return ('\'', "\'")---- Production ascii from section B.2--        '^':c:_         -> discard 2 >> cntrl c-        'N':'U':'L':_   -> discard 3 >> return ('\NUL', "NUL")-        'S':'O':'H':_   -> discard 3 >> return ('\SOH', "SOH")-        'S':'T':'X':_   -> discard 3 >> return ('\STX', "STX")-        'E':'T':'X':_   -> discard 3 >> return ('\ETX', "ETX")-        'E':'O':'T':_   -> discard 3 >> return ('\EOT', "EOT")-        'E':'N':'Q':_   -> discard 3 >> return ('\ENQ', "ENQ")-        'A':'C':'K':_   -> discard 3 >> return ('\ACK', "ACK")-        'B':'E':'L':_   -> discard 3 >> return ('\BEL', "BEL")-        'B':'S':_       -> discard 2 >> return ('\BS',  "BS")-        'H':'T':_       -> discard 2 >> return ('\HT',  "HT")-        'L':'F':_       -> discard 2 >> return ('\LF',  "LF")-        'V':'T':_       -> discard 2 >> return ('\VT',  "VT")-        'F':'F':_       -> discard 2 >> return ('\FF',  "FF")-        'C':'R':_       -> discard 2 >> return ('\CR',  "CR")-        'S':'O':_       -> discard 2 >> return ('\SO',  "SO")-        'S':'I':_       -> discard 2 >> return ('\SI',  "SI")-        'D':'L':'E':_   -> discard 3 >> return ('\DLE', "DLE")-        'D':'C':'1':_   -> discard 3 >> return ('\DC1', "DC1")-        'D':'C':'2':_   -> discard 3 >> return ('\DC2', "DC2")-        'D':'C':'3':_   -> discard 3 >> return ('\DC3', "DC3")-        'D':'C':'4':_   -> discard 3 >> return ('\DC4', "DC4")-        'N':'A':'K':_   -> discard 3 >> return ('\NAK', "NAK")-        'S':'Y':'N':_   -> discard 3 >> return ('\SYN', "SYN")-        'E':'T':'B':_   -> discard 3 >> return ('\ETB', "ETB")-        'C':'A':'N':_   -> discard 3 >> return ('\CAN', "CAN")-        'E':'M':_       -> discard 2 >> return ('\EM',  "EM")-        'S':'U':'B':_   -> discard 3 >> return ('\SUB', "SUB")-        'E':'S':'C':_   -> discard 3 >> return ('\ESC', "ESC")-        'F':'S':_       -> discard 2 >> return ('\FS',  "FS")-        'G':'S':_       -> discard 2 >> return ('\GS',  "GS")-        'R':'S':_       -> discard 2 >> return ('\RS',  "RS")-        'U':'S':_       -> discard 2 >> return ('\US',  "US")-        'S':'P':_       -> discard 2 >> return ('\SP',  "SP")-        'D':'E':'L':_   -> discard 3 >> return ('\DEL', "DEL")---- Escaped numbers--        'o':c:_ | isOctDigit c -> do-                    discard 1-                    (n, raw) <- lexOctal-                    n <- checkChar n-                    return (n, 'o':raw)-        'x':c:_ | isHexDigit c -> do-                    discard 1-                    (n, raw) <- lexHexadecimal-                    n <- checkChar n-                    return (n, 'x':raw)-        c:_ | isDigit c -> do-                    (n, raw) <- lexDecimal-                    n <- checkChar n-                    return (n, raw)--        _       -> fail "Illegal escape sequence"--    where-    checkChar n | n <= 0x10FFFF = return (chr (fromInteger n))-    checkChar _                 = fail "Character constant out of range"---- Production cntrl from section B.2--    cntrl :: Char -> Lex a (Char, String)-    cntrl c | c >= '@' && c <= '_' = return (chr (ord c - ord '@'), '^':c:[])-    cntrl _                        = fail "Illegal control character"---- assumes at least one octal digit-lexOctal :: Lex a (Integer, String)-lexOctal = do-    ds <- lexWhile isOctDigit-    return (parseInteger 8 ds, ds)---- assumes at least one hexadecimal digit-lexHexadecimal :: Lex a (Integer, String)-lexHexadecimal = do-    ds <- lexWhile isHexDigit-    return (parseInteger 16 ds, ds)---- assumes at least one decimal digit-lexDecimal :: Lex a (Integer, String)-lexDecimal = do-    ds <- lexWhile isDigit-    return (parseInteger 10 ds, ds)---- Stolen from Hugs's Prelude-parseInteger :: Integer -> String -> Integer-parseInteger radix ds =-    foldl1 (\n d -> n * radix + d) (map (toInteger . digitToInt) ds)--flagKW :: Token -> Lex a ()-flagKW t = when (t `elem` [KW_Do, KW_MDo]) flagDo----------------------------------------------------------------------- "Pretty" printing for tokens--showToken :: Token -> String-showToken t = case t of-  VarId s           -> s-  QVarId (q,s)      -> q ++ '.':s-  IDupVarId s       -> '?':s-  ILinVarId s       -> '%':s-  ConId s           -> s-  QConId (q,s)      -> q ++ '.':s-  DVarId ss         -> concat $ intersperse "-" ss-  VarSym s          -> s-  ConSym s          -> s-  QVarSym (q,s)     -> q ++ '.':s-  QConSym (q,s)     -> q ++ '.':s-  IntTok (_, s)         -> s-  FloatTok (_, s)       -> s-  Character (_, s)      -> '\'':s ++ "'"-  StringTok (_, s)      -> '"':s ++ "\""-  IntTokHash (_, s)     -> s ++ "#"-  WordTokHash (_, s)    -> s ++ "##"-  FloatTokHash (_, s)   -> s ++ "#"-  DoubleTokHash (_, s)  -> s ++ "##"-  CharacterHash (_, s)  -> '\'':s ++ "'#"-  StringHash (_, s)     -> '"':s ++ "\"#"-  LeftParen         -> "("-  RightParen        -> ")"-  LeftHashParen     -> "(#"-  RightHashParen    -> "#)"-  LeftCurlyBar      -> "{|"-  RightCurlyBar     -> "|}"-  SemiColon         -> ";"-  LeftCurly         -> "{"-  RightCurly        -> "}"-  VRightCurly       -> "virtual }"-  LeftSquare        -> "["-  RightSquare       -> "]"-  Comma             -> ","-  Underscore        -> "_"-  BackQuote         -> "`"-  Dot               -> "."-  DotDot            -> ".."-  Colon             -> ":"-  DoubleColon       -> "::"-  Equals            -> "="-  Backslash         -> "\\"-  Bar               -> "|"-  LeftArrow         -> "<-"-  RightArrow        -> "->"-  At                -> "@"-  Tilde             -> "~"-  DoubleArrow       -> "=>"-  Minus             -> "-"-  Exclamation       -> "!"-  Star              -> "*"-  LeftArrowTail     -> ">-"-  RightArrowTail    -> "-<"-  LeftDblArrowTail  -> ">>-"-  RightDblArrowTail -> "-<<"-  THExpQuote        -> "[|"-  THPatQuote        -> "[p|"-  THDecQuote        -> "[d|"-  THTypQuote        -> "[t|"-  THCloseQuote      -> "|]"-  THIdEscape s      -> '$':s-  THParenEscape     -> "$("-  THVarQuote        -> "'"-  THTyQuote         -> "''"-  THQuasiQuote (n,q) -> "[$" ++ n ++ "|" ++ q ++ "]"-  RPGuardOpen       -> "(|"-  RPGuardClose      -> "|)"-  RPCAt             -> "@:"-  XCodeTagOpen      -> "<%"-  XCodeTagClose     -> "%>"-  XStdTagOpen       -> "<"-  XStdTagClose      -> ">"-  XCloseTagOpen     -> "</"-  XEmptyTagClose    -> "/>"-  XPCDATA s         -> "PCDATA " ++ s-  XRPatOpen         -> "<["-  XRPatClose        -> "]>"-  PragmaEnd         -> "#-}"-  RULES             -> "{-# RULES"-  INLINE b          -> "{-# " ++ if b then "INLINE" else "NOINLINE"-  INLINE_CONLIKE    -> "{-# " ++ "INLINE_CONLIKE"-  SPECIALISE        -> "{-# SPECIALISE"-  SPECIALISE_INLINE b -> "{-# SPECIALISE " ++ if b then "INLINE" else "NOINLINE"-  SOURCE            -> "{-# SOURCE"-  DEPRECATED        -> "{-# DEPRECATED"-  WARNING           -> "{-# WARNING"-  SCC               -> "{-# SCC"-  GENERATED         -> "{-# GENERATED"-  CORE              -> "{-# CORE"-  UNPACK            -> "{-# UNPACK"-  OPTIONS (mt,s)    -> "{-# OPTIONS" ++ maybe "" (':':) mt ++ " ..."---  CFILES  s         -> "{-# CFILES ..."---  INCLUDE s         -> "{-# INCLUDE ..."-  LANGUAGE          -> "{-# LANGUAGE"-  ANN               -> "{-# ANN"-  KW_As         -> "as"-  KW_By         -> "by"-  KW_Case       -> "case"-  KW_Class      -> "class"-  KW_Data       -> "data"-  KW_Default    -> "default"-  KW_Deriving   -> "deriving"-  KW_Do         -> "do"-  KW_MDo        -> "mdo"-  KW_Else       -> "else"-  KW_Family     -> "family"-  KW_Forall     -> "forall"-  KW_Group      -> "group"-  KW_Hiding     -> "hiding"-  KW_If         -> "if"-  KW_Import     -> "import"-  KW_In         -> "in"-  KW_Infix      -> "infix"-  KW_InfixL     -> "infixl"-  KW_InfixR     -> "infixr"-  KW_Instance   -> "instance"-  KW_Let        -> "let"-  KW_Module     -> "module"-  KW_NewType    -> "newtype"-  KW_Of         -> "of"-  KW_Proc       -> "proc"-  KW_Rec        -> "rec"-  KW_Then       -> "then"-  KW_Type       -> "type"-  KW_Using      -> "using"-  KW_Where      -> "where"-  KW_Qualified  -> "qualified"-  KW_Foreign    -> "foreign"-  KW_Export     -> "export"-  KW_Safe       -> "safe"-  KW_Unsafe     -> "unsafe"-  KW_Threadsafe -> "threadsafe"-  KW_StdCall    -> "stdcall"-  KW_CCall      -> "ccall"--  EOF           -> "EOF"+-----------------------------------------------------------------------------+-- |+-- Module      :  Language.Haskell.Exts.Lexer+-- Copyright   :  (c) The GHC Team, 1997-2000+--                (c) Niklas Broberg, 2004-2012+-- License     :  BSD-style (see the file LICENSE.txt)+--+-- Maintainer  :  Niklas Broberg, niklas.broberg@chalmers.se+-- Stability   :  stable+-- Portability :  portable+--+-- Lexer for Haskell with extensions.+--+-----------------------------------------------------------------------------++module Language.Haskell.Exts.Lexer +    (+      lexTokenStream, lexTokenStreamWithMode,++      Token(..), Loc(..)++    ) where++import Language.Haskell.Exts.InternalLexer+import Language.Haskell.Exts.ParseMonad+import Language.Haskell.Exts.SrcLoc++-- | Lex a string into a list of Haskell 2010 source tokens.+lexTokenStream :: String -> ParseResult [Loc Token]+lexTokenStream = lexTokenStreamWithMode defaultParseMode++-- | Lex a string into a list of Haskell source tokens, using an explicit mode.+lexTokenStreamWithMode :: ParseMode -> String -> ParseResult [Loc Token]+lexTokenStreamWithMode mode str = runParserWithMode mode lexIt str+  where lexIt :: P [Loc Token]+        lexIt = runL go return+        go :: Lex [Loc Token] [Loc Token]+        go = do+          ltok <- topLexer+          case ltok of+            Loc _ EOF -> return []+            _ -> do ts <- go+                    return (ltok:ts)
src/Language/Haskell/Exts/Parser.hs view
@@ -1,3 +1,18 @@+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Language.Haskell.Exts.Parser
+-- Copyright   :  (c) The GHC Team, 1997-2000
+--                (c) Niklas Broberg, 2004-2012
+-- License     :  BSD-style (see the file LICENSE.txt)
+--
+-- Maintainer  :  Niklas Broberg, niklas.broberg@chalmers.se
+-- Stability   :  stable
+-- Portability :  portable
+--
+-- Parser for Haskell with extensions.
+--
+-----------------------------------------------------------------------------
+
 module Language.Haskell.Exts.Parser
             (
                 -- * General parsing