mirror of
https://github.com/Avi-D-coder/implicit-hie.git
synced 2024-09-11 09:05:25 +03:00
Improve list parser
Current parser for lists, like `packages:` in `cabal.project.local`, fails to process some input, for example: packages: foo/foo.cabal , bar/bar.cabal , baz/baz.cabal This commit simplifies the parser by using `sepBy` directly and by handling indented fields more uniformly.
This commit is contained in:
parent
5f2ed1c9cf
commit
7ae66425ab
@ -6,6 +6,7 @@ import Control.Applicative
|
||||
import Control.Monad
|
||||
import Data.Attoparsec.Text
|
||||
import Data.Char
|
||||
import Data.Functor
|
||||
import Data.Maybe
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as T
|
||||
@ -92,19 +93,24 @@ parseString = parseQuoted <|> unqualName
|
||||
unqualName :: Parser Text
|
||||
unqualName = takeWhile1 (not . (\c -> isSpace c || c == ','))
|
||||
|
||||
-- | Skip spaces and if enf of line is reached, skip it as well and require that
|
||||
-- next one starts with indent.
|
||||
--
|
||||
-- Used for parsing fields.
|
||||
optSkipToNextLine :: Indent -> Parser ()
|
||||
optSkipToNextLine i = do
|
||||
skipMany $ satisfy (\c -> isSpace c && not (isEndOfLine c))
|
||||
mChar <- peekChar
|
||||
case mChar of
|
||||
Just c | isEndOfLine c ->
|
||||
char c *> indent i $> ()
|
||||
_ -> pure ()
|
||||
|
||||
-- | Comma or space separated list, with optional new lines.
|
||||
parseList :: Indent -> Parser [Text]
|
||||
parseList i = items <|> (emptyOrComLine >> indent i >> items)
|
||||
where
|
||||
items = do
|
||||
skipMany tabOrSpace
|
||||
h <- parseString
|
||||
skipMany tabOrSpace
|
||||
skipMany (char ',')
|
||||
t <-
|
||||
items
|
||||
<|> (skipToNextLine >> indent i >> parseList i)
|
||||
<|> pure []
|
||||
pure $ h : t
|
||||
items = sepBy parseString (optSkipToNextLine i *> skipMany (char ',') *> optSkipToNextLine i)
|
||||
|
||||
pathMain :: Indent -> [Text] -> Text -> [Text] -> [Text] -> Parser [Text]
|
||||
pathMain i p m o a =
|
||||
|
@ -86,6 +86,10 @@ spec = do
|
||||
$ it "quoted list"
|
||||
$ ("\"one\"\n two\n three3" :: Text) ~> parseList 1
|
||||
`shouldParse` ["one", "two", "three3"]
|
||||
describe "Should Succeed"
|
||||
$ it "list with leading commas"
|
||||
$ ("one\n , two\n , three3" :: Text) ~> parseList 1
|
||||
`shouldParse` ["one", "two", "three3"]
|
||||
|
||||
exeSection :: Text
|
||||
exeSection =
|
||||
|
Loading…
Reference in New Issue
Block a user