on 22894b4 help sign in
syntax/Data/Syntax.hs
96 lines 3.0 kB history raw
1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE DefaultSignatures #-}
3{-# LANGUAGE MultiParamTypeClasses #-}
4{-# LANGUAGE FunctionalDependencies #-}
5{- |
6Module : Data.Syntax
7Description : Abstract syntax description.
8Copyright : (c) Paweł Nowak
9License : MIT
11Maintainer : Paweł Nowak <pawel834@gmail.com>
12Stability : experimental
14Abstract syntax descriptions based on semi-isomorphisms.
15-}
16module Data.Syntax (
17 -- * Syntax.
18 Syntax(..),
19 -- * Common isomorphisms.
20 packed
21 ) where
23import Prelude hiding (take, takeWhile)
25import Control.Lens.Iso
26import Control.Lens.SemiIso
27import Data.MonoTraversable
28import Data.SemiIsoFunctor
29import Data.Sequences hiding (take, takeWhile)
31-- | An isomorphism between a sequence and a list of its elements.
32packed :: IsSequence seq => Iso' seq [Element seq]
33packed = iso otoList fromList
35-- | An abstract syntax description based on semi-isomorphisms.
36--
37-- This class can be implemented by both parsers and printers (and maybe more?).
38--
39-- The usual use is to write a polymorphic syntax description and instantiate it
40-- both as a parser and a printer. An example is available in the 'syntax-example'
41-- package.
42--
43-- Methods of this class try to mimic "Data.Attoparsec.Text" interface.
44class ( SemiIsoAlternative syn
45 , SemiIsoMonad syn
46 , IsSequence seq
47 , Eq seq
48 , Eq (Element seq))
49 => Syntax syn seq | syn -> seq
50 where
52 -- | Any character.
53 anyChar :: syn (Element seq)
55 -- | A specific character.
56 char :: Element seq -> syn ()
57 char c = rev (exact c) /$/ anyChar
59 -- | Any character except the given one.
60 notChar :: Element seq -> syn (Element seq)
61 notChar c = bifiltered (/= c) /$/ anyChar
63 -- | Any character satisfying a predicate.
64 satisfy :: (Element seq -> Bool) -> syn (Element seq)
65 satisfy p = bifiltered p /$/ anyChar
67 -- | Transforms a character using a SemiIso and filters out values
68 -- not satisfying the predicate.
69 satisfyWith :: ASemiIso' a (Element seq) -> (a -> Bool) -> syn a
70 satisfyWith ai p = bifiltered p . ai /$/ anyChar
72 -- | A specific string.
73 string :: seq -> syn ()
74 string s = rev (exact s) /$/ take (olength s)
76 -- | A string of length @n@.
77 take :: Int -> syn seq
78 take n = packed /$/ sireplicate n anyChar
80 -- | Maximal string which elements satisfy a predicate.
81 takeWhile :: (Element seq -> Bool) -> syn seq
82 takeWhile p = packed /$/ simany (satisfy p)
84 -- | Maximal non-empty string which elements satisfy a predicate.
85 takeWhile1 :: (Element seq -> Bool) -> syn seq
86 takeWhile1 p = packed /$/ sisome (satisfy p)
88 -- | Maximal string which elements do not satisfy a predicate.
89 takeTill :: (Element seq -> Bool) -> syn seq
90 takeTill p = takeWhile (not . p)
92 -- | Maximal non-empty string which elements do not satisfy a predicate.
93 takeTill1 :: (Element seq -> Bool) -> syn seq
94 takeTill1 p = takeWhile1 (not . p)
96 {-# MINIMAL anyChar #-}