{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE PolymorphicComponents #-}
{-# LANGUAGE Safe #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Text.Parsec.Token
-- Copyright   :  (c) Daan Leijen 1999-2001, (c) Paolo Martini 2007
-- License     :  BSD-style (see the LICENSE file)
--
-- Maintainer  :  derek.a.elkins@gmail.com
-- Stability   :  provisional
-- Portability :  non-portable (uses local universal quantification: PolymorphicComponents)
--
-- A helper module to parse lexical elements (tokens). See 'makeTokenParser'
-- for a description of how to use it.
--
-----------------------------------------------------------------------------

{-# OPTIONS_GHC -fno-warn-name-shadowing #-}

module Text.Parsec.Token
    ( LanguageDef
    , GenLanguageDef (..)
    , TokenParser
    , GenTokenParser (..)
    , makeTokenParser
    ) where

import Data.Char ( isAlpha, toLower, toUpper, isSpace, digitToInt )
#if MIN_VERSION_base(4,7,0)
import Data.Typeable ( Typeable )
#endif
import Data.List ( nub, sort )
import Control.Monad.Identity (Identity)

import Text.Parsec.Prim
import Text.Parsec.Char
import Text.Parsec.Combinator

-----------------------------------------------------------
-- Language Definition
-----------------------------------------------------------

type LanguageDef st = GenLanguageDef String st Identity

-- | The @GenLanguageDef@ type is a record that contains all parameterizable
-- features of the "Text.Parsec.Token" module. The module "Text.Parsec.Language"
-- contains some default definitions.

data GenLanguageDef s u m
    = LanguageDef {

    -- | Describes the start of a block comment. Use the empty string if the
    -- language doesn't support block comments. For example \"\/*\".

    forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentStart   :: String,

    -- | Describes the end of a block comment. Use the empty string if the
    -- language doesn't support block comments. For example \"*\/\".

    forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentEnd     :: String,

    -- | Describes the start of a line comment. Use the empty string if the
    -- language doesn't support line comments. For example \"\/\/\".

    forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentLine    :: String,

    -- | Set to 'True' if the language supports nested block comments.

    forall s u (m :: * -> *). GenLanguageDef s u m -> Bool
nestedComments :: Bool,

    -- | This parser should accept any start characters of identifiers. For
    -- example @letter \<|> char \'_\'@.

    forall s u (m :: * -> *).
GenLanguageDef s u m -> ParsecT s u m Char
identStart     :: ParsecT s u m Char,

    -- | This parser should accept any legal tail characters of identifiers.
    -- For example @alphaNum \<|> char \'_\'@.

    forall s u (m :: * -> *).
GenLanguageDef s u m -> ParsecT s u m Char
identLetter    :: ParsecT s u m Char,

    -- | This parser should accept any start characters of operators. For
    -- example @oneOf \":!#$%&*+.\/\<=>?\@\\\\^|-~\"@

    forall s u (m :: * -> *).
GenLanguageDef s u m -> ParsecT s u m Char
opStart        :: ParsecT s u m Char,

    -- | This parser should accept any legal tail characters of operators.
    -- Note that this parser should even be defined if the language doesn't
    -- support user-defined operators, or otherwise the 'reservedOp'
    -- parser won't work correctly.

    forall s u (m :: * -> *).
GenLanguageDef s u m -> ParsecT s u m Char
opLetter       :: ParsecT s u m Char,

    -- | The list of reserved identifiers.

    forall s u (m :: * -> *). GenLanguageDef s u m -> [String]
reservedNames  :: [String],

    -- | The list of reserved operators.

    forall s u (m :: * -> *). GenLanguageDef s u m -> [String]
reservedOpNames:: [String],

    -- | Set to 'True' if the language is case sensitive.

    forall s u (m :: * -> *). GenLanguageDef s u m -> Bool
caseSensitive  :: Bool

    }
#if MIN_VERSION_base(4,7,0)
    deriving ( Typeable )
#endif

-----------------------------------------------------------
-- A first class module: TokenParser
-----------------------------------------------------------

type TokenParser st = GenTokenParser String st Identity

-- | The type of the record that holds lexical parsers that work on
-- @s@ streams with state @u@ over a monad @m@.

data GenTokenParser s u m
    = TokenParser {

        -- | This lexeme parser parses a legal identifier. Returns the identifier
        -- string. This parser will fail on identifiers that are reserved
        -- words. Legal identifier (start) characters and reserved words are
        -- defined in the 'LanguageDef' that is passed to
        -- 'makeTokenParser'. An @identifier@ is treated as
        -- a single token using 'try'.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
identifier       :: ParsecT s u m String,

        -- | The lexeme parser @reserved name@ parses @symbol
        -- name@, but it also checks that the @name@ is not a prefix of a
        -- valid identifier. A @reserved@ word is treated as a single token
        -- using 'try'.

        forall s u (m :: * -> *).
GenTokenParser s u m -> String -> ParsecT s u m ()
reserved         :: String -> ParsecT s u m (),

        -- | This lexeme parser parses a legal operator. Returns the name of the
        -- operator. This parser will fail on any operators that are reserved
        -- operators. Legal operator (start) characters and reserved operators
        -- are defined in the 'LanguageDef' that is passed to
        -- 'makeTokenParser'. An @operator@ is treated as a
        -- single token using 'try'.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
operator         :: ParsecT s u m String,

        -- |The lexeme parser @reservedOp name@ parses @symbol
        -- name@, but it also checks that the @name@ is not a prefix of a
        -- valid operator. A @reservedOp@ is treated as a single token using
        -- 'try'.

        forall s u (m :: * -> *).
GenTokenParser s u m -> String -> ParsecT s u m ()
reservedOp       :: String -> ParsecT s u m (),


        -- | This lexeme parser parses a single literal character. Returns the
        -- literal character value. This parsers deals correctly with escape
        -- sequences. The literal character is parsed according to the grammar
        -- rules defined in the Haskell report (which matches most programming
        -- languages quite closely).

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Char
charLiteral      :: ParsecT s u m Char,

        -- | This lexeme parser parses a literal string. Returns the literal
        -- string value. This parsers deals correctly with escape sequences and
        -- gaps. The literal string is parsed according to the grammar rules
        -- defined in the Haskell report (which matches most programming
        -- languages quite closely).

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
stringLiteral    :: ParsecT s u m String,

        -- | This lexeme parser parses a natural number (a non-negative whole
        -- number). Returns the value of the number. The number can be
        -- specified in 'decimal', 'hexadecimal' or
        -- 'octal'. The number is parsed according to the grammar
        -- rules in the Haskell report.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
natural          :: ParsecT s u m Integer,

        -- | This lexeme parser parses an integer (a whole number). This parser
        -- is like 'natural' except that it can be prefixed with
        -- sign (i.e. \'-\' or \'+\'). Returns the value of the number. The
        -- number can be specified in 'decimal', 'hexadecimal'
        -- or 'octal'. The number is parsed according
        -- to the grammar rules in the Haskell report.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
integer          :: ParsecT s u m Integer,

        -- | This lexeme parser parses a floating point value. Returns the value
        -- of the number. The number is parsed according to the grammar rules
        -- defined in the Haskell report.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Double
float            :: ParsecT s u m Double,

        -- | This lexeme parser parses either 'natural' or a 'float'.
        -- Returns the value of the number. This parsers deals with
        -- any overlap in the grammar rules for naturals and floats. The number
        -- is parsed according to the grammar rules defined in the Haskell report.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m (Either Integer Double)
naturalOrFloat   :: ParsecT s u m (Either Integer Double),

        -- | Parses a non-negative whole number in the decimal system. Returns the
        -- value of the number.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
decimal          :: ParsecT s u m Integer,

        -- | Parses a non-negative whole number in the hexadecimal system. The
        -- number should be prefixed with \"x\" or \"X\". Returns the value of the
        -- number.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
hexadecimal      :: ParsecT s u m Integer,

        -- | Parses a non-negative whole number in the octal system. The number
        -- should be prefixed with \"o\" or \"O\". Returns the value of the
        -- number.

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m Integer
octal            :: ParsecT s u m Integer,

        -- | Lexeme parser @symbol s@ parses 'string' @s@ and skips
        -- trailing white space.

        forall s u (m :: * -> *).
GenTokenParser s u m -> String -> ParsecT s u m String
symbol           :: String -> ParsecT s u m String,

        -- | @lexeme p@ first applies parser @p@ and then the 'whiteSpace'
        -- parser, returning the value of @p@. Every lexical
        -- token (lexeme) is defined using @lexeme@, this way every parse
        -- starts at a point without white space. Parsers that use @lexeme@ are
        -- called /lexeme/ parsers in this document.
        --
        -- The only point where the 'whiteSpace' parser should be
        -- called explicitly is the start of the main parser in order to skip
        -- any leading white space.
        --
        -- >    mainParser  = do{ whiteSpace
        -- >                     ; ds <- many (lexeme digit)
        -- >                     ; eof
        -- >                     ; return (sum ds)
        -- >                     }

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
lexeme           :: forall a. ParsecT s u m a -> ParsecT s u m a,

        -- | Parses any white space. White space consists of /zero/ or more
        -- occurrences of a 'space', a line comment or a block (multi
        -- line) comment. Block comments may be nested. How comments are
        -- started and ended is defined in the 'LanguageDef'
        -- that is passed to 'makeTokenParser'.

        forall s u (m :: * -> *). GenTokenParser s u m -> ParsecT s u m ()
whiteSpace       :: ParsecT s u m (),

        -- | Lexeme parser @parens p@ parses @p@ enclosed in parenthesis,
        -- returning the value of @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
parens           :: forall a. ParsecT s u m a -> ParsecT s u m a,

        -- | Lexeme parser @braces p@ parses @p@ enclosed in braces (\'{\' and
        -- \'}\'), returning the value of @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
braces           :: forall a. ParsecT s u m a -> ParsecT s u m a,

        -- | Lexeme parser @angles p@ parses @p@ enclosed in angle brackets (\'\<\'
        -- and \'>\'), returning the value of @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
angles           :: forall a. ParsecT s u m a -> ParsecT s u m a,

        -- | Lexeme parser @brackets p@ parses @p@ enclosed in brackets (\'[\'
        -- and \']\'), returning the value of @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
brackets         :: forall a. ParsecT s u m a -> ParsecT s u m a,

        -- | DEPRECATED: Use 'brackets'.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m a
squares          :: forall a. ParsecT s u m a -> ParsecT s u m a,

        -- | Lexeme parser |semi| parses the character \';\' and skips any
        -- trailing white space. Returns the string \";\".

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
semi             :: ParsecT s u m String,

        -- | Lexeme parser @comma@ parses the character \',\' and skips any
        -- trailing white space. Returns the string \",\".

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
comma            :: ParsecT s u m String,

        -- | Lexeme parser @colon@ parses the character \':\' and skips any
        -- trailing white space. Returns the string \":\".

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
colon            :: ParsecT s u m String,

        -- | Lexeme parser @dot@ parses the character \'.\' and skips any
        -- trailing white space. Returns the string \".\".

        forall s u (m :: * -> *).
GenTokenParser s u m -> ParsecT s u m String
dot              :: ParsecT s u m String,

        -- | Lexeme parser @semiSep p@ parses /zero/ or more occurrences of @p@
        -- separated by 'semi'. Returns a list of values returned by
        -- @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m [a]
semiSep          :: forall a . ParsecT s u m a -> ParsecT s u m [a],

        -- | Lexeme parser @semiSep1 p@ parses /one/ or more occurrences of @p@
        -- separated by 'semi'. Returns a list of values returned by @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m [a]
semiSep1         :: forall a . ParsecT s u m a -> ParsecT s u m [a],

        -- | Lexeme parser @commaSep p@ parses /zero/ or more occurrences of
        -- @p@ separated by 'comma'. Returns a list of values returned
        -- by @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m [a]
commaSep         :: forall a . ParsecT s u m a -> ParsecT s u m [a],

        -- | Lexeme parser @commaSep1 p@ parses /one/ or more occurrences of
        -- @p@ separated by 'comma'. Returns a list of values returned
        -- by @p@.

        forall s u (m :: * -> *).
GenTokenParser s u m
-> forall a. ParsecT s u m a -> ParsecT s u m [a]
commaSep1        :: forall a . ParsecT s u m a -> ParsecT s u m [a]
    }
#if MIN_VERSION_base(4,7,0)
    deriving ( Typeable )
#endif

-----------------------------------------------------------
-- Given a LanguageDef, create a token parser.
-----------------------------------------------------------

-- | The expression @makeTokenParser language@ creates a 'GenTokenParser'
-- record that contains lexical parsers that are
-- defined using the definitions in the @language@ record.
--
-- The use of this function is quite stylized - one imports the
-- appropriate language definition and selects the lexical parsers that
-- are needed from the resulting 'GenTokenParser'.
--
-- >  module Main where
-- >
-- >  import Text.Parsec
-- >  import qualified Text.Parsec.Token as P
-- >  import Text.Parsec.Language (haskellDef)
-- >
-- >  -- The parser
-- >  ...
-- >
-- >  expr  =   parens expr
-- >        <|> identifier
-- >        <|> ...
-- >
-- >
-- >  -- The lexer
-- >  lexer       = P.makeTokenParser haskellDef
-- >
-- >  parens      = P.parens lexer
-- >  braces      = P.braces lexer
-- >  identifier  = P.identifier lexer
-- >  reserved    = P.reserved lexer
-- >  ...

makeTokenParser :: (Stream s m Char)
                => GenLanguageDef s u m -> GenTokenParser s u m
{-# INLINABLE makeTokenParser #-}
makeTokenParser :: forall s (m :: * -> *) u.
Stream s m Char =>
GenLanguageDef s u m -> GenTokenParser s u m
makeTokenParser GenLanguageDef s u m
languageDef
    = TokenParser{ identifier :: ParsecT s u m String
identifier = ParsecT s u m String
identifier
                 , reserved :: String -> ParsecT s u m ()
reserved = String -> ParsecT s u m ()
reserved
                 , operator :: ParsecT s u m String
operator = ParsecT s u m String
operator
                 , reservedOp :: String -> ParsecT s u m ()
reservedOp = String -> ParsecT s u m ()
reservedOp

                 , charLiteral :: ParsecT s u m Char
charLiteral = ParsecT s u m Char
forall {u}. ParsecT s u m Char
charLiteral
                 , stringLiteral :: ParsecT s u m String
stringLiteral = ParsecT s u m String
forall {u}. ParsecT s u m String
stringLiteral
                 , natural :: ParsecT s u m Integer
natural = ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
natural
                 , integer :: ParsecT s u m Integer
integer = ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
integer
                 , float :: ParsecT s u m Double
float = ParsecT s u m Double
forall {u}. ParsecT s u m Double
float
                 , naturalOrFloat :: ParsecT s u m (Either Integer Double)
naturalOrFloat = ParsecT s u m (Either Integer Double)
forall {u}. ParsecT s u m (Either Integer Double)
naturalOrFloat
                 , decimal :: ParsecT s u m Integer
decimal = ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
decimal
                 , hexadecimal :: ParsecT s u m Integer
hexadecimal = ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
hexadecimal
                 , octal :: ParsecT s u m Integer
octal = ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
octal

                 , symbol :: String -> ParsecT s u m String
symbol = String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol
                 , lexeme :: forall a. ParsecT s u m a -> ParsecT s u m a
lexeme = ParsecT s u m a -> ParsecT s u m a
forall a. ParsecT s u m a -> ParsecT s u m a
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme
                 , whiteSpace :: ParsecT s u m ()
whiteSpace = ParsecT s u m ()
forall {u}. ParsecT s u m ()
whiteSpace

                 , parens :: forall a. ParsecT s u m a -> ParsecT s u m a
parens = ParsecT s u m a -> ParsecT s u m a
forall a. ParsecT s u m a -> ParsecT s u m a
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
parens
                 , braces :: forall a. ParsecT s u m a -> ParsecT s u m a
braces = ParsecT s u m a -> ParsecT s u m a
forall a. ParsecT s u m a -> ParsecT s u m a
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
braces
                 , angles :: forall a. ParsecT s u m a -> ParsecT s u m a
angles = ParsecT s u m a -> ParsecT s u m a
forall a. ParsecT s u m a -> ParsecT s u m a
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
angles
                 , brackets :: forall a. ParsecT s u m a -> ParsecT s u m a
brackets = ParsecT s u m a -> ParsecT s u m a
forall a. ParsecT s u m a -> ParsecT s u m a
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
brackets
                 , squares :: forall a. ParsecT s u m a -> ParsecT s u m a
squares = ParsecT s u m a -> ParsecT s u m a
forall a. ParsecT s u m a -> ParsecT s u m a
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
brackets
                 , semi :: ParsecT s u m String
semi = ParsecT s u m String
forall {u}. ParsecT s u m String
semi
                 , comma :: ParsecT s u m String
comma = ParsecT s u m String
forall {u}. ParsecT s u m String
comma
                 , colon :: ParsecT s u m String
colon = ParsecT s u m String
forall {u}. ParsecT s u m String
colon
                 , dot :: ParsecT s u m String
dot = ParsecT s u m String
forall {u}. ParsecT s u m String
dot
                 , semiSep :: forall a. ParsecT s u m a -> ParsecT s u m [a]
semiSep = ParsecT s u m a -> ParsecT s u m [a]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall {u} {a}. ParsecT s u m a -> ParsecT s u m [a]
semiSep
                 , semiSep1 :: forall a. ParsecT s u m a -> ParsecT s u m [a]
semiSep1 = ParsecT s u m a -> ParsecT s u m [a]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall {u} {a}. ParsecT s u m a -> ParsecT s u m [a]
semiSep1
                 , commaSep :: forall a. ParsecT s u m a -> ParsecT s u m [a]
commaSep = ParsecT s u m a -> ParsecT s u m [a]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall {u} {a}. ParsecT s u m a -> ParsecT s u m [a]
commaSep
                 , commaSep1 :: forall a. ParsecT s u m a -> ParsecT s u m [a]
commaSep1 = ParsecT s u m a -> ParsecT s u m [a]
forall a. ParsecT s u m a -> ParsecT s u m [a]
forall {u} {a}. ParsecT s u m a -> ParsecT s u m [a]
commaSep1
                 }
    where

    -----------------------------------------------------------
    -- Bracketing
    -----------------------------------------------------------
    parens :: ParsecT s u m a -> ParsecT s u m a
parens ParsecT s u m a
p        = ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
"(") (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
")") ParsecT s u m a
p
    braces :: ParsecT s u m a -> ParsecT s u m a
braces ParsecT s u m a
p        = ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
"{") (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
"}") ParsecT s u m a
p
    angles :: ParsecT s u m a -> ParsecT s u m a
angles ParsecT s u m a
p        = ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
"<") (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
">") ParsecT s u m a
p
    brackets :: ParsecT s u m a -> ParsecT s u m a
brackets ParsecT s u m a
p      = ParsecT s u m String
-> ParsecT s u m String -> ParsecT s u m a -> ParsecT s u m a
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
"[") (String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
"]") ParsecT s u m a
p

    semi :: ParsecT s u m String
semi            = String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
";"
    comma :: ParsecT s u m String
comma           = String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
","
    dot :: ParsecT s u m String
dot             = String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
"."
    colon :: ParsecT s u m String
colon           = String -> ParsecT s u m String
forall {u}. String -> ParsecT s u m String
symbol String
":"

    commaSep :: ParsecT s u m a -> ParsecT s u m [a]
commaSep ParsecT s u m a
p      = ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m [a]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy ParsecT s u m a
p ParsecT s u m String
forall {u}. ParsecT s u m String
comma
    semiSep :: ParsecT s u m a -> ParsecT s u m [a]
semiSep ParsecT s u m a
p       = ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m [a]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy ParsecT s u m a
p ParsecT s u m String
forall {u}. ParsecT s u m String
semi

    commaSep1 :: ParsecT s u m a -> ParsecT s u m [a]
commaSep1 ParsecT s u m a
p     = ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m [a]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy1 ParsecT s u m a
p ParsecT s u m String
forall {u}. ParsecT s u m String
comma
    semiSep1 :: ParsecT s u m a -> ParsecT s u m [a]
semiSep1 ParsecT s u m a
p      = ParsecT s u m a -> ParsecT s u m String -> ParsecT s u m [a]
forall s (m :: * -> *) t u a sep.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m sep -> ParsecT s u m [a]
sepBy1 ParsecT s u m a
p ParsecT s u m String
forall {u}. ParsecT s u m String
semi


    -----------------------------------------------------------
    -- Chars & Strings
    -----------------------------------------------------------
    charLiteral :: ParsecT s u m Char
charLiteral     = ParsecT s u m Char -> ParsecT s u m Char
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (ParsecT s u m Char
-> ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\'')
                                      (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\'' ParsecT s u m Char -> String -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"end of character")
                                      ParsecT s u m Char
forall {u}. ParsecT s u m Char
characterChar )
                    ParsecT s u m Char -> String -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"character"

    characterChar :: ParsecT s u m Char
characterChar   = ParsecT s u m Char
forall {u}. ParsecT s u m Char
charLetter ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Char
forall {u}. ParsecT s u m Char
charEscape
                    ParsecT s u m Char -> String -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"literal character"

    charEscape :: ParsecT s u m Char
charEscape      = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'; escapeCode }
    charLetter :: ParsecT s u m Char
charLetter      = (Char -> Bool) -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy (\Char
c -> (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\'') Bool -> Bool -> Bool
&& (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\\') Bool -> Bool -> Bool
&& (Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
> Char
'\026'))



    stringLiteral :: ParsecT s u m String
stringLiteral   = ParsecT s u m String -> ParsecT s u m String
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (
                      do{ str <- ParsecT s u m Char
-> ParsecT s u m Char
-> ParsecT s u m [Maybe Char]
-> ParsecT s u m [Maybe Char]
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"')
                                         (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'"' ParsecT s u m Char -> String -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"end of string")
                                         (ParsecT s u m (Maybe Char) -> ParsecT s u m [Maybe Char]
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m [a]
many ParsecT s u m (Maybe Char)
forall {u}. ParsecT s u m (Maybe Char)
stringChar)
                        ; return (foldr (maybe id (:)) "" str)
                        }
                      ParsecT s u m String -> String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"literal string")

    stringChar :: ParsecT s u m (Maybe Char)
stringChar      =   do{ c <- ParsecT s u m Char
forall {u}. ParsecT s u m Char
stringLetter; return (Just c) }
                    ParsecT s u m (Maybe Char)
-> ParsecT s u m (Maybe Char) -> ParsecT s u m (Maybe Char)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m (Maybe Char)
forall {u}. ParsecT s u m (Maybe Char)
stringEscape
                    ParsecT s u m (Maybe Char) -> String -> ParsecT s u m (Maybe Char)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"string character"

    stringLetter :: ParsecT s u m Char
stringLetter    = (Char -> Bool) -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy (\Char
c -> (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'"') Bool -> Bool -> Bool
&& (Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\\') Bool -> Bool -> Bool
&& (Char
c Char -> Char -> Bool
forall a. Ord a => a -> a -> Bool
> Char
'\026'))

    stringEscape :: ParsecT s u m (Maybe Char)
stringEscape    = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'\\'
                        ;     do{ _ <- escapeGap  ; return Nothing }
                          <|> do{ _ <- escapeEmpty; return Nothing }
                          <|> do{ esc <- escapeCode; return (Just esc) }
                        }

    escapeEmpty :: ParsecT s u m Char
escapeEmpty     = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'&'
    escapeGap :: ParsecT s u m Char
escapeGap       = do{ _ <- ParsecT s u m Char -> ParsecT s u m String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
space
                        ; char '\\' <?> "end of string gap"
                        }



    -- escape codes
    escapeCode :: ParsecT s u m Char
escapeCode      = ParsecT s u m Char
forall {u}. ParsecT s u m Char
charEsc ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Char
forall {u}. ParsecT s u m Char
charNum ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Char
forall {u}. ParsecT s u m Char
charAscii ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Char
forall {u}. ParsecT s u m Char
charControl
                    ParsecT s u m Char -> String -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"escape code"

    charControl :: ParsecT s u m Char
charControl     = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'^'
                        ; code <- upper
                        ; return (toEnum (fromEnum code - fromEnum 'A' + 1))
                        }

    charNum :: ParsecT s u m Char
charNum         = do{ code <- ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
decimal
                                  ParsecT s u m Integer
-> ParsecT s u m Integer -> ParsecT s u m Integer
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'o'; number 8 octDigit }
                                  ParsecT s u m Integer
-> ParsecT s u m Integer -> ParsecT s u m Integer
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'x'; number 16 hexDigit }
                        ; if code > 0x10FFFF
                          then fail "invalid escape sequence"
                          else return (toEnum (fromInteger code))
                        }

    charEsc :: ParsecT s u m Char
charEsc         = [ParsecT s u m Char] -> ParsecT s u m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice (((Char, Char) -> ParsecT s u m Char)
-> [(Char, Char)] -> [ParsecT s u m Char]
forall a b. (a -> b) -> [a] -> [b]
map (Char, Char) -> ParsecT s u m Char
forall {s} {m :: * -> *} {b} {u}.
Stream s m Char =>
(Char, b) -> ParsecT s u m b
parseEsc [(Char, Char)]
escMap)
                    where
                      parseEsc :: (Char, b) -> ParsecT s u m b
parseEsc (Char
c,b
code)     = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c; return code }

    charAscii :: ParsecT s u m Char
