on master help sign in
Implemented optional, opt, opt_.
commit6a334b9b0d62135b3a68b7188b408ac10c08d891 authorPaweł Nowak <pawel834@gmail.com> dateSun 23 Nov 2014, 15:09 (12 years ago) parentca19f14
2 files changed+29−27
Data/Syntax/Char.hs+14−17 Data/Syntax/Combinator.hs+15−10
Data/Syntax/Char.hs+14−17
@@ -18,18 +18,16 @@ module Data.Syntax.Char (
1818 spaces,
1919 spaces_,
2020 spaces1,
21− spaces1_,
2221 endOfLine
2322 ) where
2423
25−import Control.Lens.SemiIso
26−import Data.Char
27−import Data.MonoTraversable
28−import Data.Monoid
29−import Data.Scientific (Scientific)
30−import Data.SemiIsoFunctor
31−import Data.Syntax (Syntax)
32−import qualified Data.Syntax as S
24+import Control.Lens.SemiIso
25+import Data.Char
26+import Data.MonoTraversable
27+import Data.Scientific (Scientific)
28+import Data.SemiIsoFunctor
29+import Data.Syntax
30+import Data.Syntax.Combinator
3331
3432-- | Syntax constrainted to sequences of chars.
3533--
@@ -45,23 +43,22 @@ class (Syntax syn seq, Element seq ~ Char) => SyntaxChar syn seq where
4543 {-# MINIMAL decimal, scientific #-}
4644
4745-- | A number with an optional leading '+' or '-' sign character.
48−signed :: (Num a, SyntaxChar syn seq) => syn a -> syn a
49−signed n = _Negative /$/ S.char '-' */ n
50− /|/ S.char '+' */ n
51− /|/ n
46+signed :: (Real a, SyntaxChar syn seq) => syn a -> syn a
47+signed n = _Negative /$/ char '-' */ n
48+ /|/ opt_ (char '+') */ n
5249
5350-- | Accepts zero or more spaces. Generates a single space.
5451spaces :: SyntaxChar syn seq => syn ()
55−spaces = constant (opoint ' ') /$/ S.takeWhile isSpace
52+spaces = opt spaces1
5653
5754-- | Accepts zero or more spaces. Generates no output.
5855spaces_ :: SyntaxChar syn seq => syn ()
59−spaces_ = constant mempty /$/ S.takeWhile isSpace
56+spaces_ = opt_ spaces1
6057
6158-- | Accepts one or more spaces. Generates a single space.
6259spaces1 :: SyntaxChar syn seq => syn ()
63−spaces1 = constant (opoint ' ') /$/ S.takeWhile1 isSpace
60+spaces1 = constant (opoint ' ') /$/ takeWhile1 isSpace
6461
6562-- | Accepts a single newline. Generates a newline.
6663endOfLine :: SyntaxChar syn seq => syn ()
67−endOfLine = S.char '\n'
64+endOfLine = char '\n'
Data/Syntax/Combinator.hs+15−10
@@ -11,23 +11,28 @@ Combinators that work with any sequence type.
1111-}
1212module Data.Syntax.Combinator where
1313
14−import Control.Lens.Cons
15−import Control.Lens.Empty
14+import Control.Lens
15+import Control.Lens.SemiIso
1616import Data.SemiIsoFunctor
1717
18−-- | Zero or more occurences of v separated by s.
18+-- | Zero or more occurences of @v@ separated by @s@.
1919sepBy :: SemiIsoAlternative f => f a -> f () -> f [a]
2020sepBy v s = sepBy1 v s
2121 /|/ sipure _Empty
2222
23−-- | One or more occurences of v separated by s.
23+-- | One or more occurences of @v@ separated by @s@.
2424sepBy1 :: SemiIsoAlternative f => f a -> f () -> f [a]
2525sepBy1 v s = _Cons /$/ v /*/ (s */ sepBy1 v s /|/ sipure _Empty)
2626
27−-- |
28−couldBe :: SemiIsoFunctor f => f () -> f ()
29−couldBe f = undefined
27+-- | One or none occurences of @f@.
28+optional :: SemiIsoAlternative f => f a -> f (Maybe a)
29+optional f = _Just /$/ f /|/ sipure _Nothing
3030
31−-- | Something that should be, but doesn't have to be.
32−shouldBe :: SemiIsoAlternative f => f () -> f ()
33−shouldBe f = constant () /$/ f
31+-- | Like 'optional', but specialized for @()@.
32+opt :: SemiIsoAlternative f => f () -> f ()
33+opt f = f /|/ sipure id
34+
35+-- | Parser one or more occurences of @f@, but prints nothing.
36+opt_ :: SemiIsoAlternative f => f () -> f ()
37+opt_ f = semiIso (const (Left "opt_")) Right /$/ f
38+ /|/ sipure id