syntax (empty) → 0.1.0.0
raw patch · 5 files changed
+228/−0 lines, 5 filesdep +basedep +lensdep +mono-traversablesetup-changed
Dependencies added: base, lens, mono-traversable, semi-iso
Files
- Data/Syntax.hs +124/−0
- Data/Syntax/Char.hs +54/−0
- LICENSE +20/−0
- Setup.hs +2/−0
- syntax.cabal +28/−0
+ Data/Syntax.hs view
@@ -0,0 +1,124 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{- |+Module : Data.Syntax+Description : Abstract syntax description.+Copyright : (c) Paweł Nowak+License : MIT++Maintainer : Paweł Nowak <pawel834@gmail.com>+Stability : experimental++Abstract syntax descriptions based on semi-isomorphisms.+-}+module Data.Syntax (+ -- * Syntax.+ Syntax(..),+ -- * Common isomorphisms.+ packed+ ) where++import Prelude hiding (take, takeWhile)++import Control.Lens+import Control.Lens.SemiIso+import Data.MonoTraversable+import Data.SemiIsoFunctor+import Data.Sequences hiding (take, takeWhile)++-- | An isomorphism between a sequence and a list of its elements.+packed :: IsSequence seq => Iso' seq [Element seq]+packed = iso otoList fromList++-- | An abstract syntax description based on semi-isomorphisms.+--+-- This class can be implemented by both parsers and printers (and maybe more?).+-- +-- The usual use is to write a polymorphic syntax description and instantiate it+-- both as a parser and a printer. An example syntax description:+--+-- > | A simple untyped lambda calculus.+-- > data AST = Var Text+-- > | App AST AST+-- > | Abs Text AST+-- > deriving (Show)+-- >+-- > $(makePrisms ''AST)+-- >+-- > -- | A variable name.+-- > name :: Syntax syn Text => syn Text+-- > name = S.takeWhile1 isAlphaNum+-- >+-- > -- | Encloses a symbol in parentheses.+-- > parens :: Syntax syn Text => syn a -> syn a+-- > parens m = S.char '(' */ S.spaces_ */ m /* S.spaces_ /* S.char ')'+-- >+-- > -- | An atom is a variable or an expression in parentheses.+-- > atom :: Syntax syn Text => syn AST+-- > atom = _Var /$/ name+-- > /|/ parens expr+-- >+-- > -- | An expression of our lambda calculus.+-- > expr :: Syntax syn Text => syn AST+-- > expr = _App /$/ atom /* S.spaces1 /*/ atom+-- > /|/ _Abs /$/ S.char '\\' /* S.spaces_+-- > */ name /* S.spaces+-- > /* S.string "->" /* S.spaces+-- > /*/ expr +-- > /|/ atom+--+-- Methods of this class try to mimic "Data.Attoparsec.Text" interface.+class ( SemiIsoAlternative syn+ , IsSequence seq+ , Eq seq+ , Eq (Element seq)) + => Syntax syn seq | syn -> seq + where+ + -- | Any character.+ anyChar :: syn (Element seq)++ -- | A specific character.+ char :: Element seq -> syn ()+ char c = exact c /$/ anyChar++ -- | Any character except the given one.+ notChar :: Element seq -> syn (Element seq)+ notChar c = filtered (/= c) /$/ anyChar++ -- | Any character satisfying a predicate.+ satisfy :: (Element seq -> Bool) -> syn (Element seq)+ satisfy p = filtered p /$/ anyChar++ -- | Transforms a character using a SemiIso and filters out values+ -- not satisfying the predicate.+ satisfyWith :: ASemiIso' a (Element seq) -> (a -> Bool) -> syn a+ satisfyWith ai p = filtered p . ai /$/ anyChar++ -- | A specific string.+ string :: seq -> syn ()+ string s = exact s /$/ take (olength s)++ -- | A string of length @n@.+ take :: Int -> syn seq+ take n = packed /$/ sireplicate n anyChar++ -- | Maximal string which elements satisfy a predicate.+ takeWhile :: (Element seq -> Bool) -> syn seq+ takeWhile p = packed /$/ simany (satisfy p)++ -- | Maximal non-empty string which elements satisfy a predicate.+ takeWhile1 :: (Element seq -> Bool) -> syn seq+ takeWhile1 p = packed /$/ sisome (satisfy p)++ -- | Maximal string which elements do not satisfy a predicate.+ takeTill :: (Element seq -> Bool) -> syn seq+ takeTill p = takeWhile (not . p)++ -- | Maximal non-empty string which elements do not satisfy a predicate.+ takeTill1 :: (Element seq -> Bool) -> syn seq+ takeTill1 p = takeWhile1 (not . p)++ {-# MINIMAL anyChar #-}
+ Data/Syntax/Char.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ConstraintKinds #-}+{- |+Module : Data.Syntax.Char+Description : Char specific combinators.+Copyright : (c) Paweł Nowak+License : MIT++Maintainer : Paweł Nowak <pawel834@gmail.com>+Stability : experimental++Common combinators that work with sequences of chars.++There are A LOT of combinators missing.+-}+module Data.Syntax.Char (+ SyntaxChar,+ spaces,+ spaces_,+ spaces1,+ spaces1_,+ endOfLine+ ) where++import Control.Lens.SemiIso+import Data.Char+import Data.MonoTraversable+import Data.Monoid+import Data.SemiIsoFunctor+import Data.Syntax (Syntax)+import qualified Data.Syntax as S++-- | Syntax constrainted to sequences of chars.+type SyntaxChar syn seq = (Syntax syn seq, Element seq ~ Char)++-- | Accepts zero or more spaces. Generates a single space.+spaces :: SyntaxChar syn seq => syn ()+spaces = constant (opoint ' ') /$/ S.takeWhile isSpace++-- | Accepts zero or more spaces. Generates no output.+spaces_ :: SyntaxChar syn seq => syn ()+spaces_ = constant mempty /$/ S.takeWhile isSpace++-- | Accepts one or more spaces. Generates a single space.+spaces1 :: SyntaxChar syn seq => syn ()+spaces1 = constant (opoint ' ') /$/ S.takeWhile1 isSpace++-- | Accepts one or more spaces. Generates no output.+spaces1_ :: SyntaxChar syn seq => syn ()+spaces1_ = constant mempty /$/ S.takeWhile1 isSpace++-- | Accepts a single newline. Generates a newline.+endOfLine :: SyntaxChar syn seq => syn ()+endOfLine = S.char '\n'
+ LICENSE view
@@ -0,0 +1,20 @@+Copyright (c) 2014 Paweł Nowak++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ syntax.cabal view
@@ -0,0 +1,28 @@+name: syntax+version: 0.1.0.0+synopsis: Abstract syntax descriptions for parsing and pretty-printing.+description: Write single syntax description, get both parser and pretty-printer.+ .+ Syntax descriptions are based on semi-isomorphisms from @semi-iso@ library.+ .+ The library is very young. There are lots of useful combinators that could be written.+ .+ See @syntax-example@ for an example.+license: MIT+license-file: LICENSE+author: Paweł Nowak+maintainer: Paweł Nowak <pawel834@gmail.com>+copyright: Paweł Nowak 2014+category: Data+build-type: Simple+cabal-version: >=1.10++source-repository head+ type: git+ location: git@github.com:Pawel834/syntax.git++library+ exposed-modules: Data.Syntax+ Data.Syntax.Char+ build-depends: base >= 4 && < 5, mono-traversable, lens, semi-iso+ default-language: Haskell2010