charAscii       = [ParsecT s u m Char] -> ParsecT s u m Char
forall s (m :: * -> *) t u a.
Stream s m t =>
[ParsecT s u m a] -> ParsecT s u m a
choice (((String, Char) -> ParsecT s u m Char)
-> [(String, Char)] -> [ParsecT s u m Char]
forall a b. (a -> b) -> [a] -> [b]
map (String, Char) -> ParsecT s u m Char
forall {s} {m :: * -> *} {a} {u}.
Stream s m Char =>
(String, a) -> ParsecT s u m a
parseAscii [(String, Char)]
asciiMap)
                    where
                      parseAscii :: (String, a) -> ParsecT s u m a
parseAscii (String
asc,a
code) = ParsecT s u m a -> ParsecT s u m a
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (do{ _ <- String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
asc; return code })


    -- escape code tables
    escMap :: [(Char, Char)]
escMap          = String -> String -> [(Char, Char)]
forall a b. [a] -> [b] -> [(a, b)]
zip (String
"abfnrtv\\\"\'") (String
"\a\b\f\n\r\t\v\\\"\'")
    asciiMap :: [(String, Char)]
asciiMap        = [String] -> String -> [(String, Char)]
forall a b. [a] -> [b] -> [(a, b)]
zip ([String]
ascii3codes [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
ascii2codes) (String
ascii3 String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ascii2)

    ascii2codes :: [String]
ascii2codes     = [String
"BS",String
"HT",String
"LF",String
"VT",String
"FF",String
"CR",String
"SO",String
"SI",String
"EM",
                       String
"FS",String
"GS",String
"RS",String
"US",String
"SP"]
    ascii3codes :: [String]
ascii3codes     = [String
"NUL",String
"SOH",String
"STX",String
"ETX",String
"EOT",String
"ENQ",String
"ACK",String
"BEL",
                       String
"DLE",String
"DC1",String
"DC2",String
"DC3",String
"DC4",String
"NAK",String
"SYN",String
"ETB",
                       String
"CAN",String
"SUB",String
"ESC",String
"DEL"]

    ascii2 :: String
ascii2          = [Char
'\BS',Char
'\HT',Char
'\LF',Char
'\VT',Char
'\FF',Char
'\CR',Char
'\SO',Char
'\SI',
                       Char
'\EM',Char
'\FS',Char
'\GS',Char
'\RS',Char
'\US',Char
'\SP']
    ascii3 :: String
ascii3          = [Char
'\NUL',Char
'\SOH',Char
'\STX',Char
'\ETX',Char
'\EOT',Char
'\ENQ',Char
'\ACK',
                       Char
'\BEL',Char
'\DLE',Char
'\DC1',Char
'\DC2',Char
'\DC3',Char
'\DC4',Char
'\NAK',
                       Char
'\SYN',Char
'\ETB',Char
'\CAN',Char
'\SUB',Char
'\ESC',Char
'\DEL']


    -----------------------------------------------------------
    -- Numbers
    -----------------------------------------------------------
    naturalOrFloat :: ParsecT s u m (Either Integer Double)
naturalOrFloat  = ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (ParsecT s u m (Either Integer Double)
forall {u}. ParsecT s u m (Either Integer Double)
natFloat) ParsecT s u m (Either Integer Double)
-> String -> ParsecT s u m (Either Integer Double)
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"number"

    float :: ParsecT s u m Double
float           = ParsecT s u m Double -> ParsecT s u m Double
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme ParsecT s u m Double
forall {u}. ParsecT s u m Double
floating   ParsecT s u m Double -> String -> ParsecT s u m Double
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"float"
    integer :: ParsecT s u m Integer
integer         = ParsecT s u m Integer -> ParsecT s u m Integer
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
int        ParsecT s u m Integer -> String -> ParsecT s u m Integer
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"integer"
    natural :: ParsecT s u m Integer
natural         = ParsecT s u m Integer -> ParsecT s u m Integer
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
nat        ParsecT s u m Integer -> String -> ParsecT s u m Integer
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"natural"


    -- floats
    floating :: ParsecT s u m Double
floating        = do{ n <- ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
decimal
                        ; fractExponent n
                        }


    natFloat :: ParsecT s u m (Either Integer Double)
natFloat        = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'0'
                        ; zeroNumFloat
                        }
                      ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m (Either Integer Double)
