1 {-# LANGUAGE BangPatterns #-}
2 {-# LANGUAGE FlexibleContexts #-}
3 {-# LANGUAGE FlexibleInstances #-}
4 {-# LANGUAGE OverloadedStrings #-}
5 {-# LANGUAGE RecordWildCards #-}
6 {-# LANGUAGE ScopedTypeVariables #-}
7 {-# LANGUAGE TypeFamilies #-}
8 {-# LANGUAGE ViewPatterns #-}
9 {-# OPTIONS_GHC -fno-warn-orphans #-}
10 -- | Read DTC from TCT.
11 module Language.DTC.Read.TCT where
13 import Control.Applicative (Applicative(..))
14 import Control.Monad (Monad(..))
16 import Data.Either (Either(..))
17 import Data.Eq (Eq(..))
18 import Data.Foldable (null, foldl')
19 import Data.Function (($), (.), const, id)
20 import Data.Functor ((<$>), (<$))
22 import Data.List.NonEmpty (NonEmpty(..))
23 import Data.Maybe (Maybe(..), fromMaybe)
24 import Data.Monoid (Monoid(..))
25 import Data.Ord (Ord(..))
26 import Data.Proxy (Proxy(..))
27 import Data.Semigroup (Semigroup(..))
28 import Data.Sequence (ViewL(..))
29 import Data.String (String)
30 import Data.Text (Text)
31 import Data.Tuple (snd)
32 import GHC.Exts (toList)
33 import Text.Read (readMaybe)
34 import Text.Show (Show(..))
35 import qualified Data.List as List
36 import qualified Data.Sequence as Seq
37 import qualified Data.Set as Set
38 import qualified Data.Text as Text
39 import qualified Text.Megaparsec as P
40 import qualified Text.Megaparsec.Perm as P
42 import Language.TCT hiding (Parser)
43 import Language.TCT.Write.XML (XML,XMLs,XmlLeaf(..))
44 import Language.DTC.Document (Nat(..), Nat1(..))
45 import qualified Language.DTC.Document as DTC
46 import qualified Language.DTC.Sym as Sym
47 import qualified Language.TCT.Write.XML as XML
50 type Parser = P.Parsec Error XMLs
52 instance Sym.Sym_RNC Parser where
53 rule n p = P.dbg s p {-(p P.<?> s)-} where s = Text.unpack n
55 none = P.label "none" $ P.eof
56 any = P.label "any" $ p_satisfyMaybe $ const $ Just ()
57 anyElem p = P.dbg "anyElem" $ P.label "anyElem" $ do
58 (n,ts) <- P.token check $ Just expected
61 expected = TreeN (cell0 "") mempty
62 check (TreeN (unCell -> n) ts) = Right (n,ts)
64 ( Just $ P.Tokens $ pure t
65 , Set.singleton $ P.Tokens $ pure expected )
67 ts <- P.token check $ Just expected
70 expected = TreeN (cell0 n) mempty
71 check (TreeN (unCell -> e) ts) | e == n = Right ts
73 ( Just $ P.Tokens $ pure t
74 , Set.singleton $ P.Tokens $ pure expected )
76 v <- P.token check $ Just expected
79 expected = Tree0 (cell0 $ XML.XmlAttr n "")
80 check (TreeN (unCell -> e) ts) | e == n = Right ts
81 check (Tree0 (Cell bp ep (XML.XmlAttr k v))) | k == n =
82 Right $ Seq.singleton $ Tree0 $ Cell bp ep $ XML.XmlText v
84 ( Just $ P.Tokens $ pure t
85 , Set.singleton $ P.Tokens $ pure expected )
89 Tree0 (unCell -> XmlComment c) :< ts -> do
92 t :< _ts -> P.failure (Just $ P.Tokens $ pure t) ex
93 EmptyL -> P.failure Nothing ex
95 ex = Set.singleton $ P.Tokens $ pure expected
96 expected = Tree0 (cell0 $ XML.XmlComment "")
98 P.token check (Just expected)
101 expected = Tree0 (cell0 $ XML.XmlText "")
102 check (Tree0 (unCell -> XML.XmlText t)) = Right t
104 ( Just $ P.Tokens $ pure t
105 , Set.singleton $ P.Tokens $ pure expected )
106 int = Sym.rule "int" $ Sym.text >>= \t ->
107 case readMaybe (Text.unpack t) of
109 Nothing -> P.fancyFailure $
110 Set.singleton $ P.ErrorCustom $ Error_Not_Int t
111 nat = Sym.rule "nat" $ Sym.int >>= \i ->
114 else P.fancyFailure $ Set.singleton $
115 P.ErrorCustom $ Error_Not_Nat i
116 nat1 = Sym.rule "nat1" $ Sym.int >>= \i ->
119 else P.fancyFailure $ Set.singleton $
120 P.ErrorCustom $ Error_Not_Nat1 i
124 type Perm Parser = P.PermParser XMLs Parser
125 interleaved = P.makePermParser
130 f <$*> a = f P.<$?> ([],P.some a)
131 f <|*> a = f P.<|?> ([],P.some a)
132 instance Sym.Sym_DTC Parser
135 Sym.Sym_DTC Parser =>
137 Either (P.ParseError (P.Token XMLs) Error) DTC.Document
138 readDTC = parseXMLs (P.initialPos "") Sym.document
141 Sym.Sym_DTC Parser =>
142 P.SourcePos -> Parser a -> XMLs ->
143 Either (P.ParseError (P.Token XMLs) Error) a
145 snd $ P.runParser' (p <* Sym.none)
148 , P.statePos = pure $
150 Tree0 c :< _ -> sourcePosCell c
151 TreeN c _ :< _ -> sourcePosCell c
153 , P.stateTabWidth = P.pos1
154 , P.stateTokensProcessed = 0
157 -- | @parserXMLs pos p xs@ returns a 'Parser' parsing @xs@ with @p@.
159 Sym.Sym_DTC Parser =>
160 Parser a -> XMLs -> Parser a
163 case parseXMLs pos p xs of
164 Left (P.TrivialError (posErr:|_) un ex) -> do
167 Left (P.FancyError (posErr:|_) errs) -> do
170 Right a -> a <$ fixPos
172 -- | Adjust the current 'P.SourcePos'
173 -- to be the begining of the following-sibling 'XML' node
174 -- so that on error 'P.toHints' keeps expected 'P.Token's in the list,
175 -- and thus makes useful error messages.
177 -- This is needed because the end of a 'Cell'
178 -- is not necessarily the begin of the next 'Cell'.
183 , P.statePos = pos :| _
184 } <- P.getParserState
185 case Seq.viewl inp of
187 t :< _ -> P.setPosition $
188 P.positionAt1 (Proxy::Proxy XMLs) pos t
190 sourcePosCell :: Cell a -> P.SourcePos
193 (P.mkPos $ lineCell c)
194 (P.mkPos $ columnCell c)
196 sourcePos :: Pos -> Maybe P.SourcePos
197 sourcePos (Pos l c) | l>0 && c>0 = Just $ P.SourcePos "" (P.mkPos l) (P.mkPos c)
198 sourcePos _ = Nothing
201 instance P.Stream XMLs where
202 type Token XMLs = XML
203 type Tokens XMLs = XMLs
206 Tree0 (unCell -> XmlComment{}) :< ts -> P.take1_ ts
209 positionAt1 _s pos t =
210 fromMaybe pos $ sourcePos $
212 TreeN c _ -> posCell c
214 positionAtN s pos ts =
216 t :< _ -> P.positionAt1 s pos t
218 advance1 _s _indent pos t =
219 -- WARNING: the end of a 'Cell' is not necessarily
220 -- the beginning of the next 'Cell'.
221 fromMaybe pos $ sourcePos $
223 TreeN c _ -> posEndCell c
224 Tree0 c -> posEndCell c
225 advanceN s = foldl' . P.advance1 s
227 | n <= 0 = Just (mempty, s)
229 | otherwise = Just (Seq.splitAt n s) -- FIXME: handle XmlComment
230 tokensToChunk _s = Seq.fromList
231 chunkToTokens _s = toList
232 chunkLength _s = Seq.length
233 takeWhile_ = Seq.spanl
234 instance P.ShowToken XML where
235 showTokens toks = List.intercalate ", " $ toList $ showTree <$> toks
237 showTree :: XML -> String
239 Tree0 c -> showCell c showXmlLeaf
240 TreeN c _ts -> showCell c showXmlName
242 showCell (Cell (Pos 0 0) (Pos 0 0) a) f = f a
243 showCell (Cell bp ep a) f = f a<>" at "<>show bp<>"-"<>show ep
246 XmlAttr n _v -> show n<>"="
248 XmlComment _c -> "comment"
249 showXmlName n = "<"<>show n<>">"
257 -- | Error_Unexpected P.sourcePos XML
258 deriving (Eq,Ord,Show)
259 instance P.ShowErrorComponent Error where
260 showErrorComponent = show