-- | 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 = 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
    | forall {a} {a}. [Either a (a, TokenT)] -> Bool
interiorRef [Either String (Posn, TokenT)]
lexedQ = forall i. DFilter i -> CFilter i
dfilter (forall i. [Either String (Posn, TokenT)] -> DFilter i
parseXtract [Either String (Posn, TokenT)]
lexedQ)
    | Bool
otherwise          = forall i. DFilter i -> CFilter i
cfilter (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 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 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 = forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall a. HasCallStack => String -> a
error forall a. a -> a
id forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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' = forall a b. (a, b) -> a
fst forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t a. Parser t a -> [t] -> (Either String a, [t])
runParser (forall i.
((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
-> XParser (DFilter i)
aquery 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 = 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)]
_) -> 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) -> forall z a. z -> a -> Result z a
Success [Either String (Posn, TokenT)]
ts String
n
                [Either String (Posn, TokenT)]
ts -> 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 = 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)]
_) -> 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) -> forall z a. z -> a -> Result z a
Success [Either String (Posn, TokenT)]
ts Integer
n
                [Either String (Posn, TokenT)]
ts -> 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 = 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)]
_) -> 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
nforall a. Eq a => a -> a -> Bool
==String
s -> forall z a. z -> a -> Result z a
Success [Either String (Posn, TokenT)]
ts ()
                [Either String (Posn, TokenT)]
ts -> forall z a. z -> String -> Result z a
Failure [Either String (Posn, TokenT)]
ts (String
"expected symbol "forall a. [a] -> [a] -> [a]
++String
s) )

quote :: XParser ()
quote :: XParser ()
quote = 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
"("
     a
x <- XParser a
p
     String -> XParser ()
symbol String
")"
     forall (m :: * -> *) a. Monad m => a -> m a