forall {u}. ParsecT s u m (Either Integer Double)
decimalFloat

    zeroNumFloat :: ParsecT s u m (Either Integer Double)
zeroNumFloat    =  do{ n <- ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
hexadecimal ParsecT s u m Integer
-> ParsecT s u m Integer -> ParsecT s u m Integer
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
octal
                         ; return (Left n)
                         }
                    ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m (Either Integer Double)
forall {u}. ParsecT s u m (Either Integer Double)
decimalFloat
                    ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Integer -> ParsecT s u m (Either Integer Double)
forall {b} {a} {u} {a}.
(Read b, Show a) =>
a -> ParsecT s u m (Either a b)
fractFloat (Integer
0 :: Integer)
                    ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
-> ParsecT s u m (Either Integer Double)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Either Integer Double -> ParsecT s u m (Either Integer Double)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return (Integer -> Either Integer Double
forall a b. a -> Either a b
Left Integer
0)

    decimalFloat :: ParsecT s u m (Either Integer Double)
decimalFloat    = do{ n <- ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
decimal
                        ; option (Left n)
                                 (fractFloat n)
                        }

    fractFloat :: a -> ParsecT s u m (Either a b)
fractFloat a
n    = do{ f <- a -> ParsecT s u m b
forall {a} {a} {u}. (Read a, Show a) => a -> ParsecT s u m a
fractExponent a
n
                        ; return (Right f)
                        }

    fractExponent :: a -> ParsecT s u m a
