simple-arithmetic-compiler/app/Lexer.hs

36 lines
1.2 KiB
Haskell

module Lexer where
data Token = Plus
| Hyphen
| Asterisk
| ForwardSlash
| Integer Int
| LBrace
| RBrace
deriving Show
lex :: String -> [Token]
lex source = reverse (lex' source [] (length source))
lex' :: String -> [Token] -> Int -> [Token]
lex' "" tokens _ = tokens
lex' (' ':xs) tokens orgLength = lex' xs tokens orgLength
lex' (x:xs) tokens orgLength = case x of
'+' -> lex' xs (Plus:tokens) orgLength
'-' -> lex' xs (Hyphen:tokens) orgLength
'*' -> lex' xs (Asterisk:tokens) orgLength
'/' -> lex' xs (ForwardSlash:tokens) orgLength
'(' -> lex' xs (LBrace:tokens) orgLength
')' -> lex' xs (RBrace:tokens) orgLength
_ -> lexNumbers (x:xs) tokens orgLength
lexNumbers :: String -> [Token] -> Int -> [Token]
lexNumbers (x:xs) tokens orgLength
| isDigit x = lex' rest ((Integer(read digits::Int)):tokens) orgLength
| otherwise = syntaxError x (orgLength - (length (x:xs)) + 1)
where
digits = takeWhile isDigit (x:xs)
rest = dropWhile isDigit (x:xs)
isDigit c = c `elem` "0123456789"
syntaxError char pos = error $ "Syntax error: " ++ [char] ++ " (" ++ show pos ++ ")"