module BishBosh.ContextualNotation.PGNComment(
PGNComment(..),
blockCommentEnd,
lineCommentEnd,
blockCommentParser,
parser,
getString
) where
import Control.Applicative((<|>))
import qualified Control.Applicative
#ifdef USE_POLYPARSE
import qualified BishBosh.Text.Poly as Text.Poly
#if USE_POLYPARSE == 1
import qualified Text.ParserCombinators.Poly.Lazy as Poly
#else /* Plain */
import qualified Text.ParserCombinators.Poly.Plain as Poly
#endif
#else /* Parsec */
import qualified Control.Monad
import qualified Text.ParserCombinators.Parsec as Parsec
import Text.ParserCombinators.Parsec((<?>))
#endif
blockCommentStart :: Char
blockCommentStart = '{'
blockCommentEnd :: Char
blockCommentEnd = '}'
lineCommentStart :: Char
lineCommentStart = ';'
lineCommentEnd :: Char
lineCommentEnd = '\n'
data PGNComment = BlockComment String | LineComment String
instance Show PGNComment where
showsPrec _ (BlockComment s) = showChar blockCommentStart . showString s . showChar blockCommentEnd
showsPrec _ (LineComment s) = showChar lineCommentStart . showString s . showChar lineCommentEnd
getString :: PGNComment -> String
getString (BlockComment s) = s
getString (LineComment s) = s
blockCommentParser ::
#ifdef USE_POLYPARSE
Text.Poly.TextParser PGNComment
blockCommentParser = Text.Poly.spaces >> Poly.bracket (
Text.Poly.char blockCommentStart
) (
Text.Poly.char blockCommentEnd
) (
BlockComment `fmap` Control.Applicative.many (Poly.satisfyMsg (/= blockCommentEnd) "Block-comment")
)
#else /* Parsec */
Parsec.Parser PGNComment
blockCommentParser = Parsec.try (
Parsec.spaces >> Parsec.between (
Parsec.char blockCommentStart <?> "Block-comment start"
) (
Parsec.char blockCommentEnd <?> "Block-comment end"
) (
BlockComment `fmap` Control.Applicative.many (Parsec.satisfy (/= blockCommentEnd)) <?> "Block-comment text"
) <?> "Block-comment"
)
#endif
lineCommentParser ::
#ifdef USE_POLYPARSE
Text.Poly.TextParser PGNComment
lineCommentParser = Text.Poly.spaces >> Poly.bracket (
Text.Poly.char lineCommentStart
) (
Poly.commit $ Text.Poly.char lineCommentEnd <|> Poly.eof
) (
LineComment `fmap` Control.Applicative.many (Poly.satisfyMsg (/= lineCommentEnd) "Line-comment text")
)
#else /* Parsec */
Parsec.Parser PGNComment
lineCommentParser = Parsec.try (
Parsec.spaces >> Parsec.between (
Parsec.char lineCommentStart <?> "Line-comment start"
) (
Control.Monad.void (Parsec.char lineCommentEnd <?> "EOLN") <|> (Parsec.eof <?> "EOF")
) (
LineComment `fmap` Control.Applicative.many (Parsec.satisfy (/= lineCommentEnd)) <?> "Line-comment text"
) <?> "Line-comment"
)
#endif
parser ::
#ifdef USE_POLYPARSE
Text.Poly.TextParser String
#else /* Parsec */
Parsec.Parser String
#endif
parser = fmap getString $ blockCommentParser <|> lineCommentParser