fractExponent a
n = do{ fract <- ParsecT s u m String
forall {u}. ParsecT s u m String
fraction
                        ; expo  <- option "" exponent'
                        ; readDouble (show n ++ fract ++ expo)
                        }
                    ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|>
                      do{ expo <- ParsecT s u m String
forall {u}. ParsecT s u m String
exponent'
                        ; readDouble (show n ++ expo)
                        }
                      where
                        readDouble :: String -> ParsecT s u m a
readDouble String
s =
                          case ReadS a
forall a. Read a => ReadS a
reads String
s of
                            [(a
x, String
"")] -> a -> ParsecT s u m a
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
                            [(a, String)]
_         -> ParsecT s u m a
forall s u (m :: * -> *) a. ParsecT s u m a
parserZero

    fraction :: ParsecT s u m String
fraction        = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'.'
                        ; digits <- many1 digit <?> "fraction"
                        ; return ('.' : digits)
                        }
                      ParsecT s u m String -> String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"fraction"

    exponent' :: ParsecT s u m String
exponent'       = do{ _ <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"eE"
                        ; sign' <- fmap (:[]) (oneOf "+-") <|> return ""
                        ; e <- decimal <?> "exponent"
                        ; return ('e' : sign' ++ show e)
                        }
                      ParsecT s u m String -> String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"exponent"


    -- integers and naturals
    int :: ParsecT s u m Integer
