morley-1.16.0: src/Morley/Michelson/Parser/Helpers.hs
-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ
module Morley.Michelson.Parser.Helpers
( mkParser
, sepEndBy1
, some'
, sepBy1
, sepBy2
, parseDef
, positive
) where
import Data.Default (Default(..))
import qualified Data.List.NonEmpty as NE
import qualified Text.Megaparsec as P
import Text.Megaparsec.Char.Lexer (decimal)
import Morley.Michelson.Parser.Lexer (word')
import Morley.Michelson.Parser.Types (Parser)
import Morley.Util.Positive
-- | Version of 'P.sepEndBy1' returning a 'NonEmpty' list
sepEndBy1 :: MonadPlus m => m a -> m sep -> m (NonEmpty a)
sepEndBy1 = fmap NE.fromList ... P.sepEndBy1
-- | Version of 'P.some' returning a 'NonEmpty' list
some' :: MonadPlus f => f a -> f (NonEmpty a)
some' = fmap NE.fromList . P.some
-- | Version of 'P.sepBy1' returning a 'NonEmpty' list
sepBy1 :: MonadPlus f => f a -> f sep -> f (NonEmpty a)
sepBy1 = fmap NE.fromList ... P.sepBy1
-- | @endBy2 p sep@ parses two or more occurrences of @p@, separated by @sep@.
sepBy2 :: MonadPlus m => m a -> m sep -> m (NonEmpty a)
sepBy2 parser sep = do
e <- parser
void sep
es <- P.sepBy1 parser sep
return $ e :| es
-- | Make a parser from a string
mkParser :: (a -> Text) -> a -> Parser a
mkParser f a = P.try $ word' (f a) a
-- | Apply given parser and return default value if it fails.
parseDef :: Default a => Parser a -> Parser a
parseDef a = P.try a <|> pure def
-- | Parse a positive number.
positive :: Parser Positive
positive = do
n :: Integer <- decimal
mkPositive n
& either (fail . toString) pure