return a
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 = forall (p :: * -> *) a. PolyParse p => [p a] -> p a
oneOf
    [ do String -> XParser ()
symbol String
"//"
         forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery [(CFilter i -> CFilter i) -> DFilter i -> DFilter i
lift forall i. CFilter i -> CFilter i
C.multi]
    , do String -> XParser ()
symbol String
"/"
         forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery [(CFilter i -> CFilter i) -> DFilter i -> DFilter i
lift forall a. a -> a
id]
    , do String -> XParser ()
symbol String
"./"
         forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery [(forall i. CFilter i -> DFilter i
local forall a. a -> [a]
C.keep forall i. DFilter i -> DFilter i -> DFilter i
D./>)]
    , do forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery [(forall i. CFilter i -> DFilter i
local forall a. a -> [a]
C.keep 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 [] = forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery [forall a. a -> a
id]
tquery (DFilter i -> DFilter i
qf:[DFilter i -> DFilter i]
cxt) = forall (p :: * -> *) a. PolyParse p => [p a] -> p a
oneOf
    [ do DFilter i
q <- forall a. XParser a -> XParser a
bracket (forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery (DFilter i -> DFilter i
qfforall a. a -> [a] -> [a]
:DFilter i -> DFilter i
qfforall a. a -> [a] -> [a]
:[DFilter i -> DFilter i]
cxt))
         forall i.
[DFilter i -> DFilter i] -> DFilter i -> XParser (DFilter i)
xquery [DFilter i -> DFilter i]
cxt DFilter i
q
    , do DFilter i
q <- forall i. XParser (DFilter i)
xtag
         forall i.
[DFilter i -> DFilter i] -> DFilter i -> XParser (DFilter i)
xquery [DFilter i -> DFilter i]
cxt (DFilter i -> DFilter i
qf ((forall i. [Content i] -> [Content i]
unescape forall b c a. (b -> c) -> (a -> b) -> a -> c
.)forall b c a. (b -> c) -> (a -> b) -> a -> c
.DFilter i
q))       -- glue inners texts together
    , do String -> XParser ()
symbol String
"-"
         forall (m :: * -> *) a. Monad m => a -> m a
return (DFilter i -> DFilter i
qf (forall i. CFilter i -> DFilter i
local forall i. CFilter i
C.txt))
    ]

xtag :: XParser (DFilter i)
xtag :: forall i. XParser (DFilter i)
xtag = forall (p :: * -> *) a. PolyParse p => [p a] -> p a
oneOf
    [ do String
s <- XParser String
string
         String -> XParser ()
symbol String
"*"
         forall (m :: * -> *) a. Monad m => a -> m a
return (forall i. CFilter i -> DFilter i
local (forall i. (String -> Bool) -> CFilter i
C.tagWith (String
s forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`)))
    , forall i. CFilter i -> DFilter i
local forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i. String -> CFilter i
C.tag forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> XParser String
string
    , do String -> XParser ()
symbol String
"*"
         String
s <- XParser String
string
         forall (m :: * -> *) a. Monad m => a -> m a
return (forall i. CFilter i -> DFilter i
local (forall i. (String -> Bool) -> CFilter i
C.tagWith ((forall a. [a] -> [a]
reverse String
s forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf`) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. [a] -> [a]
reverse)))
    , do String -> XParser ()
symbol String
"*"
         forall (m :: * -> *) a. Monad m => a -> m a
return (forall i. CFilter i -> DFilter i
local 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 = forall (p :: * -> *) a. PolyParse p => [p a] -> p a
oneOf
    [ do String -> XParser ()
symbol String
"/"
         do String -> XParser ()
symbol String
"@"
            String
attr <- XParser String
string
            forall (m :: * -> *) a. Monad m => a -> m a
return (forall i. String -> (String -> DFilter i) -> DFilter i -> DFilter i
D.iffind String
attr (forall i. CFilter i -> DFilter i
local forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall i. String -> CFilter i
C.literal) forall i. DFilter i
D.none forall i. DFilter i -> DFilter i -> DFilter i
`D.o` DFilter i
q1)
           forall t a. Parser t a -> Parser t a -> Parser t a
`onFail`
           forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery ((DFilter i
q1 forall i. DFilter i -> DFilter i -> DFilter i
D./>)forall a. a -> [a] -> [a]
:[DFilter i -> DFilter i]
cxt)
    , do String -> XParser ()
symbol String
"//"
         forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery ((\DFilter i
q2-> forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
liftLocal forall i. CFilter i -> CFilter i
C.multi DFilter i
q2
                            forall i. DFilter i -> DFilter i -> DFilter i
`D.o` forall i. CFilter i -> DFilter i
local forall i. CFilter i
C.children forall i. DFilter i -> DFilter i -> DFilter i
`D.o` DFilter i
q1)forall a. a -> [a] -> [a]
:[DFilter i -> DFilter i]
cxt)
    , do String -> XParser ()
symbol String
"+"
         DFilter i
q2 <- forall i. [DFilter i -> DFilter i] -> XParser (DFilter i)
tquery [DFilter i -> DFilter i]
cxt
         forall (m :: * -> *) a. Monad m => a -> m a
return (forall a b c. [a -> b -> [c]] -> a -> b -> [c]
D.cat [DFilter i
q1,DFilter i
q2])
    , do String -> XParser ()
symbol String
"["
         [[Content i] -> [Content i]]
is <- forall a. XParser [[a] -> [a]]
iindex   -- now extended to multiple indexes
         String -> XParser ()
symbol String
"]"
         forall i.
[DFilter i -> DFilter i] -> DFilter i -> XParser (DFilter i)
xquery [DFilter i -> DFilter i]
cxt (\Content i
xml-> forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. [a -> b] -> a -> [b]
pam [[Content i] -> [Content i]]
is forall b c a. (b -> c) -> (a -> b) -> a -> c
. DFilter i
q1 Content i
xml)
    , do String -> XParser ()
symbol String
"["
         DFilter i
p <- forall i. XParser (DFilter i)
tpredicate
         String -> XParser ()
symbol String
"]"
         forall i.
[DFilter i -> DFilter i] -> DFilter i -> XParser (DFilter i)
xquery [DFilter i -> DFilter i]
cxt (DFilter i
q1 forall i. DFilter i -> DFilter i -> DFilter i
`D.with` DFilter i
p)
    , forall (m :: * -> *) a. Monad m => a -> m a
return DFilter i
q1
    ]

tpredicate :: XParser (DFilter i)
tpredicate :: forall i. XParser (DFilter i)
tpredicate =
  do DFilter i
p <- forall i. XParser (DFilter i)
vpredicate
     DFilter i -> DFilter i
f <- forall i. XParser (DFilter i -> DFilter i)
upredicate
     forall (m :: * -> *) a. Monad m => a -> m a
return (DFilter i -> DFilter i
f DFilter i
p)

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

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

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

uattribute :: DFilter i -> XParser (DFilter i)
uattribute :: forall i. DFilter i -> XParser (DFilter i)
uattribute DFilter i
q = forall (p :: * -> *) a. PolyParse p => [p a] -> p a
oneOf
    [ do String -> XParser ()
symbol String
"/"
         String -> XParser ()
symbol String
"@"
         String
s <- XParser String
string
         forall i.
(DFilter i, DFilter i,
 (String -> DFilter i) -> DFilter i -> DFilter i)
-> XParser (DFilter i)
vattribute (DFilter i
q, forall i. CFilter i -> DFilter i
local (forall i. String -> CFilter i
C.attr String
s), forall i. String -> (String -> DFilter i) -> DFilter i -> DFilter i
D.iffind String
s)
    , do forall i.
(DFilter i, DFilter i,
 (String -> DFilter i) -> DFilter i -> DFilter i)
-> XParser (DFilter i)
vattribute (DFilter i
q, forall i. CFilter i -> DFilter i
local forall a. a -> [a]
C.keep,     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) = forall (p :: * -> *) a. PolyParse p => [p a] -> p a
oneOf
  [ do String -> String -> Bool
cmp <- XParser (String -> String -> Bool)
op
       XParser ()
quote
       String
s2 <- XParser String
string
       XParser ()
quote
       forall (m :: * -> *) a. Monad m => a -> m a
return ((String -> DFilter i) -> DFilter i -> DFilter i
iffn (\String
s1->if String -> String -> Bool
cmp String
s1 String
s2 then forall i. DFilter i
D.keep else forall i. DFilter i
D.none) forall i. DFilter i
D.none
               forall i. DFilter i -> DFilter i -> DFilter i
`D.o` DFilter i
q)
  , do String -> String -> Bool
cmp <- XParser (String -> String -> Bool)
op
       (DFilter i
q2,(String -> DFilter i) -> DFilter i -> DFilter i
iffn2) <- forall i.
XParser
  (DFilter i, (String -> DFilter i) -> DFilter i -> DFilter i)
wattribute -- q2 unused?  is this a mistake?
       forall (m :: * -> *) a. Monad m => a -> m a
return ((String -> DFilter i) -> DFilter i -> DFilter i
iffn (\String
s1-> (String -> DFilter i) -> DFilter i -> DFilter i
iffn2 (\String
s2-> if String -> String -> Bool
cmp String
s1 String
s2 then forall i. DFilter i
D.keep else forall i. DFilter i
D.none)
                                  forall i. DFilter i
D.none)
                     forall i. DFilter i
D.none forall i. DFilter i -> DFilter i -> DFilter i
`D.o` DFilter i
q)
  , do Integer -> Integer -> Bool
cmp <- XParser (Integer -> Integer -> Bool)
nop
       Integer
n <- XParser Integer
number
       forall (m :: * -> *) a. Monad m => a -> m a
return ((String -> DFilter i) -> DFilter i -> DFilter i
iffn (\String
s->if Integer -> Integer -> Bool
cmp (forall a. Read a => String -> a
read String
s) Integer
n then forall i. DFilter i
D.keep else forall i. DFilter i
D.none) forall i. DFilter i
D.none
               forall i. DFilter i -> DFilter i -> DFilter i
`D.o` DFilter i
q)
  , do Integer -> Integer -> Bool
cmp <- XParser (Integer -> Integer -> Bool)
nop
       (DFilter i
q2,(String -> DFilter i) -> DFilter i -> DFilter i
iffn2) <- forall i.
XParser
  (DFilter i, (String -> DFilter i) -> DFilter i -> DFilter i)
wattribute -- q2 unused?  is this a mistake?
       forall (m :: * -> *) a. Monad m => a -> m a
return ((String -> DFilter i) -> DFilter i -> DFilter i
iffn (\String
s1-> (String -> DFilter i) -> DFilter i -> DFilter i
iffn2 (\String
s2-> if Integer -> Integer -> Bool
cmp (forall a. Read a => String -> a
read String
s1) (forall a. Read a => String -> a
read String
s2) then forall i. DFilter i
D.keep
                                                                    else forall i. DFilter i
D.none)
                                  forall i. DFilter i
D.none)
                     forall i. DFilter i
D.none forall i. DFilter i -> DFilter i -> DFilter i
`D.o` DFilter i
q)
  , do forall (m :: * -> *) a. Monad m => a -> m a
return (DFilter i
a 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 = forall (p :: * -> *) a. PolyParse p => [p a] -> p a
oneOf
    [ do String -> XParser ()
symbol String
"@"
         String
s <- XParser String
string
         forall (m :: * -> *) a. Monad m => a -> m a
return (forall i. DFilter i
D.keep, forall i. String -> (String -> DFilter i) -> DFilter i -> DFilter i
D.iffind String
s)
    , do DFilter i
q <- forall i.
((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
-> XParser (DFilter i)
aquery forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
liftGlobal
         String -> XParser ()
symbol String
"/"
         String -> XParser ()
symbol String
"@"
         String
s <- XParser String
string
         forall (m :: * -> *) a. Monad m => a -> m a
return (DFilter i
q, forall i. String -> (String -> DFilter i) -> DFilter i -> DFilter i
D.iffind String
s)
    , do DFilter i
q <- forall i.
((CFilter i -> CFilter i) -> DFilter i -> DFilter i)
-> XParser (DFilter i)
aquery forall i. (CFilter i -> CFilter i) -> DFilter i -> DFilter i
liftGlobal
         forall (m :: * -> *) a. Monad m => a -> m a
return (DFilter i
q, forall i. (String -> DFilter i) -> DFilter i -> DFilter i
D.ifTxt)
    ]


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

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

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

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

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


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

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