{-
Author: Wishnu Prasetya
Copyright 2011 Utrecht University
The use of this sofware is free under the Modified BSD License.
-}
{- |
This module provides a parser for FITTEST raw-log files. It also
defines a data type that abstractly represents such a file.
-}
module Eu.Fittest.Logging.Compression.RawlogParser(
RawLogEntry(..),
isParagraph,
isSection,
strParseRawLog,
UTCTimeStamp1970(..)
)
where
import Text.ParserCombinators.ReadP
import Data.Char
import Data.Time
import System.IO
-- | A representation of entries in a raw-log file. We will make it more
-- generic than needed so that we can reuse it later.
data RawLogEntry timestamp attrib paragraph
-- | Section
= Section (Maybe timestamp) attrib [RawLogEntry timestamp attrib paragraph]
-- | Paragraph
| Par paragraph
deriving (Eq,Show)
isParagraph (Par p) = True
isParagraph _ = False
isSection s = not (isParagraph s)
-- Hashlog literals
--
dquote = '\"'
sectionStart = "% [RawLogEntry UTCTimeStamp1970 String [String]]
strParseRawLog input = runParser parseLog input
runParser p s = fst . last $ (readP_to_S p s)
parseLog :: ReadP [RawLogEntry UTCTimeStamp1970 String [String]]
parseLog = do {
skipSpaces ;
sections <- endBy (parseSection <++ parseParagraph) skipSpaces ;
return sections
}
parseSection :: ReadP (RawLogEntry (Int,Integer) String [String])
parseSection = do {
string sectionStart ;
skipSpaces ;
time <- option Nothing (do { t <- parseTimeStamp; return (Just t) }) ;
skipSpaces ;
tag <- parseSectionTag ;
skipSpaces ;
content <- pSectionPart `manyTill` (string endTok) ;
return (Section time tag content) ;
}
pSectionPart = do {
part <- (parseParagraph <++ parseSection) ;
skipSpaces ;
return part ;
}
parseSectionTag = do {
char dquote ;
tag <- pAny `manyTill` char dquote ;
return tag ;
}
parseTimeStamp :: ReadP UTCTimeStamp1970
parseTimeStamp = do {
offset <- pInteger ;
char ':';
time <- pInteger ;
return (fromInteger offset,time) ;
}
pInteger :: ReadP Integer
pInteger = do {
sign <- option 1 ((do { char '-' ; return (-1) })
<++
(do { char '+' ; return 1 })) ;
s <- munch1 isDigit ;
if (sign < 0) then return (- (read s))
else return (read s)
}
parseParagraph = do {
string parStart ;
skipSpaces ;
sentences <- parseSentence `manyTill` (string endTok) ;
return (Par sentences) ;
}
parseSentence = do {
string sentStart ;
skipSpaces ;
s <- pAny `manyTill` (string sentEnd) ;
skipSpaces ;
return (dropTrailingSpace s) ;
}
pAny = satisfy (\_-> True)
dropTrailingSpace = reverse . dropWhile isSpace . reverse
exPar1 = "%
" exPar2 = "%
%>" exPar3 = "%
%<{ undefined:void }%>%> \n %>"
exSec1 = "%"
exSec2 = "%"
exSec3 = "%"
exSec4 = "%"
exSec5 = "%"
exSec6 = "% %>\n"
++ "% %>\n"
++ "%
%>\n" ++ "%>\n" ++ "%>\n" exLog1 = do { log <- readFile "./Eu/Fittest/Logging/Compression/SampleRawLog1.log" ; return (strParseRawLog log) }