int             = do{ f <- ParsecT s u m (Integer -> Integer)
-> ParsecT s u m (Integer -> Integer)
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme ParsecT s u m (Integer -> Integer)
forall {u}. ParsecT s u m (Integer -> Integer)
sign
                        ; n <- nat
                        ; return (f n)
                        }

    sign :: ParsecT s u m (Integer -> Integer)
sign            =   (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'-' ParsecT s u m Char
-> ParsecT s u m (Integer -> Integer)
-> ParsecT s u m (Integer -> Integer)
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Integer -> Integer) -> ParsecT s u m (Integer -> Integer)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Integer -> Integer
forall a. Num a => a -> a
negate)
                    ParsecT s u m (Integer -> Integer)
-> ParsecT s u m (Integer -> Integer)
-> ParsecT s u m (Integer -> Integer)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'+' ParsecT s u m Char
-> ParsecT s u m (Integer -> Integer)
-> ParsecT s u m (Integer -> Integer)
forall a b. ParsecT s u m a -> ParsecT s u m b -> ParsecT s u m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Integer -> Integer) -> ParsecT s u m (Integer -> Integer)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Integer -> Integer
forall a. a -> a
id)
                    ParsecT s u m (Integer -> Integer)
-> ParsecT s u m (Integer -> Integer)
-> ParsecT s u m (Integer -> Integer)
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> (Integer -> Integer) -> ParsecT s u m (Integer -> Integer)
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return Integer -> Integer
forall a. a -> a
id

    nat :: ParsecT s u m Integer
nat             = ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
zeroNumber ParsecT s u m Integer
-> ParsecT s u m Integer -> ParsecT s u m Integer
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m Integer
forall {u}. ParsecT s u m Integer
decimal

    zeroNumber :: ParsecT s u m Integer
zeroNumber      = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
'0'
                        ; hexadecimal <|> octal <|> decimal <|> return 0
                        }
                      ParsecT s u m Integer -> String -> ParsecT s u m Integer
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
""

    decimal :: ParsecT s u m Integer
decimal         = Integer -> ParsecT s u m Char -> ParsecT s u m Integer
forall {s} {m :: * -> *} {t} {u}.
Stream s m t =>
Integer -> ParsecT s u m Char -> ParsecT s u m Integer
number Integer
10 ParsecT s u m Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit
    hexadecimal :: ParsecT s u m Integer
hexadecimal     = do{ _ <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"xX"; number 16 hexDigit }
    octal :: ParsecT s u m Integer
octal           = do{ _ <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
"oO"; number 8 octDigit  }

    number :: Integer -> ParsecT s u m Char -> ParsecT s u m Integer
number Integer
base ParsecT s u m Char
baseDigit
        = do{ digits <- ParsecT s u m Char -> ParsecT s u m String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m [a]
many1 ParsecT s u m Char
baseDigit
            ; let n = (Integer -> Char -> Integer) -> Integer -> String -> Integer
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl (\Integer
x Char
d -> Integer
baseInteger -> Integer -> Integer
forall a. Num a => a -> a -> a
*Integer
x Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Int -> Integer
forall a. Integral a => a -> Integer
toInteger (Char -> Int
digitToInt Char
d)) Integer
0 String
digits
            ; seq n (return n)
            }

    -----------------------------------------------------------
    -- Operators & reserved ops
    -----------------------------------------------------------
    reservedOp :: String -> ParsecT s u m ()
reservedOp String
name =
        ParsecT s u m () -> ParsecT s u m ()
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$
        do{ _ <- String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
name
          ; notFollowedBy (opLetter languageDef) <?> ("end of " ++ show name)
          }

    operator :: ParsecT s u m String
operator =
        ParsecT s u m String -> ParsecT s u m String
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$
        do{ name <- ParsecT s u m String
oper
          ; if (isReservedOp name)
             then unexpected ("reserved operator " ++ show name)
             else return name
          }

    oper :: ParsecT s u m String
oper =
        do{ c <- (GenLanguageDef s u m -> ParsecT s u m Char
forall s u (m :: * -> *).
GenLanguageDef s u m -> ParsecT s u m Char
opStart GenLanguageDef s u m
languageDef)
          ; cs <- many (opLetter languageDef)
          ; return (c:cs)
          }
        ParsecT s u m String -> String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"operator"

    isReservedOp :: String -> Bool
isReservedOp String
name =
        [String] -> String -> Bool
forall {p}. Ord p => [p] -> p -> Bool
isReserved ([String] -> [String]
forall a. Ord a => [a] -> [a]
sort (GenLanguageDef s u m -> [String]
forall s u (m :: * -> *). GenLanguageDef s u m -> [String]
reservedOpNames GenLanguageDef s u m
languageDef)) String
name


    -----------------------------------------------------------
    -- Identifiers & Reserved words
    -----------------------------------------------------------
    reserved :: String -> ParsecT s u m ()
reserved String
name =
        ParsecT s u m () -> ParsecT s u m ()
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$ ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m () -> ParsecT s u m ())
-> ParsecT s u m () -> ParsecT s u m ()
forall a b. (a -> b) -> a -> b
$
        do{ _ <- String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
caseString String
name
          ; notFollowedBy (identLetter languageDef) <?> ("end of " ++ show name)
          }

    caseString :: String -> ParsecT s u m String
caseString String
name
        | GenLanguageDef s u m -> Bool
forall s u (m :: * -> *). GenLanguageDef s u m -> Bool
caseSensitive GenLanguageDef s u m
languageDef  = String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
name
        | Bool
otherwise               = do{ String -> ParsecT s u m ()
forall {s} {m :: * -> *} {u}.
Stream s m Char =>
String -> ParsecT s u m ()
walk String
name; String -> ParsecT s u m String
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return String
name }
        where
          walk :: String -> ParsecT s u m ()
walk []     = () -> ParsecT s u m ()
forall a. a -> ParsecT s u m a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
          walk (Char
c:String
cs) = do{ _ <- Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
caseChar Char
c ParsecT s u m Char -> String -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
msg; walk cs }

          caseChar :: Char -> ParsecT s u m Char
caseChar Char
c  | Char -> Bool
isAlpha Char
c  = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char (Char -> Char
toLower Char
c) ParsecT s u m Char -> ParsecT s u m Char -> ParsecT s u m Char
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char (Char -> Char
toUpper Char
c)
                      | Bool
otherwise  = Char -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char Char
c

          msg :: String
msg         = String -> String
forall a. Show a => a -> String
show String
name


    identifier :: ParsecT s u m String
identifier =
        ParsecT s u m String -> ParsecT s u m String
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$ ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT s u m String -> ParsecT s u m String)
-> ParsecT s u m String -> ParsecT s u m String
forall a b. (a -> b) -> a -> b
$
        do{ name <- ParsecT s u m String
ident
          ; if (isReservedName name)
             then unexpected ("reserved word " ++ show name)
             else return name
          }


    ident :: ParsecT s u m String
ident
        = do{ c <- GenLanguageDef s u m -> ParsecT s u m Char
forall s u (m :: * -> *).
GenLanguageDef s u m -> ParsecT s u m Char
identStart GenLanguageDef s u m
languageDef
            ; cs <- many (identLetter languageDef)
            ; return (c:cs)
            }
        ParsecT s u m String -> String -> ParsecT s u m String
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"identifier"

    isReservedName :: String -> Bool
isReservedName String
name
        = [String] -> String -> Bool
forall {p}. Ord p => [p] -> p -> Bool
isReserved [String]
theReservedNames String
caseName
        where
          caseName :: String
caseName      | GenLanguageDef s u m -> Bool
forall s u (m :: * -> *). GenLanguageDef s u m -> Bool
caseSensitive GenLanguageDef s u m
languageDef  = String
name
                        | Bool
otherwise               = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
name


    isReserved :: [p] -> p -> Bool
isReserved [p]
names p
name
        = [p] -> Bool
scan [p]
names
        where
          scan :: [p] -> Bool
