    -- | A parser for the Xtract command-language.  (The string input is
    --   tokenised internally by the lexer 'lexXtract'.)
    --   See <http://www.haskell.org/HaXml/Xtract.html> for the grammar that
    --   is accepted.

    --   Because the original Xtract grammar was left-recursive, we have
    --   transformed it into a non-left-recursive form.
    module Text.XML.HaXml.Xtract.Parse (parseXtract,xtract) where

    import Text.ParserCombinators.Poly hiding (bracket)
    import Text.XML.HaXml.Xtract.Lex
    import Text.XML.HaXml.Xtract.Combinators as D
    import Text.XML.HaXml.Combinators as C
    import Text.XML.HaXml.Types (Content)
    import Data.List(isPrefixOf)
    import Text.XML.HaXml.Escape (xmlUnEscapeContent,stdXmlEscaper)

    -- output transformer - to ensure that text/references are glued together
    unescape :: [Content i] -> [Content i]
    unescape :: forall i. [Content i] -> [Content i]
    unescape = XmlEscaper -> [Content i] -> [Content i]
    forall i. XmlEscaper -> [Content i] -> [Content i]
    xmlUnEscapeContent XmlEscaper
    stdXmlEscaper

    -- | To convert an Xtract query into an ordinary HaXml combinator expression.
    --   First arg is a tag-transformation function (e.g. map toLower) applied
    ---  before matching.  Second arg is the query string.
    xtract :: (String->String) -> String -> CFilter i
    xtract :: forall i. (String -> String) -> String -> CFilter i
    xtract String -> String
    f String
    query
        | [Either String (Posn, TokenT)] -> Bool
    forall {a} {a}. [Either a (a, TokenT)] -> Bool
    interiorRef [Either String (Posn, TokenT)]
    lexedQ = DFilter i -> CFilter i
    forall i. DFilter i -> CFilter i
    dfilter ([Either String (Posn, TokenT)] -> DFilter i
    forall i. [Either String (Posn, TokenT)] -> DFilter i
    parseXtract [Either String (Posn, TokenT)]
    lexedQ)
        | Bool
    otherwise          = DFilter i -> CFilter i
    forall i. DFilter i -> CFilter i
    cfilter ([Either String (Posn, TokenT)] -> DFilter i
    forall i. [Either String (Posn, TokenT)] -> DFilter i
    parseXtract [Either String (Posn, TokenT)]
    lexedQ)
      where
        lexedQ :: [Either String (Posn, TokenT)]
    lexedQ = (String -> String) -> String -> [Either String (Posn, TokenT)]
    lexXtract String -> String
    f String
    query
        -- test whether query has interior reference to doc root
        interiorRef :: [Either a (a, TokenT)] -> Bool
    interiorRef (Right (a
    _,Symbol String
    s): Right (a
    _,Symbol String
    "//"): [Either a (a, TokenT)]
    _)
                                              | String
    s String -> [String] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [String]
    predicateIntro = Bool
    True
        interiorRef (Right (a
    _,Symbol String
    s): Right (a
    _,Symbol String
    "/"): [Either a (a, TokenT)]
    _)
                                              | String
    s String -> [String] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [String]
    predicateIntro = Bool
    True
        interiorRef (Either a (a, TokenT)
    _ : [Either a (a, TokenT)]
    rest) = [Either a (a, TokenT)] -> Bool
    interiorRef [Either a (a, TokenT)]
    rest
        interiorRef [] = Bool
    False
        predicateIntro :: [String]
    predicateIntro = [ String
    "[", String
    "("
                         ,  String
    "&",   String
    "|",  String
    "~"
                         ,  String
    "=",  String
    "!=",  String
    "<",  String
    "<=",  String
    ">",  String
    ">="
                         , String
    ".=.",String
    ".!=.",String
    ".<.",String
    ".<=.",String
    ".>.",String
    ".>=." ]

    -- | The cool thing is that the Xtract command parser directly builds
    --   a higher-order 'DFilter' (see "Text.XML.HaXml.Xtract.Combinators")
    --   which can be applied to an XML document without further ado.
    --   (@parseXtract@ halts the program if a parse error is found.)
    parseXtract :: [Token] -> DFilter i
    parseXtract :: forall i. [Either String (Posn, TokenT)] -> DFilter i
    parseXtract = (String -> DFilter i)
    -> (DFilter i -> DFilter i)
    -> Either String (DFilter i)
    -> DFilter i
    forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
    either String -> DFilter i
    forall a. HasCallStack => String -> a
    error DFilter i -> DFilter i
    forall a. a -> a
    id (Either String (DFilter i) -> DFilter i)
    -> ([Either String (Posn, TokenT)] -> Either String (DFilter i))
    -> [Either String (Posn, TokenT)]
    -> DFilter i
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Either String (Posn, TokenT)] -> Either String (DFilter i)
    forall i.
    [Either String (Posn, TokenT)] -> Either String (DFilter i)
    parseXtract'

    -- | @parseXtract'@ returns error messages through the Either type.
    parseXtract' :: [Token] -> Either String (DFilter i)
    parseXtract' :: forall i.
    [Either String (Posn, TokenT)] -> Either String (DFilter i)
    parseXtract' = (Either String (DFilter i), [Either String (Posn, TokenT)])
    -> Either String (DFilter i)
    forall a b. (a, b) -> a
    fst ((Either String (DFilter i), [Either String (Posn, TokenT)])
     -> Either String (DFilter i))
    -> ([Either String (Posn, TokenT)]
        -> (Either String (DFilter i), [Either String (Posn, TokenT)]))
    -> [Either String (Posn, TokenT)]
    -> Either String (DFilter i)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Parser (Either String (Posn, TokenT)) (DFilter i)
    -> [Either String (Posn, TokenT)]
    -> (Either String (DFilter i), [Either String (Posn, TokenT)])
    forall t a. Parser t a -> [t] -> (Either String a, [t])
    runParser (((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i.
    ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    aquery (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    liftLocal)

    ---- Auxiliary Parsing Functions ----
    type XParser a = Parser (Either String (Posn,TokenT)) a

    string :: XParser String
    string :: XParser String
    string = ([Either String (Posn, TokenT)]
     -> Result [Either String (Posn, TokenT)] String)
    -> XParser String
    forall t a. ([t] -> Result [t] a) -> Parser t a
    P (\[Either String (Posn, TokenT)]
    inp -> case [Either String (Posn, TokenT)]
    inp of
                    (Left String
    err: [Either String (Posn, TokenT)]
    _) -> [Either String (Posn, TokenT)]
    -> String -> Result [Either String (Posn, TokenT)] String
    forall z a. z -> String -> Result z a
    Failure [Either String (Posn, TokenT)]
    inp String
    err
                    (Right (Posn
    _,TokString String
    n):[Either String (Posn, TokenT)]
    ts) -> [Either String (Posn, TokenT)]
    -> String -> Result [Either String (Posn, TokenT)] String
    forall z a. z -> a -> Result z a
    Success [Either String (Posn, TokenT)]
    ts String
    n
                    [Either String (Posn, TokenT)]
    ts -> [Either String (Posn, TokenT)]
    -> String -> Result [Either String (Posn, TokenT)] String
    forall z a. z -> String -> Result z a
    Failure [Either String (Posn, TokenT)]
    ts String
    "expected a string" )
    number :: XParser Integer
    number :: XParser Integer
    number = ([Either String (Posn, TokenT)]
     -> Result [Either String (Posn, TokenT)] Integer)
    -> XParser Integer
    forall t a. ([t] -> Result [t] a) -> Parser t a
    P (\[Either String (Posn, TokenT)]
    inp -> case [Either String (Posn, TokenT)]
    inp of
                    (Left String
    err: [Either String (Posn, TokenT)]
    _) -> [Either String (Posn, TokenT)]
    -> String -> Result [Either String (Posn, TokenT)] Integer
    forall z a. z -> String -> Result z a
    Failure [Either String (Posn, TokenT)]
    inp String
    err
                    (Right (Posn
    _,TokNum Integer
    n):[Either String (Posn, TokenT)]
    ts) -> [Either String (Posn, TokenT)]
    -> Integer -> Result [Either String (Posn, TokenT)] Integer
    forall z a. z -> a -> Result z a
    Success [Either String (Posn, TokenT)]
    ts Integer
    n
                    [Either String (Posn, TokenT)]
    ts -> [Either String (Posn, TokenT)]
    -> String -> Result [Either String (Posn, TokenT)] Integer
    forall z a. z -> String -> Result z a
    Failure [Either String (Posn, TokenT)]
    ts String
    "expected a number" )
    symbol :: String -> XParser ()
    symbol :: String -> XParser ()
    symbol String
    s = ([Either String (Posn, TokenT)]
     -> Result [Either String (Posn, TokenT)] ())
    -> XParser ()
    forall t a. ([t] -> Result [t] a) -> Parser t a
    P (\[Either String (Posn, TokenT)]
    inp -> case [Either String (Posn, TokenT)]
    inp of
                    (Left String
    err: [Either String (Posn, TokenT)]
    _) -> [Either String (Posn, TokenT)]
    -> String -> Result [Either String (Posn, TokenT)] ()
    forall z a. z -> String -> Result z a
    Failure [Either String (Posn, TokenT)]
    inp String
    err
                    (Right (Posn
    _, Symbol String
    n):[Either String (Posn, TokenT)]
    ts) | String
    nString -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    ==String
    s -> [Either String (Posn, TokenT)]
    -> () -> Result [Either String (Posn, TokenT)] ()
    forall z a. z -> a -> Result z a
    Success [Either String (Posn, TokenT)]
    ts ()
                    [Either String (Posn, TokenT)]
    ts -> [Either String (Posn, TokenT)]
    -> String -> Result [Either String (Posn, TokenT)] ()
    forall z a. z -> String -> Result z a
    Failure [Either String (Posn, TokenT)]
    ts (String
    "expected symbol "String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++String
    s) )

    quote :: XParser ()
    quote :: XParser ()
    quote = [XParser ()] -> XParser ()
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf [ String -> XParser ()
    symbol String
    "'",  String -> XParser ()
    symbol String
    "\"" ]

    pam :: [a->b] -> a -> [b]
    pam :: forall a b. [a -> b] -> a -> [b]
    pam [a -> b]
    fs a
    x = [ a -> b
    f a
    x | a -> b
    f <- [a -> b]
    fs ]

    {--- original Xtract grammar ----
          query     = string                        tagname
                    | string *                      tagname prefix
                    | * string                      tagname suffix
                    | *                             any element
                    | -                             chardata
                    | ( query )
                    | query / query                 parent/child relationship
                    | query // query                deep inside
                    | query + query                 union of queries
                    | query [predicate]
                    | query [positions]

          predicate = quattr                        has attribute
                    | quattr op ' string '          attribute has value
                    | quattr op " string "          attribute has value
                    | quattr op  quattr             attribute value comparison (lexical)
                    | quattr nop integer            attribute has value (numerical)
                    | quattr nop quattr             attribute value comparison (numerical)
                    | ( predicate )                 bracketting
                    | predicate & predicate         logical and
                    | predicate | predicate         logical or
                    | ~ predicate                   logical not

          attribute = @ string                      has attribute
                    | query / @ string              child has attribute
                    | -                             has textual content
                    | query / -                     child has textual content

          quattr    = query
                    | attribute

          op        =  =                            equal to
                    |  !=                           not equal to
                    |  <                            less than
                    |  <=                           less than or equal to
                    |  >                            greater than
                    |  >=                           greater than or equal to

          nop       =  .=.                          equal to
                    |  .!=.                         not equal to
                    |  .<.                          less than
                    |  .<=.                         less than or equal to
                    |  .>.                          greater than
                    |  .>=.                         greater than or equal to

          positions = position {, positions}        multiple positions
                    | position - position           ranges

          position  = integer                       numbering is from 0 upwards
                    | $                             last

    ---- transformed grammar (removing left recursion)
          aquery = ./ tquery        -- current context
                 | tquery           -- also current context
                 | / tquery         -- root context
                 | // tquery        -- deep context from root

          tquery = ( tquery ) xquery
                 | tag xquery
                 | -                -- fixes original grammar ("-/*" is incorrect)

          tag    = string *
                 | string
                 | * string
                 | *

          xquery = / tquery
                 | // tquery
                 | / @ string       -- new: print attribute value
                 | + tquery
                 | [ tpredicate ] xquery
                 | [ positions ] xquery
                 | lambda

          tpredicate = vpredicate upredicate
          upredicate = & tpredicate
                     | | tpredicate
                     | lambda
          vpredicate = ( tpredicate )
                     | ~ tpredicate
                     | tattribute

          tattribute = aquery uattribute
                     | @ string vattribute
          uattribute = / @ string vattribute
                     | vattribute
          vattribute = op wattribute
                     | op ' string '
                     | nop wattribute
                     | nop integer
                     | lambda
          wattribute = @ string
                     | aquery / @ string
                     | aquery

          positions  = simplepos commapos
          simplepos  = integer range
                     | $
          range      = - integer
                     | - $
                     | lambda
          commapos   = , simplepos commapos
                     | lambda

          op         =  =
                     |  !=
                     |  <
                     |  <=
                     |  >
                     |  >=

          nop        =  .=.
                     |  .!=.
                     |  .<.
                     |  .<=.
                     |  .>.
                     |  .>=.
    -}

    bracket :: XParser a -> XParser a
    bracket :: forall a. XParser a -> XParser a
    bracket XParser a
    p =
      do String -> XParser ()
    symbol String
    "("
         x <- XParser a
    p
         symbol ")"
         return x

    ---- Xtract parsers ----

    -- aquery chooses to search from the root, or only in local context
    aquery ::  ((CFilter i->CFilter i) -> (DFilter i->DFilter i))
               -> XParser (DFilter i)
    aquery :: forall i.
    ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    aquery (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    lift = [Parser (Either String (Posn, TokenT)) (DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    "//"
             [DFilter i -> DFilter i]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery [(CFilter i -> CFilter i) -> DFilter i -> DFilter i
    lift CFilter i -> CFilter i
    forall i. CFilter i -> CFilter i
    C.multi]
        , do String -> XParser ()
    symbol String
    "/"
             [DFilter i -> DFilter i]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery [(CFilter i -> CFilter i) -> DFilter i -> DFilter i
    lift CFilter i -> CFilter i
    forall a. a -> a
    id]
        , do String -> XParser ()
    symbol String
    "./"
             [DFilter i -> DFilter i]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery [(CFilter i -> DFilter i
    forall i. CFilter i -> DFilter i
    local CFilter i
    forall a. a -> [a]
    C.keep DFilter i -> DFilter i -> DFilter i
    forall i. DFilter i -> DFilter i -> DFilter i
    D./>)]
        , do [DFilter i -> DFilter i]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery [(CFilter i -> DFilter i
    forall i. CFilter i -> DFilter i
    local CFilter i
    forall a. a -> [a]
    C.keep DFilter i -> DFilter i -> DFilter i
    forall i. DFilter i -> DFilter i -> DFilter i
    D./>)]
        ]

    tquery :: [DFilter i->DFilter i] -> XParser (DFilter i)
    tquery :: forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery [] = [DFilter i -> DFilter i] -> XParser (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery [DFilter i -> DFilter i
    forall a. a -> a
    id]
    tquery (DFilter i -> DFilter i
    qf:[DFilter i -> DFilter i]
    cxt) = [XParser (DFilter i)] -> XParser (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do q <- XParser (DFilter i) -> XParser (DFilter i)
    forall a. XParser a -> XParser a
    bracket ([DFilter i -> DFilter i] -> XParser (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery (DFilter i -> DFilter i
    qf(DFilter i -> DFilter i)
    -> [DFilter i -> DFilter i] -> [DFilter i -> DFilter i]
    forall a. a -> [a] -> [a]
    :DFilter i -> DFilter i
    qf(DFilter i -> DFilter i)
    -> [DFilter i -> DFilter i] -> [DFilter i -> DFilter i]
    forall a. a -> [a] -> [a]
    :[DFilter i -> DFilter i]
    cxt))
             xquery cxt q
        , do q <- XParser (DFilter i)
    forall i. XParser (DFilter i)
    xtag
             xquery cxt (qf ((unescape .).q))       -- glue inners texts together
        , do String -> XParser ()
    symbol String
    "-"
             DFilter i -> XParser (DFilter i)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DFilter i -> DFilter i
    qf ((Content i -> [Content i]) -> DFilter i
    forall i. CFilter i -> DFilter i
    local Content i -> [Content i]
    forall i. CFilter i
    C.txt))
        ]

    xtag :: XParser (DFilter i)
    xtag :: forall i. XParser (DFilter i)
    xtag = [Parser (Either String (Posn, TokenT)) (DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do s <- XParser String
    string
             symbol "*"
             return (local (C.tagWith (s `isPrefixOf`)))
        , CFilter i -> DFilter i
    forall i. CFilter i -> DFilter i
    local (CFilter i -> DFilter i)
    -> (String -> CFilter i) -> String -> DFilter i
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> CFilter i
    forall i. String -> CFilter i
    C.tag (String -> DFilter i)
    -> XParser String
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> XParser String
    string
        , do String -> XParser ()
    symbol String
    "*"
             s <- XParser String
    string
             return (local (C.tagWith ((reverse s `isPrefixOf`) . reverse)))
        , do String -> XParser ()
    symbol String
    "*"
             DFilter i -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (CFilter i -> DFilter i
    forall i. CFilter i -> DFilter i
    local CFilter i
    forall i. CFilter i
    C.elm)
        ]

    xquery :: [DFilter i->DFilter i] -> DFilter i -> XParser (DFilter i)
    xquery :: forall i.
    [DFilter i -> DFilter i] -> DFilter i -> XParser (DFilter i)
    xquery [DFilter i -> DFilter i]
    cxt DFilter i
    q1 = [Parser (Either String (Posn, TokenT)) (DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    "/"
             do String -> XParser ()
    symbol String
    "@"
                attr <- XParser String
    string
                return (D.iffind attr (local . C.literal) D.none `D.o` q1)
               Parser (Either String (Posn, TokenT)) (DFilter i)
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall t a. Parser t a -> Parser t a -> Parser t a
    `onFail`
               [DFilter i -> DFilter i]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery ((DFilter i
    q1 DFilter i -> DFilter i -> DFilter i
    forall i. DFilter i -> DFilter i -> DFilter i
    D./>)(DFilter i -> DFilter i)
    -> [DFilter i -> DFilter i] -> [DFilter i -> DFilter i]
    forall a. a -> [a] -> [a]
    :[DFilter i -> DFilter i]
    cxt)
        , do String -> XParser ()
    symbol String
    "//"
             [DFilter i -> DFilter i]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery ((\DFilter i
    q2-> (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    liftLocal CFilter i -> CFilter i
    forall i. CFilter i -> CFilter i
    C.multi DFilter i
    q2
                                DFilter i -> DFilter i -> DFilter i
    forall i. DFilter i -> DFilter i -> DFilter i
    `D.o` CFilter i -> DFilter i
    forall i. CFilter i -> DFilter i
    local CFilter i
    forall i. CFilter i
    C.children DFilter i -> DFilter i -> DFilter i
    forall i. DFilter i -> DFilter i -> DFilter i
    `D.o` DFilter i
    q1)(DFilter i -> DFilter i)
    -> [DFilter i -> DFilter i] -> [DFilter i -> DFilter i]
    forall a. a -> [a] -> [a]
    :[DFilter i -> DFilter i]
    cxt)
        , do String -> XParser ()
    symbol String
    "+"
             q2 <- [DFilter i -> DFilter i]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
    tquery [DFilter i -> DFilter i]
    cxt
             return (D.cat [q1,q2])
        , do String -> XParser ()
    symbol String
    "["
             is <- XParser [[Content i] -> [Content i]]
    forall a. XParser [[a] -> [a]]
    iindex   -- now extended to multiple indexes
             symbol "]"
             xquery cxt (\Content i
    xml-> [[Content i]] -> [Content i]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat ([[Content i]] -> [Content i])
    -> (Content i -> [[Content i]]) -> CFilter i
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [[Content i] -> [Content i]] -> [Content i] -> [[Content i]]
    forall a b. [a -> b] -> a -> [b]
    pam [[Content i] -> [Content i]]
    is ([Content i] -> [[Content i]])
    -> CFilter i -> Content i -> [[Content i]]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . DFilter i
    q1 Content i
    xml)
        , do String -> XParser ()
    symbol String
    "["
             p <- Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. XParser (DFilter i)
    tpredicate
             symbol "]"
             xquery cxt (q1 `D.with` p)
        , DFilter i -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return DFilter i
    q1
        ]

    tpredicate :: XParser (DFilter i)
    tpredicate :: forall i. XParser (DFilter i)
    tpredicate =
      do p <- XParser (DFilter i)
    forall i. XParser (DFilter i)
    vpredicate
         f <- upredicate
         return (f p)

    upredicate :: XParser (DFilter i->DFilter i)
    upredicate :: forall i. XParser (DFilter i -> DFilter i)
    upredicate = [Parser (Either String (Posn, TokenT)) (DFilter i -> DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i -> DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    "&"
             p2 <- XParser (DFilter i)
    forall i. XParser (DFilter i)
    tpredicate
             return (`D.o` p2)
        , do String -> XParser ()
    symbol String
    "|"
             p2 <- XParser (DFilter i)
    forall i. XParser (DFilter i)
    tpredicate
             return (D.|>| p2)
        , (DFilter i -> DFilter i)
    -> Parser (Either String (Posn, TokenT)) (DFilter i -> DFilter i)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return DFilter i -> DFilter i
    forall a. a -> a
    id
        ]

    vpredicate :: XParser (DFilter i)
    vpredicate :: forall i. XParser (DFilter i)
    vpredicate = [Parser (Either String (Posn, TokenT)) (DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do Parser (Either String (Posn, TokenT)) (DFilter i)
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall a. XParser a -> XParser a
    bracket Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. XParser (DFilter i)
    tpredicate
        , do String -> XParser ()
    symbol String
    "~"
             p <- Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i. XParser (DFilter i)
    tpredicate
             return (local C.keep `D.without` p)
        , do tattribute
        ]

    tattribute :: XParser (DFilter i)
    tattribute :: forall i. XParser (DFilter i)
    tattribute = [Parser (Either String (Posn, TokenT)) (DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do q <- ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i.
    ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    aquery (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    liftGlobal
             uattribute q
        , do String -> XParser ()
    symbol String
    "@"
             s <- XParser String
    string
             vattribute (local C.keep, local (C.attr s), D.iffind s)
        ]

    uattribute :: DFilter i -> XParser (DFilter i)
    uattribute :: forall i. DFilter i -> XParser (DFilter i)
    uattribute DFilter i
    q = [Parser (Either String (Posn, TokenT)) (DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    "/"
             String -> XParser ()
    symbol String
    "@"
             s <- XParser String
    string
             vattribute (q, local (C.attr s), D.iffind s)
        , do (DFilter i, DFilter i,
     (String -> DFilter i) -> DFilter i -> DFilter i)
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall i.
    (DFilter i, DFilter i,
     (String -> DFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    vattribute (DFilter i
    q, CFilter i -> DFilter i
    forall i. CFilter i -> DFilter i
    local CFilter i
    forall a. a -> [a]
    C.keep,     (String -> DFilter i) -> DFilter i -> DFilter i
    forall i. (String -> DFilter i) -> DFilter i -> DFilter i
    D.ifTxt)
        ]

    vattribute :: (DFilter i, DFilter i, (String->DFilter i)->DFilter i->DFilter i)
                  -> XParser (DFilter i)
    vattribute :: forall i.
    (DFilter i, DFilter i,
     (String -> DFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    vattribute (DFilter i
    q,DFilter i
    a,(String -> DFilter i) -> DFilter i -> DFilter i
    iffn) = [Parser (Either String (Posn, TokenT)) (DFilter i)]
    -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
      [ do cmp <- XParser (String -> String -> Bool)
    op
           quote
           s2 <- string
           quote
           return (iffn (\String
    s1->if String -> String -> Bool
    cmp String
    s1 String
    s2 then DFilter i
    forall i. DFilter i
    D.keep else DFilter i
    forall i. DFilter i
    D.none) D.none
                   `D.o` q)
      , do cmp <- XParser (String -> String -> Bool)
    op
           (q2,iffn2) <- wattribute -- q2 unused?  is this a mistake?
           return (iffn (\String
    s1-> (String -> DFilter i) -> DFilter i -> DFilter i
    iffn2 (\String
    s2-> if String -> String -> Bool
    cmp String
    s1 String
    s2 then DFilter i
    forall i. DFilter i
    D.keep else DFilter i
    forall i. DFilter i
    D.none)
                                      DFilter i
    forall i. DFilter i
    D.none)
                         D.none `D.o` q)
      , do cmp <- XParser (Integer -> Integer -> Bool)
    nop
           n <- number
           return (iffn (\String
    s->if Integer -> Integer -> Bool
    cmp (String -> Integer
    forall a. Read a => String -> a
    read String
    s) Integer
    n then DFilter i
    forall i. DFilter i
    D.keep else DFilter i
    forall i. DFilter i
    D.none) D.none
                   `D.o` q)
      , do cmp <- XParser (Integer -> Integer -> Bool)
    nop
           (q2,iffn2) <- wattribute -- q2 unused?  is this a mistake?
           return (iffn (\String
    s1-> (String -> DFilter i) -> DFilter i -> DFilter i
    iffn2 (\String
    s2-> if Integer -> Integer -> Bool
    cmp (String -> Integer
    forall a. Read a => String -> a
    read String
    s1) (String -> Integer
    forall a. Read a => String -> a
    read String
    s2) then DFilter i
    forall i. DFilter i
    D.keep
                                                                        else DFilter i
    forall i. DFilter i
    D.none)
                                      DFilter i
    forall i. DFilter i
    D.none)
                         D.none `D.o` q)
      , do DFilter i -> Parser (Either String (Posn, TokenT)) (DFilter i)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (DFilter i
    a DFilter i -> DFilter i -> DFilter i
    forall i. DFilter i -> DFilter i -> DFilter i
    `D.o` DFilter i
    q)
      ]

    wattribute :: XParser (DFilter i, (String->DFilter i)->DFilter i->DFilter i)
    wattribute :: forall i.
    XParser
      (DFilter i, (String -> DFilter i) -> DFilter i -> DFilter i)
    wattribute = [Parser
       (Either String (Posn, TokenT))
       (DFilter i, (String -> DFilter i) -> DFilter i -> DFilter i)]
    -> Parser
         (Either String (Posn, TokenT))
         (DFilter i, (String -> DFilter i) -> DFilter i -> DFilter i)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    "@"
             s <- XParser String
    string
             return (D.keep, D.iffind s)
        , do q <- ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    forall i.
    ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    aquery (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    liftGlobal
             symbol "/"
             symbol "@"
             s <- string
             return (q, D.iffind s)
        , do q <- ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    forall i.
    ((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
    -> XParser (DFilter i)
    aquery (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
    liftGlobal
             return (q, D.ifTxt)
        ]

    iindex :: XParser [[a]->[a]]
    iindex :: forall a. XParser [[a] -> [a]]
    iindex =
        do i <- XParser ([a] -> [a])
    forall a. XParser ([a] -> [a])
    simpleindex
           is <- idxcomma
           return (i:is)

    simpleindex :: XParser ([a]->[a])
    simpleindex :: forall a. XParser ([a] -> [a])
    simpleindex = [Parser (Either String (Posn, TokenT)) ([a] -> [a])]
    -> Parser (Either String (Posn, TokenT)) ([a] -> [a])
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do n <- XParser Integer
    number
             rrange n
        , do String -> XParser ()
    symbol String
    "$"
             ([a] -> [a]) -> Parser (Either String (Posn, TokenT)) ([a] -> [a])
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (a -> [a]
    forall a. a -> [a]
    C.keep (a -> [a]) -> ([a] -> a) -> [a] -> [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [a] -> a
    forall a. HasCallStack => [a] -> a
    last)
        ]

    rrange, numberdollar :: Integer -> XParser ([a]->[a])
    rrange :: forall a. Integer -> XParser ([a] -> [a])
    rrange Integer
    n1 = [Parser (Either String (Posn, TokenT)) ([a] -> [a])]
    -> Parser (Either String (Posn, TokenT)) ([a] -> [a])
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    "-"
             Integer -> Parser (Either String (Posn, TokenT)) ([a] -> [a])
    forall a. Integer -> XParser ([a] -> [a])
    numberdollar Integer
    n1
        , ([a] -> [a]) -> Parser (Either String (Posn, TokenT)) ([a] -> [a])
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> [a] -> [a]
    forall a. Int -> [a] -> [a]
    take Int
    1 ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> [a] -> [a]
    forall a. Int -> [a] -> [a]
    drop (Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    n1))
        ]

    numberdollar :: forall a. Integer -> XParser ([a] -> [a])
    numberdollar Integer
    n1 = [Parser (Either String (Posn, TokenT)) ([a] -> [a])]
    -> Parser (Either String (Posn, TokenT)) ([a] -> [a])
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do n2 <- XParser Integer
    number
             return (take (fromInteger (1+n2-n1)) . drop (fromInteger n1))
        , do String -> XParser ()
    symbol String
    "$"
             ([a] -> [a]) -> Parser (Either String (Posn, TokenT)) ([a] -> [a])
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Int -> [a] -> [a]
    forall a. Int -> [a] -> [a]
    drop (Integer -> Int
    forall a. Num a => Integer -> a
    fromInteger Integer
    n1))
        ]

    idxcomma :: XParser [[a]->[a]]
    idxcomma :: forall a. XParser [[a] -> [a]]
    idxcomma = [Parser (Either String (Posn, TokenT)) [[a] -> [a]]]
    -> Parser (Either String (Posn, TokenT)) [[a] -> [a]]
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    ","
             r <- XParser ([a] -> [a])
    forall a. XParser ([a] -> [a])
    simpleindex
             rs <- idxcomma
             return (r:rs)
        , [[a] -> [a]] -> Parser (Either String (Posn, TokenT)) [[a] -> [a]]
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return []
        ]

    op :: XParser (String->String->Bool)
    op :: XParser (String -> String -> Bool)
    op = [XParser (String -> String -> Bool)]
    -> XParser (String -> String -> Bool)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    "=";  (String -> String -> Bool) -> XParser (String -> String -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
        , do String -> XParser ()
    symbol String
    "!="; (String -> String -> Bool) -> XParser (String -> String -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    (/=)
        , do String -> XParser ()
    symbol String
    "<";  (String -> String -> Bool) -> XParser (String -> String -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String -> String -> Bool
    forall a. Ord a => a -> a -> Bool
    (<)
        , do String -> XParser ()
    symbol String
    "<="; (String -> String -> Bool) -> XParser (String -> String -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String -> String -> Bool
    forall a. Ord a => a -> a -> Bool
    (<=)
        , do String -> XParser ()
    symbol String
    ">";  (String -> String -> Bool) -> XParser (String -> String -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String -> String -> Bool
    forall a. Ord a => a -> a -> Bool
    (>)
        , do String -> XParser ()
    symbol String
    ">="; (String -> String -> Bool) -> XParser (String -> String -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return String -> String -> Bool
    forall a. Ord a => a -> a -> Bool
    (>=)
        ]

    nop :: XParser (Integer->Integer->Bool)
    nop :: XParser (Integer -> Integer -> Bool)
    nop = [XParser (Integer -> Integer -> Bool)]
    -> XParser (Integer -> Integer -> Bool)
    forall (p :: * -> *) a. PolyParse p => [p a] -> p a
    oneOf
        [ do String -> XParser ()
    symbol String
    ".=.";  (Integer -> Integer -> Bool)
    -> XParser (Integer -> Integer -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
        , do String -> XParser ()
    symbol String
    ".!=."; (Integer -> Integer -> Bool)
    -> XParser (Integer -> Integer -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    (/=)
        , do String -> XParser ()
    symbol String
    ".<.";  (Integer -> Integer -> Bool)
    -> XParser (Integer -> Integer -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    (<)
        , do String -> XParser ()
    symbol String
    ".<=."; (Integer -> Integer -> Bool)
    -> XParser (Integer -> Integer -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    (<=)
        , do String -> XParser ()
    symbol String
    ".>.";  (Integer -> Integer -> Bool)
    -> XParser (Integer -> Integer -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    (>)
        , do String -> XParser ()
    symbol String
    ".>=."; (Integer -> Integer -> Bool)
    -> XParser (Integer -> Integer -> Bool)
    forall a. a -> Parser (Either String (Posn, TokenT)) a
    forall (m :: * -> *) a. Monad m => a -> m a
    return Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    (>=)
        ]