{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE MultiParamTypeClasses #-} {- | Module : Data.Syntax.Char Description : Char specific combinators. Copyright : (c) Paweł Nowak License : MIT Maintainer : Paweł Nowak Stability : experimental Common combinators that work with sequences of chars. -} module Data.Syntax.Char ( SyntaxChar(..), signed, spaces, spaces_, spaces1, endOfLine ) where import Control.Lens.SemiIso import Data.Char import Data.MonoTraversable import Data.Scientific (Scientific) import Data.SemiIsoFunctor import Data.Syntax import Data.Syntax.Combinator -- | Syntax constrainted to sequences of chars. -- -- Note: methods of this class do not have default implementations (for now), -- because their code is quite ugly and already written in most parser libraries. class (Syntax syn seq, Element seq ~ Char) => SyntaxChar syn seq where -- | An unsigned decimal number. decimal :: Integral a => syn a -- | A scientific number. scientific :: syn Scientific {-# MINIMAL decimal, scientific #-} -- | A number with an optional leading '+' or '-' sign character. signed :: (Real a, SyntaxChar syn seq) => syn a -> syn a signed n = _Negative /$/ char '-' */ n /|/ opt_ (char '+') */ n -- | Accepts zero or more spaces. Generates a single space. spaces :: SyntaxChar syn seq => syn () spaces = opt spaces1 -- | Accepts zero or more spaces. Generates no output. spaces_ :: SyntaxChar syn seq => syn () spaces_ = opt_ spaces1 -- | Accepts one or more spaces. Generates a single space. spaces1 :: SyntaxChar syn seq => syn () spaces1 = constant (opoint ' ') /$/ takeWhile1 isSpace -- | Accepts a single newline. Generates a newline. endOfLine :: SyntaxChar syn seq => syn () endOfLine = char '\n'