1
{- arch-tag: ConfigParser parser support
2
Copyright (C) 2004 John Goerzen <jgoerzen@complete.org>
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU Lesser General Public License as published by
6
the Free Software Foundation; either version 2.1 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU Lesser General Public License for more details.
14
You should have received a copy of the GNU Lesser General Public License
15
along with this program; if not, write to the Free Software
16
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
Module : Data.ConfigFile.Parser
21
Copyright : Copyright (C) 2004 John Goerzen
22
License : GNU LGPL, version 2.1 or above
24
Maintainer : John Goerzen <jgoerzen@complete.org>
25
Stability : provisional
28
Parser support for "Data.ConfigFile". This module is not intended to be
29
used directly by your programs.
31
Copyright (c) 2004 John Goerzen, jgoerzen\@complete.org
33
module Data.ConfigFile.Parser
35
parse_string, parse_file, parse_handle, interpmain, ParseOutput
39
import Text.ParserCombinators.Parsec
40
import Control.Monad.Error(throwError, MonadError)
42
import Data.ConfigFile.Lexer
43
import System.IO(Handle, hGetContents)
44
import Text.ParserCombinators.Parsec.Utils
45
import Data.ConfigFile.Types
47
----------------------------------------------------------------------
49
----------------------------------------------------------------------
51
parse_string :: MonadError CPError m =>
52
String -> m ParseOutput
54
detokenize "(string)" $ parse loken "(string)" s
56
--parse_file :: FilePath -> IO (CPResult ParseOutput)
57
parse_file :: MonadError CPError m => FilePath -> IO (m ParseOutput)
59
do o <- parseFromFile loken f
60
return $ detokenize f o
62
--parse_handle :: Handle -> IO (CPResult ParseOutput)
63
parse_handle :: MonadError CPError m => Handle -> IO (m ParseOutput)
65
do s <- hGetContents h
66
let o = parse loken (show h) s
67
return $ detokenize (show h) o
69
----------------------------------------------------------------------
71
----------------------------------------------------------------------
73
let conv msg (Left err) = throwError $ (ParseError (show err), msg)
74
conv msg (Right val) = return val
75
in do r <- conv "lexer" l
76
conv "parser" $ runParser main () fp r
78
main :: GeneralizedTokenParser CPTok () ParseOutput
80
do {s <- sectionlist; return s}
84
return $ ("DEFAULT", o) : s
86
<|> do {o <- optionlist; return $ [("DEFAULT", o)] }
87
<?> "Error parsing config file tokens"
89
sectionlist :: GeneralizedTokenParser CPTok () ParseOutput
90
sectionlist = do {eof; return []}
101
section :: GeneralizedTokenParser CPTok () (String, [(String, String)])
102
section = do {sh <- sectionhead; ol <- optionlist; return (sh, ol)}
104
sectionhead :: GeneralizedTokenParser CPTok () String
106
let wf (NEWSECTION x) = Just x
109
do {s <- tokeng wf; return $ strip s}
111
optionlist :: GeneralizedTokenParser CPTok () [(String, String)]
112
optionlist = many1 coption
114
coption :: GeneralizedTokenParser CPTok () (String, String)
116
let wf (NEWOPTION x) = Just x
118
wfx (EXTENSIONLINE x) = Just x
122
l <- many $ tokeng wfx
123
return (strip (fst o), valmerge ((snd o) : l))
125
valmerge :: [String] -> String
127
let vl2 = map strip vallist
130
----------------------------------------------------------------------
132
----------------------------------------------------------------------
134
interpval :: Parser String
137
s <- (many1 $ noneOf ")") <?> "interpolation name"
138
string ")s" <?> "end of interpolation name"
141
percentval :: Parser String
146
interpother :: Parser String
151
interptok :: (String -> Either CPError String) -> Parser String
152
interptok lookupfunc = (try percentval)
154
<|> do s <- interpval
156
Left (InterpolationError x, _) -> fail x
157
Left _ -> fail $ "unresolvable interpolation reference to \"" ++ s ++ "\""
161
interpmain :: (String -> Either CPError String) -> Parser String
162
interpmain lookupfunc =
163
do r <- manyTill (interptok lookupfunc) eof