Ebnf2ps-1.0.8: src/Lexer.hs
module Lexer where
-- Copyright 1994 by Peter Thiemann
-- Last Modified By: M. Walter
--
import Data.Char
------------------------------------------------------------------------------
--NOW the lexer
------------------------------------------------------------------------------
data Token
= Ident String | Symbol String | String String | Number String
instance Show Token where
showsPrec n (Ident s) = showChar '[' . showString s . showString "] "
showsPrec n (Symbol "\n") = showString "\n"
showsPrec n (Symbol s) = showChar '<' . showString s . showString "> "
showsPrec n (String s) = showChar '"' . showString s . showString "\" "
showsPrec n (Number s) = showChar ' ' . showString s . showChar ' '
showList [] = id
showList (x:xs) = shows x . showList xs
isIdChar c = isAlpha c || isDigit c || c == '_' || c == '.' -- 1.01
theSymbols = "!@#$%^&*+./<=>?\\|:"
isSymbolChar c = c `elem` theSymbols
lexer :: String -> [Token]
lexer "" = []
lexer ('"':cs) = String (stchars): lexer srest
where (stchars, srest) = lexString cs
lexer ('\'':cs) = String (oneChar): lexer srest
where (oneChar, srest) = lexChar cs
lexer ((c@'\n'):cs) = Symbol [c]: lexer cs
lexer (c:cs)
| isNewline c = Symbol [c]: lexer cs
| isSpace c = lexer cs
| isDot c = Ident (c:idchars): lexer irest -- 1.01
| isAlpha c = Ident (c:idchars): lexer irest
| isSymbolChar c = Symbol(c:sychars): lexer srest
| isDigit c = Number (c:digits): lexer nrest
| otherwise = Symbol([c]): lexer cs
where (idchars, irest) = span isIdChar cs
(sychars, srest) = span isSymbolChar cs
(digits, nrest) = span isDigit cs
isNewline c = c == '\n'
isDot c = c == '.' -- 1.01
-- preprocessor for EBNF style comments
uncomment :: String -> String
uncomment "" = ""
uncomment ('#':cs) = uncomment (dropWhile (/= '\n') cs)
uncomment ('"':cs) = '"':uncommentString cs
uncomment ('\'':cs) = '\'':uncommentChar cs
uncomment (c:cs) = c:uncomment cs
uncommentString "" = ""
uncommentString ('\\':c:cs) = '\\':c:uncommentString cs
uncommentString ('"':cs) = '"':uncomment cs
uncommentString (c:cs) = c:uncommentString cs
uncommentChar "" = ""
uncommentChar ('\\':c:cs) = '\\':c:uncommentChar cs
uncommentChar ('\'':cs) = '"':uncomment cs
uncommentChar (c:cs) = c:uncommentChar cs
-- generic lexers
lexChar ('\\':c:'\'':cs) = ([c], cs)
lexChar (c:'\'':cs) = ([c], cs)
lexChar cs = ([], cs)
lexString ('\\':c:cs) = (c:stchars, srest) where (stchars, srest) = lexString cs
lexString ('"':cs) = ("", cs)
lexString ("") = ("","")
lexString (c:cs) = (c:stchars, srest) where (stchars, srest) = lexString cs
isIdent (Ident _ ) = True
isIdent _ = False
getIdent (Ident s) = s
isString (String _) = True
isString _ = False
getString (String s) = s