From 93e0e3e64e042246ec4cd40d11b8c172acf49181 Mon Sep 17 00:00:00 2001 From: Dylan Simon Date: Fri, 22 May 2015 19:53:40 -0400 Subject: [PATCH] Allow one-line grouping using "." in idents Fixes #19 --- .gitignore | 1 + Data/Configurator/Parser.hs | 25 +++++++++++++++++++------ tests/resources/interp.cfg | 6 ++---- tests/resources/pathological.cfg | 4 +++- 4 files changed, 25 insertions(+), 11 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..178135c --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/dist/ diff --git a/Data/Configurator/Parser.hs b/Data/Configurator/Parser.hs index 1eafeb6..ec587fe 100644 --- a/Data/Configurator/Parser.hs +++ b/Data/Configurator/Parser.hs @@ -34,12 +34,11 @@ topLevel = directives <* skipLWS <* endOfInput directive :: Parser Directive directive = - mconcat [ - string "import" *> skipLWS *> (Import <$> string_) - , Bind <$> try (ident <* skipLWS <* char '=' <* skipLWS) <*> value - , Group <$> try (ident <* skipLWS <* char '{' <* skipLWS) - <*> directives <* skipLWS <* char '}' - ] + string "import" *> skipLWS *> (Import <$> string_) + <|> do + ids <- idents + skipLWS + groupIdents (\n -> bind n <|> group n) ids directives :: Parser [Directive] directives = (skipLWS *> directive <* skipHWS) `sepBy` @@ -77,6 +76,14 @@ ident = do where isCont c = isAlphaNum c || c == '_' || c == '-' +idents :: Parser [Name] +idents = sepBy1 ident (char '.') + +groupIdents :: (Name -> Parser Directive) -> [Name] -> Parser Directive +groupIdents p [n] = p n +groupIdents p (g:n) = Group g . return <$> groupIdents p n +groupIdents p [] = p (error "empty ident") + value :: Parser Value value = mconcat [ string "on" *> pure (Bool True) @@ -89,6 +96,12 @@ value = mconcat [ ((value <* skipLWS) `sepBy` (char ',' <* skipLWS)) ] +bind :: Name -> Parser Directive +bind n = char '=' >> skipLWS >> Bind n <$> value + +group :: Name -> Parser Directive +group n = brackets '{' '}' $ Group n <$> directives <* skipLWS + string_ :: Parser Text string_ = do s <- char '"' *> scan False isChar <* char '"' diff --git a/tests/resources/interp.cfg b/tests/resources/interp.cfg index db339f5..7787d19 100644 --- a/tests/resources/interp.cfg +++ b/tests/resources/interp.cfg @@ -1,7 +1,7 @@ services = "$(HOME)/services" root = "can be overwritten by inner block." +myprogram.name="myprogram" myprogram { - name = "myprogram" root = "$(services)/$(name)" exec = "$(root)/$(name)" stdout = "$(root)/stdout" @@ -13,8 +13,6 @@ top { dir = "$(dir)/top" layer1 { dir = "$(dir)/layer1" - layer2 { - dir = "$(dir)/layer2" - } + layer2.dir ="$(dir)/layer2" } } diff --git a/tests/resources/pathological.cfg b/tests/resources/pathological.cfg index 77188e5..9d576bb 100644 --- a/tests/resources/pathological.cfg +++ b/tests/resources/pathological.cfg @@ -30,10 +30,12 @@ af #baz ]#quux -ag { q-e { i_u9 { a=false}}} +ag { q-e { i_u9 { a=true}}} ba = "$(HOME)" xs = [1,2,3] c = "x" + +ag.q-e.i_u9.a=false