Created
August 23, 2022 15:06
-
-
Save apraga/f57e483e83a131022d895d52b8308fee to your computer and use it in GitHub Desktop.
Parsec example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import qualified Data.Text.IO as TIO | |
import Data.Maybe | |
import Data.Time | |
import Data.Time (defaultTimeLocale) | |
import Control.Monad | |
-- show | |
import Text.Parsec | |
import Control.Applicative | |
data Info = Info { | |
hygrometry :: Float, | |
temperature :: Float, | |
pression :: Float, | |
date :: LocalTime | |
} deriving (Show) | |
-- A positive float with a comma instead of a dot | |
-- Assume there are always decimal ! | |
posFloatC = rd <$> str | |
where | |
rd = read :: String -> Float | |
str = do | |
d1 <- number | |
comma <- char ',' | |
d2 <- number | |
return $ d1 ++ "." ++ d2 | |
number = many1 digit | |
(<:>) a b = (:) <$> a <*> b | |
(<++>) a b = (++) <$> a <*> b | |
-- A positive float with a dot | |
-- Assume there are always decimal ! | |
posFloat = rd <$> str | |
where | |
str = number <++> (char '.' <:> number) | |
rd = read :: String -> Float | |
hygrometrieP = do | |
string "Hygrométrie " *> spaces | |
f <- posFloatC <* spaces | |
char '%' | |
return f | |
readHygrometry t = do | |
let s = T.strip . head . filter (T.isInfixOf "Hygrométrie") . T.lines $ t | |
parse hygrometrieP "readHygrometry" (T.unpack s) | |
temperatureP = do | |
string "Température" *> spaces | |
char ':' *> spaces | |
f <- posFloatC | |
spaces *> string "°C" | |
return f | |
-- Température : 21,0 °C Pression atm. : 1.013 hPa Eau Ultrapure | |
readTemperature t = do | |
let s = head . filter (T.isPrefixOf "Température") . T.lines $ t | |
parse temperatureP "readTemperature" (T.unpack s) | |
pressionP = do | |
string "Pression atm." *> spaces | |
char ':' *> spaces | |
f <- posFloat | |
spaces *> string "hPa" | |
return f | |
-- Température : 21,0 °C Pression atm. : 1.013 hPa Eau Ultrapure | |
readPressure t = do | |
let s = head . filter (T.isInfixOf "Pression atm.") . T.lines $ t | |
let s' = T.unpack . snd. T.breakOn "Pression atm" $ s | |
parse pressionP "readPressure" s' | |
readDate :: Monad m => T.Text -> m LocalTime | |
readDate t = do | |
let s = head . filter (T.isInfixOf "Opérateur") . T.lines $ t | |
let s' = T.unpack . T.replace ": Le " "" . snd. T.breakOn ": Le " $ s | |
return $ parseTimeOrError True defaultTimeLocale "%d/%m/%Y %H:%M:%S" s' | |
parserFloat p l = do | |
case p l of | |
Left e -> do | |
putStrLn "Error parsing input:" | |
print e | |
return 99999 | |
Right r -> return r | |
main = do | |
l <- TIO.readFile "metrologie.txt" | |
p <- parserFloat readPressure l | |
h <- parserFloat readHygrometry l | |
t <- parserFloat readTemperature l | |
d <- readDate l | |
print $ Info h t p d |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment