syntax 0.2.1.0 → 0.3.0.0
raw patch · 4 files changed
+136/−13 lines, 4 filesdep +textdep ~semi-isoPVP ok
version bump matches the API change (PVP)
Dependencies added: text
Dependency ranges changed: semi-iso
API changes (from Hackage documentation)
+ Data.Syntax.Char: digitDec :: SyntaxChar syn seq => syn Int
+ Data.Syntax.Char: digitHex :: SyntaxChar syn seq => syn Int
+ Data.Syntax.Char: digitOct :: SyntaxChar syn seq => syn Int
+ Data.Syntax.Char: hexadecimal :: (SyntaxChar syn seq, Integral a, Bits a) => syn a
+ Data.Syntax.Char: realFloat :: (SyntaxChar syn seq, RealFloat a) => syn a
+ Data.Syntax.Char: type SyntaxText syn = SyntaxChar syn Text
+ Data.Syntax.Indent: breakLine :: SyntaxChar syn seq => Indent syn ()
+ Data.Syntax.Indent: data Indent m a
+ Data.Syntax.Indent: indented :: Indent m a -> Indent m a
+ Data.Syntax.Indent: instance SemiIsoAlternative m => SemiIsoAlternative (Indent m)
+ Data.Syntax.Indent: instance SemiIsoApply m => SemiIsoApply (Indent m)
+ Data.Syntax.Indent: instance SemiIsoFix m => SemiIsoFix (Indent m)
+ Data.Syntax.Indent: instance SemiIsoFunctor m => SemiIsoFunctor (Indent m)
+ Data.Syntax.Indent: instance SemiIsoMonad m => SemiIsoMonad (Indent m)
+ Data.Syntax.Indent: instance Syntax syn seq => Syntax (Indent syn) seq
+ Data.Syntax.Indent: instance SyntaxChar syn seq => SyntaxChar (Indent syn) seq
+ Data.Syntax.Indent: runIndent :: Indent m a -> m () -> m a
- Data.Syntax: class (SemiIsoAlternative syn, SemiIsoMonad syn, IsSequence seq, Eq seq, Eq (Element seq)) => Syntax syn seq | syn -> seq where char c = exact c /$/ anyChar notChar c = bifiltered (/= c) /$/ anyChar satisfy p = bifiltered p /$/ anyChar satisfyWith ai p = bifiltered p . ai /$/ anyChar string s = exact s /$/ take (olength s) take n = packed /$/ sireplicate n anyChar takeWhile p = packed /$/ simany (satisfy p) takeWhile1 p = packed /$/ sisome (satisfy p) takeTill p = takeWhile (not . p) takeTill1 p = takeWhile1 (not . p)
+ Data.Syntax: class (SemiIsoAlternative syn, SemiIsoMonad syn, IsSequence seq, Eq seq, Eq (Element seq)) => Syntax syn seq | syn -> seq where char c = rev (exact c) /$/ anyChar notChar c = bifiltered (/= c) /$/ anyChar satisfy p = bifiltered p /$/ anyChar satisfyWith ai p = bifiltered p . ai /$/ anyChar string s = rev (exact s) /$/ take (olength s) take n = packed /$/ sireplicate n anyChar takeWhile p = packed /$/ simany (satisfy p) takeWhile1 p = packed /$/ sisome (satisfy p) takeTill p = takeWhile (not . p) takeTill1 p = takeWhile1 (not . p)
Files
- Data/Syntax.hs +2/−2
- Data/Syntax/Char.hs +42/−2
- Data/Syntax/Indent.hs +77/−0
- syntax.cabal +15/−9
Data/Syntax.hs view
@@ -54,7 +54,7 @@ -- | A specific character. char :: Element seq -> syn ()- char c = exact c /$/ anyChar+ char c = rev (exact c) /$/ anyChar -- | Any character except the given one. notChar :: Element seq -> syn (Element seq)@@ -71,7 +71,7 @@ -- | A specific string. string :: seq -> syn ()- string s = exact s /$/ take (olength s)+ string s = rev (exact s) /$/ take (olength s) -- | A string of length @n@. take :: Int -> syn seq
Data/Syntax/Char.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE MultiParamTypeClasses #-} {- | Module : Data.Syntax.Char@@ -14,20 +15,26 @@ -} module Data.Syntax.Char ( SyntaxChar(..),+ SyntaxText, signed, spaces, spaces_, spaces1,- endOfLine+ endOfLine,+ digitDec,+ digitOct,+ digitHex ) where import Control.Lens.SemiIso+import Data.Bits import Data.Char import Data.MonoTraversable import Data.Scientific (Scientific) import Data.SemiIsoFunctor import Data.Syntax import Data.Syntax.Combinator+import Data.Text (Text) -- | Syntax constrainted to sequences of chars. --@@ -37,11 +44,20 @@ -- | An unsigned decimal number. decimal :: Integral a => syn a + -- | An unsigned hexadecimal number.+ hexadecimal :: (Integral a, Bits a) => syn a++ -- | A signed real number.+ realFloat :: RealFloat a => syn a+ -- | A scientific number. scientific :: syn Scientific - {-# MINIMAL decimal, scientific #-}+ {-# MINIMAL decimal, hexadecimal, realFloat, scientific #-} +-- | An useful synonym for SyntaxChars with Text sequences.+type SyntaxText syn = SyntaxChar syn Text+ -- | A number with an optional leading '+' or '-' sign character. signed :: (Real a, SyntaxChar syn seq) => syn a -> syn a signed n = _Negative /$/ char '-' */ n@@ -62,3 +78,27 @@ -- | Accepts a single newline. Generates a newline. endOfLine :: SyntaxChar syn seq => syn () endOfLine = char '\n'++-- | A decimal digit.+digitDec :: SyntaxChar syn seq => syn Int+digitDec = semiIso toChar toInt /$/ anyChar+ where toInt c | isDigit c = Right (digitToInt c)+ | otherwise = Left ("Expected a decimal digit, got " ++ [c])+ toChar i | i >= 0 && i <= 9 = Right (intToDigit i)+ | otherwise = Left ("Expected a decimal digit, got number " ++ show i)++-- | An octal digit.+digitOct :: SyntaxChar syn seq => syn Int+digitOct = semiIso toChar toInt /$/ anyChar+ where toInt c | isOctDigit c = Right (digitToInt c)+ | otherwise = Left ("Expected an octal digit, got " ++ [c])+ toChar i | i >= 0 && i <= 7 = Right (intToDigit i)+ | otherwise = Left ("Expected an octal digit, got number " ++ show i)++-- | A hex digit.+digitHex :: SyntaxChar syn seq => syn Int+digitHex = semiIso toChar toInt /$/ anyChar+ where toInt c | isHexDigit c = Right (digitToInt c)+ | otherwise = Left ("Expected a hex digit, got " ++ [c])+ toChar i | i >= 0 && i <= 15 = Right (intToDigit i)+ | otherwise = Left ("Expected a hex digit, got number " ++ show i)
+ Data/Syntax/Indent.hs view
@@ -0,0 +1,77 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{- |+Module : Data.Syntax.Indent+Description : Indentation.+Copyright : (c) Paweł Nowak+License : MIT++Maintainer : Paweł Nowak <pawel834@gmail.com>+Stability : experimental++Provides a very simple indentation as a \"monad\" transformer.+-}+module Data.Syntax.Indent (+ Indent,+ runIndent,+ breakLine,+ indented+ ) where++import Data.SemiIsoFunctor+import Data.Syntax+import Data.Syntax.Char+import Data.Syntax.Combinator+import Prelude hiding (takeWhile, take)++-- | Adds indentation to a syntax description.+newtype Indent m a = Indent { unIndent :: (Int, m ()) -> m a }++instance SemiIsoFunctor m => SemiIsoFunctor (Indent m) where+ simap f (Indent g) = Indent $ \i -> simap f (g i)++instance SemiIsoApply m => SemiIsoApply (Indent m) where+ sipure ai = Indent $ \_ -> sipure ai+ Indent f /*/ Indent g = Indent $ \i -> f i /*/ g i++instance SemiIsoAlternative m => SemiIsoAlternative (Indent m) where+ siempty = Indent $ \_ -> siempty+ Indent f /|/ Indent g = Indent $ \i -> f i /|/ g i++instance SemiIsoMonad m => SemiIsoMonad (Indent m) where+ (Indent m) //= f = Indent $ \i -> m i //= (\x -> unIndent (f x) i)++instance SemiIsoFix m => SemiIsoFix (Indent m) where+ sifix f = Indent $ \i -> sifix $ \y -> unIndent (f y) i++instance Syntax syn seq => Syntax (Indent syn) seq where+ anyChar = Indent $ const anyChar+ char = Indent . const . char+ notChar = Indent . const . notChar+ satisfy = Indent . const . satisfy+ satisfyWith ai = Indent . const . satisfyWith ai+ string = Indent . const . string+ take = Indent . const . take+ takeWhile = Indent . const . takeWhile+ takeWhile1 = Indent . const . takeWhile1+ takeTill = Indent . const . takeTill+ takeTill1 = Indent . const . takeTill1++instance SyntaxChar syn seq => SyntaxChar (Indent syn) seq where+ decimal = Indent $ const decimal+ scientific = Indent $ const scientific++-- | @runIndent m tab@ runs the 'Indent' transformer using @tab@ once for each+-- level of indentation.+runIndent :: Indent m a -> m () -> m a+runIndent = ($ 0) . curry . unIndent++-- | Inserts a new line and correct indentation, but does not +-- require any formatting when parsing (it just skips all white space).+breakLine :: SyntaxChar syn seq => Indent syn ()+breakLine = Indent $ \(i, tab) -> opt (char '\n') /* opt (sireplicate_ i tab) /* spaces_++-- | Increases the indentation level of its argument by one.+indented :: Indent m a -> Indent m a+indented (Indent f) = Indent $ \(i, tab) -> f (i + 1, tab)
syntax.cabal view
@@ -1,16 +1,16 @@ name: syntax-version: 0.2.1.0+version: 0.3.0.0 synopsis: Syntax descriptions for unified parsing and pretty-printing. description: 'syntax' allows you to write a single syntax description and instantiate is both as a parser and a pretty printer. .- The interface is based on a custom Functor/Applicative/Monad hierarchy, provided by the 'semi-iso' package. You fmap using+ The interface is based on a custom Functor\/Applicative\/Monad hierarchy, provided by the 'semi-iso' package. You fmap using a semi-isomorphism instead of function. A semi-isomorphism is a isomorphism that can fail in both directions, with slightly weakened laws. It is worth to note that @Iso@s and @Prism@s from 'lens' are valid semi-isomorphisms :) .- Once you write a description you can, for example turn it into an Attoparsec parser.+ Once you write a description you can, for example turn it into an Attoparsec parser, or into a 'Data.Syntax.Printer.Text.Printer'. .- See @syntax-example@ for an example, 'syntax-attoparsec' and 'syntax-pretty' for a parser/printer implementation.+ See @syntax-example@ and @syntax-example-json@ for examples, @syntax-attoparsec@ and @syntax-printer@ for a parser/printer implementation. . The library was inspired by: .@@ -18,10 +18,15 @@ . TODO: .- * a printer library based on Text/ByteString builders (wrapping 'pretty' is inefficient and doesn't use any features of it),- * try to implement indentation and Haskell layout rule,- * combinators for binary data formats, vectors,- * implementation of do notation for SemiIsoMonad with QuasiQuoters.+ * Research relative monads and relative monad transformers. Indent is basically a Reader monad over a syntax. How would a State monad look?+ .+ * Try to implement Haskell layout rule.+ .+ * Combinators for binary data formats, vectors.+ .+ * Better error messages.+ .+ * Maybe an implementation of do notation for SemiIsoMonad with QuasiQuoters, like the codo notation for comonads. license: MIT license-file: LICENSE@@ -40,5 +45,6 @@ exposed-modules: Data.Syntax Data.Syntax.Char Data.Syntax.Combinator- build-depends: base >= 4 && < 5, mono-traversable, lens >= 4, semi-iso >= 0.4.1, scientific >= 0.3+ Data.Syntax.Indent+ build-depends: base >= 4 && < 5, mono-traversable, lens >= 4, semi-iso >= 0.5.0, scientific >= 0.3, text default-language: Haskell2010