module Utils where import "IO" -- Utilities for the N3 parser -- delimiter string delimNode = [' ','.',';', ']', '=','\n', '\r',',','}' ] -- -- see if a character is present in a string checkCharacter :: Char -> String -> Bool checkCharacter c "" = False checkCharacter c (x:xs) | x == c = True | otherwise = checkCharacter c xs -- takec a b will parse character a from string b -- and returns (True, b-a) or (False, b) takec :: Char -> String -> (Bool, String) takec a "" = (False, "") takec a (x:xs) | x == a = (True, xs) | otherwise = (False, x:xs) -- parseUntil a b will take from string b until char a is met -- and returns (True c b-c) where c is the part of b before a with -- a not included or it returns (False "" b) parseUntil :: Char -> String -> (Bool, String, String) parseUntil c "" = (False, "", "") parseUntil c s | bool == False = (False, "", s) | otherwise = (True, s1, s2) where (bool, c1, s1, s2) = parseUntilHelp (False, c, "", s) -- help function for parseUntil parseUntilHelp :: (Bool, Char, String, String) -> (Bool, Char, String, String) parseUntilHelp (bool, c, s1, "") = (bool, c, s1, "") parseUntilHelp (bool, c, s1, (x:xs)) | x /= c = parseUntilHelp (False, c, s1 ++ [x], xs) | otherwise = (True, c, s1, xs) -- parseUntilDelim delim input will take a list with delimiters and parse the -- input string till one of the delimiters is found . -- It returns (True c input-c) where c is the parsed string without the -- delimiter or it -- returns (False "" input) if no result parseUntilDelim :: String -> String -> (Bool, String, String) parseUntilDelim delim "" = (False, "", "") parseUntilDelim delim s = parseUntilDelimHelp delim "" s -- This is a help function -- must be called with s = "" parseUntilDelimHelp :: String -> String -> String -> (Bool, String, String) parseUntilDelimHelp delim s "" = (False, s, "") parseUntilDelimHelp delim s (x:xs) |elem x delim = (True, s, (x:xs)) |otherwise = parseUntilDelimHelp delim (s ++ [x]) xs -- skipTillCharacter skip the input string till the character is met . -- The rest of the string is returned without the character skipTillCharacter :: Char -> String -> String skipTillCharacter _ "" = "" skipTillCharacter c (x:xs) | x == c = xs | otherwise = skipTillCharacter c xs -- test if the following character is a blanc testBlancs :: Char -> Bool testBlancs x | x == ' ' || x == '\n' || x == '\r' || x == '\t'= True |otherwise = False -- skips the blancs in a string and returns the stripped string skipBlancs :: String -> String skipBlancs "" = "" skipBlancs s@(x:xs) -- comment | x == '#' = parseComment s | x == ' ' || x == '\n' || x == '\r' || x == '\t' = skipBlancs xs |otherwise = s -- skips the blancs but no comment in a string and returns --the stripped string skipBlancs1 :: String -> String skipBlancs1 "" = "" skipBlancs1 s@(x:xs) | x == ' ' || x == '\n' || x == '\r' = skipBlancs1 xs |otherwise = s -- function for parsing comment -- input is string to be parsed -- the comment goes till "\r\n" is encountered -- returns a string with the comment striped off parseComment :: String -> String parseComment "" = "" parseComment s | bv1 && bv2 = skipBlancs post2 | otherwise = "Error parsing comment" ++ s where (bv1, post1) = takec '#' s (bv2, comment, post2) = parseUntil '\n' post1 -- (bv3, post3) = takec '\n' post2 -- global data -- The global data are a list of tuples (Id, Value) -- Those values are extracted by means of the id and two functions : -- getIntParam and getStringParam -- The values are changed by two functions : -- setIntParam and setStringParam type Globals = [(String,String)] -- Parser data . This is a triple that contains: -- * the global data -- * the accumulated parse results in string form -- * the rest string type ParserData = (Globals, String, String, Int) -- get an integer parameter from a global list getIntParam :: Globals -> String -> Int getIntParam g "" = -30000 getIntParam [] _ = -30000 getIntParam (x:xs) s |fst x == s = stringToInt (snd x) |otherwise = getIntParam xs s -- set an integer parameter in a global list setIntParam :: Globals -> String -> Int -> Globals setIntParam [] _ _ = [] setIntParam g "" _ = g setIntParam g s i = (takeWhile p g) ++ [(s, intToString i)] ++ ys where p = (\(ind, v) -> not (ind == s)) (y:ys) = dropWhile p g -- get an string parameter from a global list getStringParam :: Globals -> String -> String getStringParam g "" = "" getStringParam [] _ = "Error get parameter " getStringParam (x:xs) s |fst x == s = snd x |otherwise = getStringParam xs s -- set an string parameter in a global list setStringParam :: Globals -> String -> String -> Globals setStringParam [] s s' = [(s, s')] setStringParam g "" _ = g setStringParam (x:xs) s s' | fst x == s = [(s, s')] ++ xs | otherwise = x:setStringParam xs s s' -- transform a string to an int stringToInt = mult .reverse .toIntM where mult [] = 0 mult (x:xs) = x + 10*(mult xs) -- transform a string to ciphers in reverse sequence toIntM [] = [] toIntM (x:xs) = [ord(x)-ord('0')] ++ toIntM xs -- transform an int to a string intToString :: Int -> String intToString i | i < 10 = [chr (ord '0' + i)] |otherwise = intToString (i `div` 10) ++ [chr(ord '0' + i`mod`10)] -- startsWith looks if a string starts with a certain chain -- the second parameter is the starting string startsWith :: String -> String -> Bool startsWith "" "" = True startsWith "" s = False startsWith s "" = True startsWith (x:xs) (y:ys) | x == y = startsWith xs ys | otherwise = False -- containsString test whether the first string is contained in the -- second string. containsString :: String -> String -> Bool containsString [] s = True containsString s [] = False containsString (x:xs) (y:ys) | x == y = containsString xs ys | otherwise = containsString (x:xs) ys testContainsString = containsString us2 us1 -- parseString a b will parse string a from string b -- and returns (True, b-a) or (False,b) parseString :: String -> String -> (Bool, String) parseString a b | s == a = (True, c) | otherwise = (False, b) where s = take (length a) b c = drop (length a) b -- save a string to a file of which the name is indicated -- by the second string -- stringToFile :: (String, String) -> IO stringToFile s fileName = do toHandle <- openFile fileName WriteMode hPutStr toHandle s hClose toHandle putStr "Done." -- open a file for reading openRead fileName = openFile fileName ReadMode -- close a file closeFile fileHandle = hClose fileHandle -- read a complete file readFileContents fromHandle = hGetContents fromHandle -- eliminates doubles in a list eliminateDoubles :: Eq a => [a] -> [a] eliminateDoubles [] = [] eliminateDoubles (x:xs) | isIn xs x = eliminateDoubles xs | otherwise = x:eliminateDoubles xs testEliminateDoubles = eliminateDoubles list -- check whether an element is in a list isIn :: Eq a => [a] -> a -> Bool isIn [] y = False isIn (x:xs) y | x == y = True | otherwise = isIn xs y -- get elements of a triple fstTriple (a, b, c) = a sndTriple (a, b, c) = b thdTriple (a, b, c) = c -- test data us1 = "this is a test" us2 = "is" list = ['a', 'b', 'c', 'a', 'd', 'c', 'a', 'f', 'b']