{-# LANGUAGE NamedFieldPuns, RecordWildCards, TemplateHaskell, FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-missing-fields #-}

-- | Interpolated here docs
module Data.String.Here.Interpolated (i, iTrim, template) where

import Control.Applicative hiding ((<|>))
import Control.Monad.State

import Data.Char
import Data.Maybe
import Data.Monoid
import Data.String
import Data.Typeable

import Language.Haskell.Meta
import Language.Haskell.TH
import Language.Haskell.TH.Quote

import Text.Parsec
import Text.Parsec.Prim
import Text.Parsec.String

import Data.String.Here.Internal

data StringPart = Lit String | Esc Char | Anti (Q Exp)

data HsChompState = HsChompState { HsChompState -> QuoteState
quoteState :: QuoteState
                                 , HsChompState -> Int
braceCt :: Int
                                 , HsChompState -> String
consumed :: String
                                 , HsChompState -> Bool
prevCharWasIdentChar :: Bool
                                 }

data QuoteState = None | Single EscapeState | Double EscapeState

data EscapeState = Escaped | Unescaped

-- | Quote a here doc with embedded antiquoted expressions
--
-- Any expression occurring between @${@ and @}@ (for which the type must have
-- 'Show' and 'Typeable' instances) will be interpolated into the quoted
-- string.
--
-- Characters preceded by a backslash are treated literally. This enables the
-- inclusion of the literal substring @${@ within your quoted text by writing
-- it as @\\${@. The literal sequence @\\${@ may be written as @\\\\${@.
i :: QuasiQuoter
i :: QuasiQuoter
i = QuasiQuoter :: (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter {quoteExp :: String -> Q Exp
quoteExp = String -> Q Exp
quoteInterp}

-- | Like 'i', but with leading and trailing whitespace trimmed
iTrim :: QuasiQuoter
iTrim :: QuasiQuoter
iTrim = QuasiQuoter :: (String -> Q Exp)
-> (String -> Q Pat)
-> (String -> Q Type)
-> (String -> Q [Dec])
-> QuasiQuoter
QuasiQuoter {quoteExp :: String -> Q Exp
quoteExp = String -> Q Exp
quoteInterp (String -> Q Exp) -> (String -> String) -> String -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
trim}

-- | Quote the contents of a file as with 'i'
--
-- This enables usage as a simple template engine
template :: QuasiQuoter
template :: QuasiQuoter
template = QuasiQuoter -> QuasiQuoter
quoteDependentFile QuasiQuoter
i

quoteInterp :: String -> Q Exp
quoteInterp :: String -> Q Exp
quoteInterp s :: String
s = (ParseError -> Q Exp)
-> ([StringPart] -> Q Exp)
-> Either ParseError [StringPart]
-> Q Exp
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> ParseError -> Q Exp
handleError String
s) [StringPart] -> Q Exp
combineParts (String -> Either ParseError [StringPart]
parseInterp String
s)

handleError :: String -> ParseError -> Q Exp
handleError :: String -> ParseError -> Q Exp
handleError expStr :: String
expStr parseError :: ParseError
parseError = String -> Q Exp
forall a. HasCallStack => String -> a
error (String -> Q Exp) -> String -> Q Exp
forall a b. (a -> b) -> a -> b
$
  "Failed to parse interpolated expression in string: "
    String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
expStr
    String -> String -> String
forall a. [a] -> [a] -> [a]
++ "\n"
    String -> String -> String
forall a. [a] -> [a] -> [a]
++ ParseError -> String
forall a. Show a => a -> String
show ParseError
parseError

combineParts :: [StringPart] -> Q Exp
combineParts :: [StringPart] -> Q Exp
combineParts = [Q Exp] -> Q Exp
combine ([Q Exp] -> Q Exp)
-> ([StringPart] -> [Q Exp]) -> [StringPart] -> Q Exp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (StringPart -> Q Exp) -> [StringPart] -> [Q Exp]
forall a b. (a -> b) -> [a] -> [b]
map StringPart -> Q Exp
toExpQ
  where
    toExpQ :: StringPart -> Q Exp
toExpQ (Lit s :: String
s) = String -> Q Exp
stringE String
s
    toExpQ (Esc c :: Char
c) = String -> Q Exp
stringE [Char
c]
    toExpQ (Anti expq :: Q Exp
expq) = [|toString $expq|]
    combine :: [Q Exp] -> Q Exp
combine [] = String -> Q Exp
stringE ""
    combine parts :: [Q Exp]
parts = (Q Exp -> Q Exp -> Q Exp) -> [Q Exp] -> Q Exp
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (\subExpr :: Q Exp
subExpr acc :: Q Exp
acc -> [|$subExpr <> $acc|]) [Q Exp]
parts

toString :: (Show a, Typeable a, Typeable b, IsString b) => a -> b
toString :: a -> b
toString x :: a
x = b -> Maybe b -> b
forall a. a -> Maybe a -> a
fromMaybe (String -> b
forall a. IsString a => String -> a
fromString (String -> b) -> String -> b
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
x) (a -> Maybe b
forall a b. (Typeable a, Typeable b) => a -> Maybe b
cast a
x)

parseInterp :: String -> Either ParseError [StringPart]
parseInterp :: String -> Either ParseError [StringPart]
parseInterp = Parsec String () [StringPart]
-> String -> String -> Either ParseError [StringPart]
forall s t a.
Stream s Identity t =>
Parsec s () a -> String -> s -> Either ParseError a
parse Parsec String () [StringPart]
p_interp ""

p_interp :: Parser [StringPart]
p_interp :: Parsec String () [StringPart]
p_interp = ParsecT String () Identity StringPart
-> ParsecT String () Identity () -> Parsec String () [StringPart]
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill ParsecT String () Identity StringPart
p_stringPart ParsecT String () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof

p_stringPart :: Parser StringPart
p_stringPart :: ParsecT String () Identity StringPart
p_stringPart = ParsecT String () Identity StringPart
p_anti ParsecT String () Identity StringPart
-> ParsecT String () Identity StringPart
-> ParsecT String () Identity StringPart
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String () Identity StringPart
p_esc ParsecT String () Identity StringPart
-> ParsecT String () Identity StringPart
-> ParsecT String () Identity StringPart
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String () Identity StringPart
p_lit

p_anti :: Parser StringPart
p_anti :: ParsecT String () Identity StringPart
p_anti = Q Exp -> StringPart
Anti (Q Exp -> StringPart)
-> ParsecT String () Identity (Q Exp)
-> ParsecT String () Identity StringPart
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT String () Identity String
-> ParsecT String () Identity String
-> ParsecT String () Identity (Q Exp)
-> ParsecT String () Identity (Q Exp)
forall s (m :: * -> *) t u open close a.
Stream s m t =>
ParsecT s u m open
-> ParsecT s u m close -> ParsecT s u m a -> ParsecT s u m a
between (ParsecT String () Identity String
-> ParsecT String () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try ParsecT String () Identity String
p_antiOpen) ParsecT String () Identity String
p_antiClose ParsecT String () Identity (Q Exp)
p_antiExpr

p_antiOpen :: Parser String
p_antiOpen :: ParsecT String () Identity String
p_antiOpen = String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "${"

p_antiClose :: Parser String
p_antiClose :: ParsecT String () Identity String
p_antiClose = String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "}"

p_antiExpr :: Parser (Q Exp)
p_antiExpr :: ParsecT String () Identity (Q Exp)
p_antiExpr = ParsecT String () Identity String
p_untilUnbalancedCloseBrace
         ParsecT String () Identity String
-> (String -> ParsecT String () Identity (Q Exp))
-> ParsecT String () Identity (Q Exp)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> ParsecT String () Identity (Q Exp))
-> (Exp -> ParsecT String () Identity (Q Exp))
-> Either String Exp
-> ParsecT String () Identity (Q Exp)
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either String -> ParsecT String () Identity (Q Exp)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (Q Exp -> ParsecT String () Identity (Q Exp)
forall (m :: * -> *) a. Monad m => a -> m a
return (Q Exp -> ParsecT String () Identity (Q Exp))
-> (Exp -> Q Exp) -> Exp -> ParsecT String () Identity (Q Exp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Exp -> Q Exp
forall (m :: * -> *) a. Monad m => a -> m a
return) (Either String Exp -> ParsecT String () Identity (Q Exp))
-> (String -> Either String Exp)
-> String
-> ParsecT String () Identity (Q Exp)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Either String Exp
parseExp

p_untilUnbalancedCloseBrace :: Parser String
p_untilUnbalancedCloseBrace :: ParsecT String () Identity String
p_untilUnbalancedCloseBrace = StateT HsChompState (ParsecT String () Identity) String
-> HsChompState -> ParsecT String () Identity String
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m a
evalStateT StateT HsChompState (ParsecT String () Identity) String
go (HsChompState -> ParsecT String () Identity String)
-> HsChompState -> ParsecT String () Identity String
forall a b. (a -> b) -> a -> b
$ QuoteState -> Int -> String -> Bool -> HsChompState
HsChompState QuoteState
None 0 "" Bool
False
  where
    go :: StateT HsChompState (ParsecT String () Identity) String
go = do
      Char
c <- ParsecT String () Identity Char
-> StateT HsChompState (ParsecT String () Identity) Char
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar
      (HsChompState -> HsChompState)
-> StateT HsChompState (ParsecT String () Identity) ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((HsChompState -> HsChompState)
 -> StateT HsChompState (ParsecT String () Identity) ())
-> (HsChompState -> HsChompState)
-> StateT HsChompState (ParsecT String () Identity) ()
forall a b. (a -> b) -> a -> b
$ \st :: HsChompState
st@HsChompState {String
consumed :: String
consumed :: HsChompState -> String
consumed} -> HsChompState
st {consumed :: String
consumed = Char
cChar -> String -> String
forall a. a -> [a] -> [a]
:String
consumed}
      HsChompState {..} <- StateT HsChompState (ParsecT String () Identity) HsChompState
forall s (m :: * -> *). MonadState s m => m s
get
      let next :: StateT HsChompState (ParsecT String () Identity) String
next = Char -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *). MonadState HsChompState m => Char -> m ()
setIdentifierCharState Char
c StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StateT HsChompState (ParsecT String () Identity) String
go
      case QuoteState
quoteState of
        None -> case Char
c of
          '{' -> Int -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *). MonadState HsChompState m => Int -> m ()
incBraceCt 1 StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StateT HsChompState (ParsecT String () Identity) String
next
          '}' | Int
braceCt Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0 -> Int -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *). MonadState HsChompState m => Int -> m ()
incBraceCt (-1) StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StateT HsChompState (ParsecT String () Identity) String
next
              | Bool
otherwise -> StateT HsChompState (ParsecT String () Identity) ()
forall u. StateT HsChompState (ParsecT String u Identity) ()
stepBack StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> String
forall a. [a] -> [a]
reverse (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
tail String
consumed)
          '\'' -> Bool
-> StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
prevCharWasIdentChar (QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState (QuoteState -> StateT HsChompState (ParsecT String () Identity) ())
-> QuoteState
-> StateT HsChompState (ParsecT String () Identity) ()
forall a b. (a -> b) -> a -> b
$ EscapeState -> QuoteState
Single EscapeState
Unescaped)
               StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StateT HsChompState (ParsecT String () Identity) String
next
          '"' -> QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState (EscapeState -> QuoteState
Double EscapeState
Unescaped) StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StateT HsChompState (ParsecT String () Identity) String
next
          _ -> StateT HsChompState (ParsecT String () Identity) String
next
        Single Unescaped -> do case Char
c of '\\' -> QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState (EscapeState -> QuoteState
Single EscapeState
Escaped)
                                         '\'' -> QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState QuoteState
None
                                         _ -> () -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                               StateT HsChompState (ParsecT String () Identity) String
next
        Single Escaped -> QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState (EscapeState -> QuoteState
Single EscapeState
Unescaped) StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StateT HsChompState (ParsecT String () Identity) String
next
        Double Unescaped -> do case Char
c of '\\' -> QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState (EscapeState -> QuoteState
Double EscapeState
Escaped)
                                         '"' -> QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState QuoteState
None
                                         _ -> () -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
                               StateT HsChompState (ParsecT String () Identity) String
next
        Double Escaped -> QuoteState -> StateT HsChompState (ParsecT String () Identity) ()
forall (m :: * -> *).
MonadState HsChompState m =>
QuoteState -> m ()
setQuoteState (EscapeState -> QuoteState
Double EscapeState
Unescaped) StateT HsChompState (ParsecT String () Identity) ()
-> StateT HsChompState (ParsecT String () Identity) String
-> StateT HsChompState (ParsecT String () Identity) String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> StateT HsChompState (ParsecT String () Identity) String
next
    stepBack :: StateT HsChompState (ParsecT String u Identity) ()
stepBack = ParsecT String u Identity ()
-> StateT HsChompState (ParsecT String u Identity) ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ParsecT String u Identity ()
 -> StateT HsChompState (ParsecT String u Identity) ())
-> ParsecT String u Identity ()
-> StateT HsChompState (ParsecT String u Identity) ()
forall a b. (a -> b) -> a -> b
$
      (State String u -> State String u)
-> ParsecT String u Identity (State String u)
forall s u (m :: * -> *).
(State s u -> State s u) -> ParsecT s u m (State s u)
updateParserState
        (\s :: State String u
s -> State String u
s {statePos :: SourcePos
statePos = SourcePos -> Int -> SourcePos
incSourceColumn (State String u -> SourcePos
forall s u. State s u -> SourcePos
statePos State String u
s) (-1)})
        ParsecT String u Identity (State String u)
-> ParsecT String u Identity String
-> ParsecT String u Identity String
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT String u Identity String
forall (m :: * -> *) s u. Monad m => ParsecT s u m s
getInput
        ParsecT String u Identity String
-> (String -> ParsecT String u Identity ())
-> ParsecT String u Identity ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> ParsecT String u Identity ()
forall (m :: * -> *) s u. Monad m => s -> ParsecT s u m ()
setInput (String -> ParsecT String u Identity ())
-> (String -> String) -> String -> ParsecT String u Identity ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ('}'Char -> String -> String
forall a. a -> [a] -> [a]
:)
    incBraceCt :: Int -> m ()
incBraceCt n :: Int
n = (HsChompState -> HsChompState) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((HsChompState -> HsChompState) -> m ())
-> (HsChompState -> HsChompState) -> m ()
forall a b. (a -> b) -> a -> b
$ \st :: HsChompState
st@HsChompState {Int
braceCt :: Int
braceCt :: HsChompState -> Int
braceCt} ->
      HsChompState
st {braceCt :: Int
braceCt = Int
braceCt Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n}
    setQuoteState :: QuoteState -> m ()
setQuoteState qs :: QuoteState
qs = (HsChompState -> HsChompState) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((HsChompState -> HsChompState) -> m ())
-> (HsChompState -> HsChompState) -> m ()
forall a b. (a -> b) -> a -> b
$ \st :: HsChompState
st -> HsChompState
st {quoteState :: QuoteState
quoteState = QuoteState
qs}
    setIdentifierCharState :: Char -> m ()
setIdentifierCharState c :: Char
c = (HsChompState -> HsChompState) -> m ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify ((HsChompState -> HsChompState) -> m ())
-> (HsChompState -> HsChompState) -> m ()
forall a b. (a -> b) -> a -> b
$ \st :: HsChompState
st ->
      HsChompState
st
        {prevCharWasIdentChar :: Bool
prevCharWasIdentChar = [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or [Char -> Bool
isLetter Char
c, Char -> Bool
isDigit Char
c, Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '_', Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== '\'']}

p_esc :: Parser StringPart
p_esc :: ParsecT String () Identity StringPart
p_esc = Char -> StringPart
Esc (Char -> StringPart)
-> ParsecT String () Identity Char
-> ParsecT String () Identity StringPart
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Char -> ParsecT String () Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
char '\\' ParsecT String () Identity Char
-> ParsecT String () Identity Char
-> ParsecT String () Identity Char
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT String () Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
anyChar)

p_lit :: Parser StringPart
p_lit :: ParsecT String () Identity StringPart
p_lit = (String -> StringPart)
-> ParsecT String () Identity String
-> ParsecT String () Identity StringPart
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> StringPart
Lit (ParsecT String () Identity String
 -> ParsecT String () Identity StringPart)
-> ParsecT String () Identity String
-> ParsecT String () Identity StringPart
forall a b. (a -> b) -> a -> b
$
  ParsecT String () Identity String
-> ParsecT String () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity String
-> ParsecT String () Identity String
forall u end.
ParsecT String u Identity end -> ParsecT String u Identity String
litCharTil (ParsecT String () Identity String
 -> ParsecT String () Identity String)
-> ParsecT String () Identity String
-> ParsecT String () Identity String
forall a b. (a -> b) -> a -> b
$ ParsecT String () Identity String
-> ParsecT String () Identity String
forall s u (m :: * -> *) a. ParsecT s u m a -> ParsecT s u m a
try (ParsecT String () Identity String
 -> ParsecT String () Identity String)
-> ParsecT String () Identity String
-> ParsecT String () Identity String
forall a b. (a -> b) -> a -> b
$ ParsecT String () Identity String
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead ParsecT String () Identity String
p_antiOpen ParsecT String () Identity String
-> ParsecT String () Identity String
-> ParsecT String () Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String () Identity String
-> ParsecT String () Identity String
forall s (m :: * -> *) t u a.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m a
lookAhead (String -> ParsecT String () Identity String
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m String
string "\\"))
    ParsecT String () Identity String
-> ParsecT String () Identity String
-> ParsecT String () Identity String
forall s u (m :: * -> *) a.
ParsecT s u m a -> ParsecT s u m a -> ParsecT s u m a
<|> ParsecT String () Identity () -> ParsecT String () Identity String
forall u end.
ParsecT String u Identity end -> ParsecT String u Identity String
litCharTil ParsecT String () Identity ()
forall s (m :: * -> *) t u.
(Stream s m t, Show t) =>
ParsecT s u m ()
eof
  where litCharTil :: ParsecT String u Identity end -> ParsecT String u Identity String
litCharTil = ParsecT String u Identity Char
-> ParsecT String u Identity end
-> ParsecT String u Identity String
forall s (m :: * -> *) t u a end.
Stream s m t =>
ParsecT s u m a -> ParsecT s u m end -> ParsecT s u m [a]
manyTill (ParsecT String u Identity Char
 -> ParsecT String u Identity end
 -> ParsecT String u Identity String)
-> ParsecT String u Identity Char
-> ParsecT String u Identity end
-> ParsecT String u Identity String
forall a b. (a -> b) -> a -> b
$ String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
noneOf ['\\']