From 24a4ffdce4b580ba6a0fed1c86419700a610ba46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benno=20F=C3=BCnfst=C3=BCck?= Date: Sat, 16 Aug 2014 01:17:01 +0200 Subject: [PATCH] now really fix parsing paths --- Nix/Parser.hs | 24 ++++++++++-------------- tests/ParserTests.hs | 7 +++++-- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/Nix/Parser.hs b/Nix/Parser.hs index 7516881..ae0b8e8 100644 --- a/Nix/Parser.hs +++ b/Nix/Parser.hs @@ -43,20 +43,19 @@ nixAntiquoted :: Parser a -> Parser (Antiquoted a NExpr) nixAntiquoted p = Plain <$> p <|> Antiquoted <$> (try (string "${") *> whiteSpace *> nixApp <* symbolic '}') +selDot :: Parser () +selDot = try (char '.' *> notFollowedBy (("path" :: String) <$ nixPath)) *> whiteSpace + nixSelector :: Parser (NSelector NExpr) -nixSelector = keyName `sepBy1` symbolic '.' +nixSelector = keyName `sepBy1` selDot where nixSelect :: Parser NExpr -> Parser NExpr nixSelect term = build <$> term - <*> optional (char '.' *> choice - [ Left <$> nixPath - , fmap Right $ (,) <$> nixSelector <*> optional (reserved "or" *> nixApp) - ]) + <*> optional ((,) <$> (selDot *> nixSelector) <*> optional (reserved "or" *> nixApp)) where build t Nothing = t - build t (Just (Left p)) = Fix $ NApp t (mkPath $ '.' : p) - build t (Just (Right (s,o))) = Fix $ NSelect t s o + build t (Just (s,o)) = Fix $ NSelect t s o nixHasAttr :: Parser NExpr -> Parser NExpr nixHasAttr term = build <$> term <*> optional (reservedOp "?" *> nixSelector) where @@ -72,7 +71,7 @@ nixTerm = choice , nixIf , nixBool , nixNull - , nixPathExpr -- can be expensive due to back-tracking + , nixPath -- can be expensive due to back-tracking , try nixLambda <|> nixSet , nixStringExpr , nixSym @@ -98,14 +97,11 @@ nixParens = parens nixApp "parens" nixList :: Parser NExpr nixList = brackets (Fix . NList <$> many (listTerm <* whiteSpace)) "list" where listTerm = nixSelect $ choice - [ nixInt, nixParens, nixList, nixSet, nixBool, nixNull, nixPathExpr, nixStringExpr + [ nixInt, nixParens, nixList, nixSet, nixBool, nixNull, nixPath, nixStringExpr , nixSym ] -nixPathExpr :: Parser NExpr -nixPathExpr = mkPath <$> nixPath - -nixPath :: Parser String -nixPath = (++) +nixPath :: Parser NExpr +nixPath = fmap mkPath $ (++) <$> try ((++) <$> many (oneOf pathChars) <*> string "/") <*> some (oneOf ('/':pathChars)) where pathChars = ['A'..'Z'] ++ ['a'..'z'] ++ "._-+" ++ ['0'..'9'] diff --git a/tests/ParserTests.hs b/tests/ParserTests.hs index b135154..f991247 100644 --- a/tests/ParserTests.hs +++ b/tests/ParserTests.hs @@ -201,8 +201,11 @@ case_string_antiquote = do assertParseFail "${true}" assertParseFail "\"${true\"" -case_fun_app_path :: Assertion -case_fun_app_path = assertParseString "f ./." $ Fix $ NApp (mkSym "f") (mkPath "./.") +case_select_path :: Assertion +case_select_path = do + assertParseString "f ./." $ Fix $ NApp (mkSym "f") (mkPath "./.") + assertParseString "f.b ../a" $ Fix $ NApp select (mkPath "../a") + where select = Fix $ NSelect (mkSym "f") (mkSelector "b") Nothing tests :: TestTree tests = $testGroupGenerator