Skip to content

Commit 326f74f

Browse files
authored
Merge pull request #12 from maksbotan/maksbotan/fix-list-parser
Improve list parser
2 parents 5f2ed1c + 7ae6642 commit 326f74f

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

src/Hie/Cabal/Parser.hs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Control.Applicative
66
import Control.Monad
77
import Data.Attoparsec.Text
88
import Data.Char
9+
import Data.Functor
910
import Data.Maybe
1011
import Data.Text (Text)
1112
import qualified Data.Text as T
@@ -92,19 +93,24 @@ parseString = parseQuoted <|> unqualName
9293
unqualName :: Parser Text
9394
unqualName = takeWhile1 (not . (\c -> isSpace c || c == ','))
9495

96+
-- | Skip spaces and if enf of line is reached, skip it as well and require that
97+
-- next one starts with indent.
98+
--
99+
-- Used for parsing fields.
100+
optSkipToNextLine :: Indent -> Parser ()
101+
optSkipToNextLine i = do
102+
skipMany $ satisfy (\c -> isSpace c && not (isEndOfLine c))
103+
mChar <- peekChar
104+
case mChar of
105+
Just c | isEndOfLine c ->
106+
char c *> indent i $> ()
107+
_ -> pure ()
108+
109+
-- | Comma or space separated list, with optional new lines.
95110
parseList :: Indent -> Parser [Text]
96111
parseList i = items <|> (emptyOrComLine >> indent i >> items)
97112
where
98-
items = do
99-
skipMany tabOrSpace
100-
h <- parseString
101-
skipMany tabOrSpace
102-
skipMany (char ',')
103-
t <-
104-
items
105-
<|> (skipToNextLine >> indent i >> parseList i)
106-
<|> pure []
107-
pure $ h : t
113+
items = sepBy parseString (optSkipToNextLine i *> skipMany (char ',') *> optSkipToNextLine i)
108114

109115
pathMain :: Indent -> [Text] -> Text -> [Text] -> [Text] -> Parser [Text]
110116
pathMain i p m o a =

test/Spec.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ spec = do
8686
$ it "quoted list"
8787
$ ("\"one\"\n two\n three3" :: Text) ~> parseList 1
8888
`shouldParse` ["one", "two", "three3"]
89+
describe "Should Succeed"
90+
$ it "list with leading commas"
91+
$ ("one\n , two\n , three3" :: Text) ~> parseList 1
92+
`shouldParse` ["one", "two", "three3"]
8993

9094
exeSection :: Text
9195
exeSection =

0 commit comments

Comments
 (0)