1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE FlexibleInstances #-}
3 {-# LANGUAGE OverloadedStrings #-}
4 {-# LANGUAGE ScopedTypeVariables #-}
5 {-# LANGUAGE TypeFamilies #-}
6 {-# LANGUAGE ViewPatterns #-}
7 {-# OPTIONS_GHC -fno-warn-orphans #-}
8 module Language.Symantic.RNC.Validate where
10 import Control.Applicative (Applicative(..))
12 import Data.Either (Either(..))
13 import Data.Eq (Eq(..))
14 import Data.Foldable (Foldable(..), all)
15 import Data.Function (($), const, id)
16 import Data.List.NonEmpty (NonEmpty(..))
17 import Data.Maybe (Maybe(..))
18 import Data.Monoid (Monoid(..))
19 import Data.Ord (Ord(..))
20 import Data.Semigroup (Semigroup(..))
21 import qualified Data.Char as Char
22 import qualified Data.Sequence as Seq
23 import qualified Data.Set as Set
24 import qualified Data.Text.Lazy as TL
25 import qualified Text.Megaparsec as P
26 import qualified Text.Megaparsec.Perm as P
28 import Language.Symantic.XML (XMLs)
29 import qualified Language.Symantic.XML as XML
30 import qualified Language.Symantic.RNC.Sym as RNC
32 validateXML :: Ord e => P.Parsec e XMLs a -> XMLs -> Either (P.ParseError (P.Token XMLs) e) a
33 validateXML p = XML.runParser p (P.initialPos "":|[])
35 type instance RNC.Perm (P.ParsecT e XMLs m) = P.PermParser XMLs (P.ParsecT e XMLs m)
36 instance Ord e => RNC.Sym_Interleaved (P.ParsecT e XMLs m) where
37 interleaved = P.makePermParser
42 f <$*> a = f P.<$?> ([],P.some a)
43 f <|*> a = f P.<|?> ([],P.some a)
44 instance Ord e => RNC.Sym_Rule (P.ParsecT e XMLs m) where
45 -- rule n p = P.dbg s p {-(p P.<?> s)-} where s = Text.unpack n
49 -- | Like 'P.satisfy' but with a predicate returning 'Maybe' instead of 'Bool'.
50 p_satisfyMaybe :: P.MonadParsec e s m => (P.Token s -> Maybe a) -> m a
51 p_satisfyMaybe f = check `P.token` Nothing
56 Nothing -> Left (Just $ P.Tokens $ c:|[], Set.empty)
58 instance Ord e => RNC.Sym_RNC (P.Parsec e XMLs) where
60 none = P.label "none" $ P.eof
62 namespace _p _n = pure ()
64 ts <- P.token check $ Just expected
67 expected = XML.Tree (XML.notSourced $ XML.NodeElem n) mempty
68 check (XML.Tree (XML.unSourced -> XML.NodeElem e) ts)
70 = Right $ removePI $ removeXMLNS $ removeSpaces ts
73 (`Seq.filter` xs) $ \case
74 XML.Tree (XML.unSourced -> XML.NodePI{}) _ts -> False
78 XML.Tree (XML.unSourced -> XML.NodeText (XML.EscapedText et)) _ts ->
80 XML.EscapedPlain t -> TL.all Char.isSpace t
83 then (`Seq.filter` xs) $ \case
84 XML.Tree (XML.unSourced -> XML.NodeText{}) _ts -> False
88 let (attrs,rest) = (`Seq.spanl` xs) $ \case
89 XML.Tree (XML.unSourced -> XML.NodeAttr{}) _ts -> True
91 let attrs' = (`Seq.filter` attrs) $ \case
92 XML.Tree (XML.unSourced -> XML.NodeAttr a) _ts ->
94 XML.QName "" "xmlns" -> False
95 XML.QName ns _l -> ns /= XML.xmlns_xmlns
99 ( Just $ P.Tokens $ pure t
100 , Set.singleton $ P.Tokens $ pure expected )
102 v <- P.token check $ Just expected
105 expected = XML.Tree0 (XML.notSourced $ XML.NodeAttr n)
106 check (XML.Tree (XML.unSourced -> XML.NodeAttr k)
107 v@(toList -> [XML.Tree0 (XML.unSourced -> XML.NodeText _v)])) | k == n =
110 ( Just $ P.Tokens $ pure t
111 , Set.singleton $ P.Tokens $ pure expected )
112 any = P.label "any" $ p_satisfyMaybe $ const $ Just ()
113 anyElem ns p = P.label "anyElem" $ do
114 (n,ts) <- P.token check $ Just expected
115 parserElement n (p $ XML.qNameLocal n) ts
117 expected = XML.Tree (XML.notSourced $ XML.NodeElem $ XML.QName ns $ XML.NCName "*") mempty
118 check (XML.Tree (XML.unSourced -> XML.NodeElem e) ts)
119 | XML.qNameSpace e == ns
122 ( Just $ P.Tokens $ pure t
123 , Set.singleton $ P.Tokens $ pure expected )
128 XML.Tree0 (XML.unSourced -> XML.NodeComment c) :< ts -> do
130 c <$ XML.setFilePosToNextNode
131 t :< _ts -> P.failure (Just $ P.Tokens $ pure t) ex
132 EmptyL -> P.failure Nothing ex
134 ex = Set.singleton $ P.Tokens $ pure expected
135 expected = XML.Tree0 (XML.notSourced $ XML.NodeComment "")
138 P.token check (Just expected)
139 <* XML.setFilePosToNextNode
141 expected = XML.Tree0 (XML.notSourced $ XML.NodeText $ XML.EscapedText mempty)
142 check (XML.Tree0 (XML.unSourced -> XML.NodeText t)) = Right t
144 ( Just $ P.Tokens $ pure t
145 , Set.singleton $ P.Tokens $ pure expected )
146 optional = P.optional
150 fail = P.label "fail" $ P.failure Nothing mempty
152 parserElement :: Ord e => XML.QName -> P.Parsec e XMLs a -> XMLs -> P.Parsec e XMLs a
153 parserElement _n = XML.parser