module Language.JavaScript.Parser.LexerUtils (
StartCode
, Action
, symbolToken
, mkString
, regExToken
, decimalToken
, endOfFileToken
, assignToken
, hexIntegerToken
, stringToken
, lexicalError
) where
import Control.Monad (liftM)
import Control.Monad.Error.Class (throwError)
import Language.JavaScript.Parser.Token as Token
import Language.JavaScript.Parser.ParserMonad
import Language.JavaScript.Parser.SrcLocation
import Prelude hiding (span)
type StartCode = Int
type Action result = AlexInput -> Int -> result
symbolToken :: (Monad m) => (t -> a) -> t -> t1 -> t2 -> m a
symbolToken mkToken location _ _ = return (mkToken location)
endOfFileToken :: Token
endOfFileToken = EOFToken alexSpanEmpty
mkString
:: (Monad m) => (t -> [a1] -> a) -> t -> Int -> [a1] -> m a
mkString toToken loc len str = do
return $ toToken loc (take len str)
mkStringRemoveContinuation
:: (Monad m) => (t -> [a1] -> a) -> t -> Int -> [a1] -> m a
mkStringRemoveContinuation toToken loc len str = do
return $ toToken loc (take len str)
decimalToken :: AlexSpan -> String -> Token
decimalToken loc str = DecimalToken loc str
hexIntegerToken :: AlexSpan -> String -> Token
hexIntegerToken loc str = HexIntegerToken loc str
assignToken :: AlexSpan -> String -> Token
assignToken loc str = AssignToken loc str
regExToken :: AlexSpan -> String -> Token
regExToken loc str = RegExToken loc str
stringToken :: AlexSpan -> String -> Token
stringToken loc str = StringToken loc str1 delimiter
where
str1 = stripLineContinuations $ init $ tail str
delimiter = head str
stripLineContinuations xs = doStripLineContinuations [] [] xs
doStripLineContinuations acc matched xs
| xs == [] = acc
| matched == [] = if (head xs == '\\')
then doStripLineContinuations acc ['\\'] (tail xs)
else doStripLineContinuations (acc ++ [head xs]) [] (tail xs)
| otherwise = if ((head xs == '\n') || (head xs == '\r') || (head xs == '\x2028') || (head xs == '\x2029'))
then doStripLineContinuations acc (matched++[head xs]) (tail xs)
else (if (matched == ['\\'])
then doStripLineContinuations (acc++matched ++ [head xs]) [] (tail xs)
else doStripLineContinuations (acc++[head xs]) [] (tail xs))
lexicalError :: P a
lexicalError = do
location <- getLocation
c <- liftM head getInput
throwError $ UnexpectedChar c location