scan []       = Bool
False
          scan (p
r:[p]
rs)   = case (p -> p -> Ordering
forall a. Ord a => a -> a -> Ordering
compare p
r p
name) of
                            Ordering
LT  -> [p] -> Bool
scan [p]
rs
                            Ordering
EQ  -> Bool
True
                            Ordering
GT  -> Bool
False

    theReservedNames :: [String]
theReservedNames
        | GenLanguageDef s u m -> Bool
forall s u (m :: * -> *). GenLanguageDef s u m -> Bool
caseSensitive GenLanguageDef s u m
languageDef  = [String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String]
reserved
        | Bool
otherwise                  = [String] -> [String]
forall a. Ord a => [a] -> [a]
sort ([String] -> [String])
-> ([String] -> [String]) -> [String] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map ((Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower) ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String]
reserved
        where
          reserved :: [String]
reserved = GenLanguageDef s u m -> [String]
forall s u (m :: * -> *). GenLanguageDef s u m -> [String]
reservedNames GenLanguageDef s u m
languageDef



    -----------------------------------------------------------
    -- White space & symbols
    -----------------------------------------------------------
    symbol :: String -> ParsecT s u m String
symbol String
name
        = ParsecT s u m String -> ParsecT s u m String
forall {u} {b}. ParsecT s u m b -> ParsecT s u m b
lexeme (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string String
name)

    lexeme :: ParsecT s u m b -> ParsecT s u m b
lexeme ParsecT s u m b
p
        = do{ x <- ParsecT s u m b
p; whiteSpace; return x  }


    --whiteSpace
    whiteSpace :: ParsecT s u m ()
whiteSpace
        | Bool
noLine Bool -> Bool -> Bool
&& Bool
noMulti  = ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (ParsecT s u m ()
forall {u}. ParsecT s u m ()
simpleSpace ParsecT s u m () -> String -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"")
        | Bool
noLine             = ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (ParsecT s u m ()
forall {u}. ParsecT s u m ()
simpleSpace ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m ()
forall {u}. ParsecT s u m ()
multiLineComment ParsecT s u m () -> String -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"")
        | Bool
noMulti            = ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (ParsecT s u m ()
forall {u}. ParsecT s u m ()
simpleSpace ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m ()
forall {u}. ParsecT s u m ()
oneLineComment ParsecT s u m () -> String -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"")
        | Bool
otherwise          = ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m ()
skipMany (ParsecT s u m ()
forall {u}. ParsecT s u m ()
simpleSpace ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m ()
forall {u}. ParsecT s u m ()
oneLineComment ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT s u m ()
forall {u}. ParsecT s u m ()
multiLineComment ParsecT s u m () -> String -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"")
        where
          noLine :: Bool
noLine  = String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentLine GenLanguageDef s u m
languageDef)
          noMulti :: Bool
noMulti = String -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentStart GenLanguageDef s u m
languageDef)


    simpleSpace :: ParsecT s u m ()
simpleSpace =
        ParsecT s u m Char -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 ((Char -> Bool) -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
(Char -> Bool) -> ParsecT s u m Char
satisfy Char -> Bool
isSpace)

    oneLineComment :: ParsecT s u m ()
oneLineComment =
        do{ _ <- ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentLine GenLanguageDef s u m
languageDef))
          ; skipMany (satisfy (/= '\n'))
          ; return ()
          }

    multiLineComment :: ParsecT s u m ()
multiLineComment =
        do { _ <- ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentStart GenLanguageDef s u m
languageDef))
           ; inComment
           }

    inComment :: ParsecT s u m ()
inComment
        | GenLanguageDef s u m -> Bool
forall s u (m :: * -> *). GenLanguageDef s u m -> Bool
nestedComments GenLanguageDef s u m
languageDef  = ParsecT s u m ()
inCommentMulti
        | Bool
otherwise                = ParsecT s u m ()
forall {u}. ParsecT s u m ()
inCommentSingle

    inCommentMulti :: ParsecT s u m ()
inCommentMulti
        =   do{ _ <- ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentEnd GenLanguageDef s u m
languageDef)) ; return () }
        ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do{ ParsecT s u m ()
multiLineComment                     ; ParsecT s u m ()
inCommentMulti }
        ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do{ ParsecT s u m Char -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 (String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
startEnd)          ; ParsecT s u m ()
inCommentMulti }
        ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do{ _ <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
startEnd                  ; inCommentMulti }
        ParsecT s u m () -> String -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"end of comment"
        where
          startEnd :: String
startEnd   = String -> String
forall a. Eq a => [a] -> [a]
nub (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentEnd GenLanguageDef s u m
languageDef String -> String -> String
forall a. [a] -> [a] -> [a]
++ GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentStart GenLanguageDef s u m
languageDef)

    inCommentSingle :: ParsecT s u m ()
inCommentSingle
        =   do{ _ <- ParsecT s u m String -> ParsecT s u m String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (String -> ParsecT s u m String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentEnd GenLanguageDef s u m
languageDef)); return () }
        ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do{ ParsecT s u m Char -> ParsecT s u m ()
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m ()
skipMany1 (String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf String
startEnd)         ; ParsecT s u m ()
inCommentSingle }
        ParsecT s u m () -> ParsecT s u m () -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> do{ _ <- String -> ParsecT s u m Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf String
startEnd                 ; inCommentSingle }
        ParsecT s u m () -> String -> ParsecT s u m ()
forall s u (m :: * -> *) a.
ParsecT s u m a -> String -> ParsecT s u m a
<?> String
"end of comment"
        where
          startEnd :: String
startEnd   = String -> String
forall a. Eq a => [a] -> [a]
nub (GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentEnd GenLanguageDef s u m
languageDef String -> String -> String
forall a. [a] -> [a] -> [a]
++ GenLanguageDef s u m -> String
forall s u (m :: * -> *). GenLanguageDef s u m -> String
commentStart GenLanguageDef s u m
languageDef)