Created
March 22, 2018 21:12
-
-
Save cocreature/8db4a6b72fdabf28f7537b73e9d037ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE TupleSections #-} | |
import Control.Monad | |
import Data.Text (Text) | |
import Data.Void | |
import Text.Megaparsec | |
import Text.Megaparsec.Char | |
import qualified Text.Megaparsec.Char.Lexer as Lexer | |
type Parser = Parsec Void Text | |
sc :: Parser () | |
sc = Lexer.space (void (takeWhile1P Nothing f)) lineComment empty | |
where f x = x `elem` [' ', '\t'] | |
scn :: Parser () | |
scn = Lexer.space space1 lineComment empty | |
lineComment :: Parser () | |
lineComment = Lexer.skipLineComment "#" | |
symbol :: Text -> Parser Text | |
symbol = Lexer.symbol sc | |
parseList :: Parser [Either (ParseError Char Void) Text] | |
parseList = | |
many (withRecovery recover (Right <$> p)) <* eof | |
where | |
recover e = | |
-- Changing this to skipManyTill anyChar (eof <|> void newline) will lead to an infinite loop since skipManyTill anyChar eof will always succeed. | |
Left e <$ skipManyTill anyChar (void newline) | |
p = do | |
s <- try (symbol "foobar" <* notFollowedBy alphaNumChar) | |
scn | |
pure s | |
main :: IO () | |
main = do | |
-- This works fine | |
parseTest parseList ("foobar2\nfoobar3\n") | |
-- This will fail completely since we have nothing to sync up on. | |
parseTest parseList ("foobar2\nfoobar3") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment