    {-# LANGUAGE CPP #-}

    module UU.Scanner.TokenParser where

    import UU.Parsing.Interface(IsParser(..), (<$), (<$>))
    import UU.Parsing.Derived(pListSep, pPacked)
    import UU.Scanner.Position(Pos)
    import UU.Scanner.GenTokenParser(pReserved, pValToken)
    import UU.Scanner.Token(Token,EnumValToken(..))

    -------------------------------------------------------------------------
    -- IsParsers for  Symbols
    -------------------------------------------------------------------------

    pKeyPos           :: IsParser p Token => String -> p Pos
    pKeyPos  keyword  =  pReserved keyword

    pSpecPos          :: IsParser p Token => Char -> p Pos
    pSpecPos s        =  pReserved [s]

    pKey              :: IsParser p Token => String -> p String
    pKey  key         =  key <$ pKeyPos key

    pSpec             :: IsParser p Token => Char -> p String
    pSpec c           =  [c] <$ pSpecPos c

    pStringPos, pCharPos,
      pInteger8Pos, pInteger10Pos, pInteger16Pos, pFractionPos,
      pVaridPos, pConidPos,
      pTextnmPos, pTextlnPos, pIntegerPos, pVarsymPos, pConsymPos  :: IsParser p Token => p (String,Pos)

    pStringPos     =   pValToken TkString    ""
    pCharPos       =   pValToken TkChar      "\NUL"
    pInteger8Pos   =   pValToken TkInteger8  "0"
    pInteger10Pos  =   pValToken TkInteger10 "0"
    pInteger16Pos  =   pValToken TkInteger16 "0"
    pFractionPos   =   pValToken TkFraction  "0.0"
    pVaridPos      =   pValToken TkVarid     "<identifier>"
    pConidPos      =   pValToken TkConid     "<Identifier>"
    pConsymPos     =   pValToken TkConOp     "<conoperator>"
    pVarsymPos     =   pValToken TkOp        "<operator>"
    pTextnmPos     =   pValToken TkTextnm    "<name>"
    pTextlnPos     =   pValToken TkTextln    "<line>"
    pIntegerPos    =   pInteger10Pos

    pString, pChar,
      pInteger8, pInteger10, pInteger16, pFraction,
      pVarid, pConid,
      pTextnm, pTextln, pInteger, pVarsym, pConsym  :: IsParser p Token => p String

    pString        = fst <$> pStringPos
    pChar          = fst <$> pCharPos
    pInteger8      = fst <$> pInteger8Pos
    pInteger10     = fst <$> pInteger10Pos
    pInteger16     = fst <$> pInteger16Pos
    pFraction      = fst <$> pFractionPos
    pVarid         = fst <$> pVaridPos
    pConid         = fst <$> pConidPos
    pVarsym        = fst <$> pVarsymPos
    pConsym        = fst <$> pConsymPos
    pTextnm        = fst <$> pTextnmPos
    pTextln        = fst <$> pTextlnPos
    pInteger       = fst <$> pIntegerPos

    pComma, pSemi, pOParen, pCParen, pOBrack, pCBrack, pOCurly, pCCurly
       :: IsParser p Token => p String

    pComma  = pSpec ','
    pSemi   = pSpec ';'
    pOParen = pSpec '('
    pCParen = pSpec ')'
    pOBrack = pSpec '['
    pCBrack = pSpec ']'
    pOCurly = pSpec '{'
    pCCurly = pSpec '}'

    pCommaPos, pSemiPos, pOParenPos, pCParenPos, pOBrackPos, pCBrackPos, pOCurlyPos, pCCurlyPos
       :: IsParser p Token => p Pos

    pCommaPos  = pSpecPos ','
    pSemiPos   = pSpecPos ';'
    pOParenPos = pSpecPos '('
    pCParenPos = pSpecPos ')'
    pOBrackPos = pSpecPos '['
    pCBrackPos = pSpecPos ']'
    pOCurlyPos = pSpecPos '{'
    pCCurlyPos = pSpecPos '}'

    pCommas ::  IsParser p Token => p a -> p [a]
    pSemics ::  IsParser p Token => p a -> p [a]
    pParens ::  IsParser p Token => p a -> p a
    pBracks ::  IsParser p Token => p a -> p a
    pCurly  ::  IsParser p Token => p a -> p a

    pCommas  = pListSep pComma
    pSemics  = pListSep pSemi
    pParens  = pPacked pOParen pCParen
    pBracks  = pPacked pOBrack pCBrack
    pCurly   = pPacked pOCurly pCCurly

    pParens_pCommas :: IsParser p Token => p a -> p [a]
    pBracks_pCommas :: IsParser p Token => p a -> p [a]
    pCurly_pSemics  :: IsParser p Token => p a -> p [a]

    pParens_pCommas = pParens.pCommas
    pBracks_pCommas = pBracks.pCommas
    pCurly_pSemics  = pCurly .pSemics