Created
August 17, 2013 06:02
-
-
Save rgrinberg/6255522 to your computer and use it in GitHub Desktop.
simple ini parser using attoparsec
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
{-# LANGUAGE OverloadedStrings #-} | |
module Inisec where | |
import Prelude as P | |
import Data.Attoparsec.Text | |
import Data.Text.IO as T | |
import Data.Text | |
import Control.Applicative | |
data Section = Section | |
{ entries :: [(Text, Text)] | |
, name :: Maybe Text | |
} deriving (Show) | |
type IniFile = [Section] | |
comment :: Parser () | |
comment = do | |
char ';' | |
skipWhile (/= '\n') | |
try $ char '\n' | |
return () | |
sectionName :: Parser Text | |
sectionName = do | |
char '[' | |
name <- takeTill (== ']') | |
char ']' | |
return name | |
entry :: Parser (Text, Text) | |
entry = do | |
key <- takeTill (== '=') | |
char '=' | |
value <- manyTill anyChar (try endOfLine <|> try comment <|> try endOfInput) | |
return (strip key, strip . pack $ value) | |
-- | take a parser and wrap it around garbage stripping | |
wrapStrip :: Parser a -> Parser a | |
wrapStrip p = do | |
crap | |
x <- p | |
crap | |
return x | |
where crap = (try $ skipMany comment) <|> (try skipSpace) | |
section :: Parser Section | |
section = do | |
sectionName <- sectionName | |
sectionEntries <- many $ wrapStrip entry | |
return $ Section sectionEntries (Just sectionName) | |
anonSection :: Parser Section | |
anonSection = do | |
sectionEntries <- many $ wrapStrip entry | |
return $ Section sectionEntries Nothing | |
parseIni :: Parser IniFile | |
parseIni = many $ wrapStrip section | |
parseIniFile :: FilePath -> IO (Either String IniFile) | |
parseIniFile path = do | |
file <- T.readFile path | |
return $ parseOnly parseIni file | |
main :: IO () | |
main = do | |
file <- T.readFile "sample.ini" | |
case parseOnly parseIni file of | |
Left error -> P.putStrLn $ "Error parsing: " ++ error | |
Right x -> P.putStrLn (show x) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment