1{- arch-tag: ConfigParser lexer support 2Copyright (C) 2004, 2008 John Goerzen <jgoerzen@complete.org> 3 4This program is free software; you can redistribute it and/or modify it, as 5specified in the COPYRIGHT file, under the terms of either version 2.1 of 6the LGPL (or, at your option, any later version) or the 3-clause BSD license. 7-} 8 9{- | 10 Module : Data.ConfigFile.Lexer 11 Copyright : Copyright (C) 2004, 2008 John Goerzen 12 License : Either LGPL or BSD3, as specified in the COPYRIGHT file. 13 14 Maintainer : John Goerzen <jgoerzen@complete.org> 15 Stability : provisional 16 Portability: portable 17 18Lexer support for "Data.ConfigFile". This module is not intended to be 19used directly by your programs. 20 21Copyright (c) 2004, 2008 John Goerzen, jgoerzen\@complete.org 22 23This program is distributed in the hope that it will be useful, 24but WITHOUT ANY WARRANTY; without even the implied warranty of 25MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 26 27-} 28module Data.ConfigFile.Lexer 29( 30 -- -- * Temporary for testing 31 --comment_chars, eol, optionsep, whitespace_chars, comment_line, 32 --empty_line, sectheader_chars, sectheader, oname_chars, value_chars, 33 --extension_line, optionkey, optionvalue, optionpair 34 loken, 35 CPTok(..) 36) where 37 38import Text.ParserCombinators.Parsec 39import Text.ParserCombinators.Parsec.Utils 40 41data CPTok = IGNOREDATA 42 | NEWSECTION String 43 | NEWSECTION_EOF String 44 | EXTENSIONLINE String 45 | NEWOPTION (String, String) 46 deriving (Eq, Show, Ord) 47 48comment_chars :: CharParser st Char 49comment_chars = oneOf "#;" 50eol :: GenParser Char st String 51eol = string "\n" <|> string "\r\n" <|> string "\r" <?> "End of line" 52eoleof :: GenParser Char st () 53eoleof = eof <|> do {eol; return ()} 54optionsep :: GenParser Char st Char 55optionsep = oneOf ":=" <?> "option separator" 56whitespace_chars :: GenParser Char st Char 57whitespace_chars = oneOf " \t" <?> "whitespace" 58comment_line :: GenParser Char st () 59comment_line = do skipMany whitespace_chars 60 comment_chars <?> "start of comment" 61 (many $ noneOf "\r\n") <?> "content of comment" 62 eoleof 63eolstuff :: GenParser Char st () 64eolstuff = (try comment_line) <|> (try empty_line) 65empty_line :: GenParser Char st () 66empty_line = do many whitespace_chars 67 eoleof 68 <?> "empty line" 69sectheader_chars :: CharParser st Char 70sectheader_chars = noneOf "]\r\n" 71sectheader :: GenParser Char st String 72sectheader = do char '[' 73 sname <- many1 $ sectheader_chars 74 char ']' 75 eolstuff 76 return sname 77 <?> "start of section" 78oname_chars :: CharParser st Char 79oname_chars = noneOf ":=\r\n" 80value_chars :: CharParser st Char 81value_chars = noneOf "\r\n" 82extension_line :: GenParser Char st String 83extension_line = do many1 whitespace_chars 84 c1 <- noneOf "\r\n#;" 85 remainder <- many value_chars 86 eolstuff 87 return (c1 : remainder) 88 89optionkey, optionvalue :: GenParser Char st String 90optionkey = many1 oname_chars 91optionvalue = many value_chars 92optionpair :: GenParser Char st (String, String) 93optionpair = do key <- optionkey 94 value <- option "" $ do { optionsep; optionvalue } 95 eolstuff 96 return (key, value) 97 <?> "key/value option" 98 99iloken :: Parser (GeneralizedToken CPTok) 100iloken = 101 -- Ignore these things 102 try (do {comment_line; togtok $ IGNOREDATA}) 103 <|> try (do {empty_line; togtok $ IGNOREDATA}) 104 105 -- Real stuff 106 <|> (do {sname <- sectheader; togtok $ NEWSECTION sname}) 107 <|> try (do {extension <- extension_line; togtok $ EXTENSIONLINE extension}) 108 <|> try (do {pair <- optionpair; togtok $ NEWOPTION pair}) 109-- <?> "Invalid syntax in configuration file" 110 111loken :: Parser [GeneralizedToken CPTok] 112loken = do x <- manyTill iloken eof 113 return $ filter (\y -> snd y /= IGNOREDATA) x 114