|
Packit |
2cbdf3 |
-- -----------------------------------------------------------------------------
|
|
Packit |
2cbdf3 |
-- ALEX TEMPLATE
|
|
Packit |
2cbdf3 |
--
|
|
Packit |
2cbdf3 |
-- This code is in the PUBLIC DOMAIN; you may copy it freely and use
|
|
Packit |
2cbdf3 |
-- it for any purpose whatsoever.
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
-- -----------------------------------------------------------------------------
|
|
Packit |
2cbdf3 |
-- INTERNALS and main scanner engine
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
#ifdef ALEX_GHC
|
|
Packit |
2cbdf3 |
#undef __GLASGOW_HASKELL__
|
|
Packit |
2cbdf3 |
#define ALEX_IF_GHC_GT_500 #if __GLASGOW_HASKELL__ > 500
|
|
Packit |
2cbdf3 |
#define ALEX_IF_GHC_LT_503 #if __GLASGOW_HASKELL__ < 503
|
|
Packit |
2cbdf3 |
#define ALEX_IF_GHC_GT_706 #if __GLASGOW_HASKELL__ > 706
|
|
Packit |
2cbdf3 |
#define ALEX_ELIF_GHC_500 #elif __GLASGOW_HASKELL__ == 500
|
|
Packit |
2cbdf3 |
#define ALEX_IF_BIGENDIAN #ifdef WORDS_BIGENDIAN
|
|
Packit |
2cbdf3 |
#define ALEX_ELSE #else
|
|
Packit |
2cbdf3 |
#define ALEX_ENDIF #endif
|
|
Packit |
2cbdf3 |
#define ALEX_DEFINE #define
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
#ifdef ALEX_GHC
|
|
Packit |
2cbdf3 |
#define ILIT(n) n#
|
|
Packit |
2cbdf3 |
#define IBOX(n) (I# (n))
|
|
Packit |
2cbdf3 |
#define FAST_INT Int#
|
|
Packit |
2cbdf3 |
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
|
|
Packit |
2cbdf3 |
ALEX_IF_GHC_GT_706
|
|
Packit |
2cbdf3 |
ALEX_DEFINE GTE(n,m) (tagToEnum# (n >=# m))
|
|
Packit |
2cbdf3 |
ALEX_DEFINE EQ(n,m) (tagToEnum# (n ==# m))
|
|
Packit |
2cbdf3 |
ALEX_ELSE
|
|
Packit |
2cbdf3 |
ALEX_DEFINE GTE(n,m) (n >=# m)
|
|
Packit |
2cbdf3 |
ALEX_DEFINE EQ(n,m) (n ==# m)
|
|
Packit |
2cbdf3 |
ALEX_ENDIF
|
|
Packit |
2cbdf3 |
#define PLUS(n,m) (n +# m)
|
|
Packit |
2cbdf3 |
#define MINUS(n,m) (n -# m)
|
|
Packit |
2cbdf3 |
#define TIMES(n,m) (n *# m)
|
|
Packit |
2cbdf3 |
#define NEGATE(n) (negateInt# (n))
|
|
Packit |
2cbdf3 |
#define IF_GHC(x) (x)
|
|
Packit |
2cbdf3 |
#else
|
|
Packit |
2cbdf3 |
#define ILIT(n) (n)
|
|
Packit |
2cbdf3 |
#define IBOX(n) (n)
|
|
Packit |
2cbdf3 |
#define FAST_INT Int
|
|
Packit |
2cbdf3 |
#define GTE(n,m) (n >= m)
|
|
Packit |
2cbdf3 |
#define EQ(n,m) (n == m)
|
|
Packit |
2cbdf3 |
#define PLUS(n,m) (n + m)
|
|
Packit |
2cbdf3 |
#define MINUS(n,m) (n - m)
|
|
Packit |
2cbdf3 |
#define TIMES(n,m) (n * m)
|
|
Packit |
2cbdf3 |
#define NEGATE(n) (negate (n))
|
|
Packit |
2cbdf3 |
#define IF_GHC(x)
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
#ifdef ALEX_GHC
|
|
Packit |
2cbdf3 |
data AlexAddr = AlexA# Addr#
|
|
Packit |
2cbdf3 |
-- Do not remove this comment. Required to fix CPP parsing when using GCC and a clang-compiled alex.
|
|
Packit |
2cbdf3 |
ALEX_IF_GHC_LT_503
|
|
Packit |
2cbdf3 |
uncheckedShiftL# = shiftL#
|
|
Packit |
2cbdf3 |
ALEX_ENDIF
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
{-# INLINE alexIndexInt16OffAddr #-}
|
|
Packit |
2cbdf3 |
alexIndexInt16OffAddr (AlexA# arr) off =
|
|
Packit |
2cbdf3 |
ALEX_IF_BIGENDIAN
|
|
Packit |
2cbdf3 |
narrow16Int# i
|
|
Packit |
2cbdf3 |
where
|
|
Packit |
2cbdf3 |
i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)
|
|
Packit |
2cbdf3 |
high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
|
|
Packit |
2cbdf3 |
low = int2Word# (ord# (indexCharOffAddr# arr off'))
|
|
Packit |
2cbdf3 |
off' = off *# 2#
|
|
Packit |
2cbdf3 |
ALEX_ELSE
|
|
Packit |
2cbdf3 |
indexInt16OffAddr# arr off
|
|
Packit |
2cbdf3 |
ALEX_ENDIF
|
|
Packit |
2cbdf3 |
#else
|
|
Packit |
2cbdf3 |
alexIndexInt16OffAddr arr off = arr ! off
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
#ifdef ALEX_GHC
|
|
Packit |
2cbdf3 |
{-# INLINE alexIndexInt32OffAddr #-}
|
|
Packit |
2cbdf3 |
alexIndexInt32OffAddr (AlexA# arr) off =
|
|
Packit |
2cbdf3 |
ALEX_IF_BIGENDIAN
|
|
Packit |
2cbdf3 |
narrow32Int# i
|
|
Packit |
2cbdf3 |
where
|
|
Packit |
2cbdf3 |
i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`
|
|
Packit |
2cbdf3 |
(b2 `uncheckedShiftL#` 16#) `or#`
|
|
Packit |
2cbdf3 |
(b1 `uncheckedShiftL#` 8#) `or#` b0)
|
|
Packit |
2cbdf3 |
b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))
|
|
Packit |
2cbdf3 |
b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))
|
|
Packit |
2cbdf3 |
b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))
|
|
Packit |
2cbdf3 |
b0 = int2Word# (ord# (indexCharOffAddr# arr off'))
|
|
Packit |
2cbdf3 |
off' = off *# 4#
|
|
Packit |
2cbdf3 |
ALEX_ELSE
|
|
Packit |
2cbdf3 |
indexInt32OffAddr# arr off
|
|
Packit |
2cbdf3 |
ALEX_ENDIF
|
|
Packit |
2cbdf3 |
#else
|
|
Packit |
2cbdf3 |
alexIndexInt32OffAddr arr off = arr ! off
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
#ifdef ALEX_GHC
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
ALEX_IF_GHC_LT_503
|
|
Packit |
2cbdf3 |
quickIndex arr i = arr ! i
|
|
Packit |
2cbdf3 |
ALEX_ELSE
|
|
Packit |
2cbdf3 |
-- GHC >= 503, unsafeAt is available from Data.Array.Base.
|
|
Packit |
2cbdf3 |
quickIndex = unsafeAt
|
|
Packit |
2cbdf3 |
ALEX_ENDIF
|
|
Packit |
2cbdf3 |
#else
|
|
Packit |
2cbdf3 |
quickIndex arr i = arr ! i
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
-- -----------------------------------------------------------------------------
|
|
Packit |
2cbdf3 |
-- Main lexing routines
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
data AlexReturn a
|
|
Packit |
2cbdf3 |
= AlexEOF
|
|
Packit |
2cbdf3 |
| AlexError !AlexInput
|
|
Packit |
2cbdf3 |
| AlexSkip !AlexInput !Int
|
|
Packit |
2cbdf3 |
| AlexToken !AlexInput !Int a
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
-- alexScan :: AlexInput -> StartCode -> AlexReturn a
|
|
Packit |
2cbdf3 |
alexScan input__ IBOX(sc)
|
|
Packit |
2cbdf3 |
= alexScanUser undefined input__ IBOX(sc)
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
alexScanUser user__ input__ IBOX(sc)
|
|
Packit |
2cbdf3 |
= case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
|
|
Packit |
2cbdf3 |
(AlexNone, input__') ->
|
|
Packit |
2cbdf3 |
case alexGetByte input__ of
|
|
Packit |
2cbdf3 |
Nothing ->
|
|
Packit |
2cbdf3 |
#ifdef ALEX_DEBUG
|
|
Packit |
2cbdf3 |
trace ("End of input.") $
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
AlexEOF
|
|
Packit |
2cbdf3 |
Just _ ->
|
|
Packit |
2cbdf3 |
#ifdef ALEX_DEBUG
|
|
Packit |
2cbdf3 |
trace ("Error.") $
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
AlexError input__'
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
(AlexLastSkip input__'' len, _) ->
|
|
Packit |
2cbdf3 |
#ifdef ALEX_DEBUG
|
|
Packit |
2cbdf3 |
trace ("Skipping.") $
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
AlexSkip input__'' len
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
(AlexLastAcc k input__''' len, _) ->
|
|
Packit |
2cbdf3 |
#ifdef ALEX_DEBUG
|
|
Packit |
2cbdf3 |
trace ("Accept.") $
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
AlexToken input__''' len (alex_actions ! k)
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
-- Push the input through the DFA, remembering the most recent accepting
|
|
Packit |
2cbdf3 |
-- state it encountered.
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
alex_scan_tkn user__ orig_input len input__ s last_acc =
|
|
Packit |
2cbdf3 |
input__ `seq` -- strict in the input
|
|
Packit |
2cbdf3 |
let
|
|
Packit |
2cbdf3 |
new_acc = (check_accs (alex_accept `quickIndex` IBOX(s)))
|
|
Packit |
2cbdf3 |
in
|
|
Packit |
2cbdf3 |
new_acc `seq`
|
|
Packit |
2cbdf3 |
case alexGetByte input__ of
|
|
Packit |
2cbdf3 |
Nothing -> (new_acc, input__)
|
|
Packit |
2cbdf3 |
Just (c, new_input) ->
|
|
Packit |
2cbdf3 |
#ifdef ALEX_DEBUG
|
|
Packit |
2cbdf3 |
trace ("State: " ++ show IBOX(s) ++ ", char: " ++ show c) $
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
case fromIntegral c of { IBOX(ord_c) ->
|
|
Packit |
2cbdf3 |
let
|
|
Packit |
2cbdf3 |
base = alexIndexInt32OffAddr alex_base s
|
|
Packit |
2cbdf3 |
offset = PLUS(base,ord_c)
|
|
Packit |
2cbdf3 |
check = alexIndexInt16OffAddr alex_check offset
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
new_s = if GTE(offset,ILIT(0)) && EQ(check,ord_c)
|
|
Packit |
2cbdf3 |
then alexIndexInt16OffAddr alex_table offset
|
|
Packit |
2cbdf3 |
else alexIndexInt16OffAddr alex_deflt s
|
|
Packit |
2cbdf3 |
in
|
|
Packit |
2cbdf3 |
case new_s of
|
|
Packit |
2cbdf3 |
ILIT(-1) -> (new_acc, input__)
|
|
Packit |
2cbdf3 |
-- on an error, we want to keep the input *before* the
|
|
Packit |
2cbdf3 |
-- character that failed, not after.
|
|
Packit |
2cbdf3 |
_ -> alex_scan_tkn user__ orig_input (if c < 0x80 || c >= 0xC0 then PLUS(len,ILIT(1)) else len)
|
|
Packit |
2cbdf3 |
-- note that the length is increased ONLY if this is the 1st byte in a char encoding)
|
|
Packit |
2cbdf3 |
new_input new_s new_acc
|
|
Packit |
2cbdf3 |
}
|
|
Packit |
2cbdf3 |
where
|
|
Packit |
2cbdf3 |
check_accs (AlexAccNone) = last_acc
|
|
Packit |
2cbdf3 |
check_accs (AlexAcc a ) = AlexLastAcc a input__ IBOX(len)
|
|
Packit |
2cbdf3 |
check_accs (AlexAccSkip) = AlexLastSkip input__ IBOX(len)
|
|
Packit |
2cbdf3 |
#ifndef ALEX_NOPRED
|
|
Packit |
2cbdf3 |
check_accs (AlexAccPred a predx rest)
|
|
Packit |
2cbdf3 |
| predx user__ orig_input IBOX(len) input__
|
|
Packit |
2cbdf3 |
= AlexLastAcc a input__ IBOX(len)
|
|
Packit |
2cbdf3 |
| otherwise
|
|
Packit |
2cbdf3 |
= check_accs rest
|
|
Packit |
2cbdf3 |
check_accs (AlexAccSkipPred predx rest)
|
|
Packit |
2cbdf3 |
| predx user__ orig_input IBOX(len) input__
|
|
Packit |
2cbdf3 |
= AlexLastSkip input__ IBOX(len)
|
|
Packit |
2cbdf3 |
| otherwise
|
|
Packit |
2cbdf3 |
= check_accs rest
|
|
Packit |
2cbdf3 |
#endif
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
data AlexLastAcc
|
|
Packit |
2cbdf3 |
= AlexNone
|
|
Packit |
2cbdf3 |
| AlexLastAcc !Int !AlexInput !Int
|
|
Packit |
2cbdf3 |
| AlexLastSkip !AlexInput !Int
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
data AlexAcc user
|
|
Packit |
2cbdf3 |
= AlexAccNone
|
|
Packit |
2cbdf3 |
| AlexAcc Int
|
|
Packit |
2cbdf3 |
| AlexAccSkip
|
|
Packit |
2cbdf3 |
#ifndef ALEX_NOPRED
|
|
Packit |
2cbdf3 |
| AlexAccPred Int (AlexAccPred user) (AlexAcc user)
|
|
Packit |
2cbdf3 |
| AlexAccSkipPred (AlexAccPred user) (AlexAcc user)
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
-- -----------------------------------------------------------------------------
|
|
Packit |
2cbdf3 |
-- Predicates on a rule
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
alexAndPred p1 p2 user__ in1 len in2
|
|
Packit |
2cbdf3 |
= p1 user__ in1 len in2 && p2 user__ in1 len in2
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
--alexPrevCharIsPred :: Char -> AlexAccPred _
|
|
Packit |
2cbdf3 |
alexPrevCharIs c _ input__ _ _ = c == alexInputPrevChar input__
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
alexPrevCharMatches f _ input__ _ _ = f (alexInputPrevChar input__)
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _
|
|
Packit |
2cbdf3 |
alexPrevCharIsOneOf arr _ input__ _ _ = arr ! alexInputPrevChar input__
|
|
Packit |
2cbdf3 |
|
|
Packit |
2cbdf3 |
--alexRightContext :: Int -> AlexAccPred _
|
|
Packit |
2cbdf3 |
alexRightContext IBOX(sc) user__ _ _ input__ =
|
|
Packit |
2cbdf3 |
case alex_scan_tkn user__ input__ ILIT(0) input__ sc AlexNone of
|
|
Packit |
2cbdf3 |
(AlexNone, _) -> False
|
|
Packit |
2cbdf3 |
_ -> True
|
|
Packit |
2cbdf3 |
-- TODO: there's no need to find the longest
|
|
Packit |
2cbdf3 |
-- match when checking the right context, just
|
|
Packit |
2cbdf3 |
-- the first match will do.
|
|
Packit |
2cbdf3 |
#endif
|