symparsec 1.1.0 → 1.1.1
raw patch · 7 files changed
+133/−3 lines, 7 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Symparsec.Example.Expr: EBOp :: Expr -> BOp -> Expr -> Expr
+ Symparsec.Example.Expr: ELit :: Lit -> Expr
+ Symparsec.Example.Expr: LNat :: Natural -> Lit
+ Symparsec.Example.Expr: Plus :: BOp
+ Symparsec.Example.Expr: data BOp
+ Symparsec.Example.Expr: data Curry3Sym f abc
+ Symparsec.Example.Expr: data Expr
+ Symparsec.Example.Expr: data FromEitherSym eaa
+ Symparsec.Example.Expr: data Lit
+ Symparsec.Example.Expr: type PBOp = ConstSym1 Plus :<$>: Literal "+"
+ Symparsec.Example.Expr: type PEBOp = Curry3Sym (Con3 EBOp) :<$>: (PExpr :<*>: PBOp :<*>: PExpr)
+ Symparsec.Example.Expr: type PELit = Con1 ELit :<$>: PLit
+ Symparsec.Example.Expr: type PExpr = PELit
+ Symparsec.Example.Expr: type PLNat = Con1 LNat :<$>: While IsHexDigitSym NatHex
+ Symparsec.Example.Expr: type PLit = PLNat
+ Symparsec.Example.Expr: type family FromEither eaa
+ Symparsec.Parser: type ResultOf (p :: PParser s r) = r
+ Symparsec.Parser.Apply: data ApplyChSym f pCh x
+ Symparsec.Parser.Apply: data ApplyChSym1 f pCh ch s
+ Symparsec.Parser.Apply: data ApplyEndSym f pEnd s
+ Symparsec.Parser.Apply: type Apply' f pCh pEnd s0 = 'PParser (ApplyChSym f pCh) (ApplyEndSym f pEnd) s0
+ Symparsec.Parser.Apply: type family ApplyEnd' f res
+ Symparsec.Run: type Run'_ p str = Run'_Inner (Run' p str)
Files
- CHANGELOG.md +4/−0
- README.md +1/−1
- src/Symparsec/Example/Expr.hs +50/−0
- src/Symparsec/Parser.hs +4/−1
- src/Symparsec/Parser/Apply.hs +61/−0
- src/Symparsec/Run.hs +10/−0
- symparsec.cabal +3/−1
CHANGELOG.md view
@@ -1,3 +1,7 @@+## 1.1.1 (2024-06-15)+* add `Apply` combinator (effectively `fmap`)+* add some more runners and utils (handy for generic-data-functions)+ ## 1.1.0 (2024-06-01) * add `While` combinator * add `Count` combinator
README.md view
@@ -2,7 +2,7 @@ [hackage-parsec]: https://hackage.haskell.org/package/parsec Type level string (`Symbol`) parser combinators. A [Parsec][hackage-parsec]-like-for `Symbol`s; thus, Symparsec! With all the features you'd expect:+for `Symbol`s; thus, Symparsec! With many of the features you'd expect: * define parsers compositionally, largely as you would on the term level * pretty, detailed parse errors
+ src/Symparsec/Example/Expr.hs view
@@ -0,0 +1,50 @@+{-# LANGUAGE UndecidableInstances#-}++{- | Experiments.++Turns out we can't write recursive parsers. But 'P.Apply' can help us write+handier parsers.+-}++module Symparsec.Example.Expr where++import Numeric.Natural+import Symparsec.Parsers qualified as P+import Symparsec.Parser.While.Predicates qualified as P+import Symparsec.Parser.Apply qualified as P+import DeFun.Core+import DeFun.Function++data Expr+ = ELit Lit+ | EBOp Expr BOp Expr++data BOp = Plus++data Lit+ = LNat Natural++type PLit = PLNat+type PLNat = Con1 LNat P.:<$>: P.While P.IsHexDigitSym P.NatHex+type PELit = Con1 ELit P.:<$>: PLit+type PEBOp = Curry3Sym (Con3 EBOp) P.:<$>: (PExpr P.:<*>: PBOp P.:<*>: PExpr)+type PExpr = PELit+--type PExpr :: PParser (P.OrS (Maybe Natural) (Maybe Natural)) Expr+--type PExpr = FromEitherSym P.:<$>: (PELit P.:<|>: PEBOp)+type PBOp = ConstSym1 Plus P.:<$>: P.Literal "+"++type Curry3Sym+ :: (a ~> b ~> c ~> r)+ -> ((a, b), c)+ ~> r+data Curry3Sym f abc+type instance App (Curry3Sym f) '( '(a, b), c) = f @@ a @@ b @@ c++type FromEither :: Either a a -> a+type family FromEither eaa where+ FromEither (Right a) = a+ FromEither (Left a) = a++type FromEitherSym :: Either a a ~> a+data FromEitherSym eaa+type instance App FromEitherSym eaa = FromEither eaa
src/Symparsec/Parser.hs view
@@ -20,7 +20,7 @@ module Symparsec.Parser ( -- * Parser- Parser(..), PParser(..), SParser(..)+ Parser(..), PParser(..), ResultOf, SParser(..) , ParserCh, PParserCh, ParserChSym, ParserChSym1, SParserChSym, SParserChSym1 , ParserEnd, PParserEnd, ParserEndSym, SParserEndSym , ParserSInit, ParserSInitSym, SParserSInitSym@@ -62,6 +62,9 @@ , pparserEnd :: ParserEndSym s r , pparserS0 :: s }++-- | The result type of a type-level parser. (Sometimes handy.)+type ResultOf (p :: PParser s r) = r -- | A singled parser. --
+ src/Symparsec/Parser/Apply.hs view
@@ -0,0 +1,61 @@+{-# LANGUAGE UndecidableInstances #-}++module Symparsec.Parser.Apply where++import Symparsec.Parser.Common++-- | Apply the given type function to the result.+--+-- Effectively 'fmap' for parsers.+type (:<$>:) :: (r ~> r') -> PParser s r -> PParser s r'+type family f :<$>: p where+ f :<$>: 'PParser pCh pEnd s0 = Apply' f pCh pEnd s0++-- unwrapped for instances+type Apply' f pCh pEnd s0 = 'PParser (ApplyChSym f pCh) (ApplyEndSym f pEnd) s0++-- TODO: Singling is a pain, similar to While. Let's ignore it for now.++type ApplyCh+ :: (r ~> r')+ -> ParserChSym s r+ -> PParserCh s r'+type family ApplyCh f pCh ch s where+ ApplyCh f pCh ch s = ApplyCh' f (pCh @@ ch @@ s)++type family ApplyCh' f res where+ ApplyCh' f (Cont s) = Cont s+ ApplyCh' f (Done r) = Done (f @@ r)+ ApplyCh' f (Err e) = Err e++type ApplyChSym+ :: (r ~> r')+ -> ParserChSym s r+ -> ParserChSym s r'+data ApplyChSym f pCh x+type instance App (ApplyChSym f pCh) x = ApplyChSym1 f pCh x++type ApplyChSym1+ :: (r ~> r')+ -> ParserChSym s r+ -> ParserChSym1 s r'+data ApplyChSym1 f pCh ch s+type instance App (ApplyChSym1 f pCh ch) s = ApplyCh f pCh ch s++type ApplyEnd+ :: (r ~> r')+ -> ParserEndSym s r+ -> PParserEnd s r'+type family ApplyEnd f pEnd s where+ ApplyEnd f pEnd s = ApplyEnd' f (pEnd @@ s)++type family ApplyEnd' f res where+ ApplyEnd' f (Right r) = Right (f @@ r)+ ApplyEnd' f (Left e) = Left e++type ApplyEndSym+ :: (r ~> r')+ -> ParserEndSym s r+ -> ParserEndSym s r'+data ApplyEndSym f pEnd s+type instance App (ApplyEndSym f pEnd) s = ApplyEnd f pEnd s
src/Symparsec/Run.hs view
@@ -44,6 +44,16 @@ type RunTest :: PParser s r -> Symbol -> (r, Symbol) type RunTest p sym = MapLeftTypeError (Run p sym) +-- | Run the given parser on the given 'Symbol', returning a 'PERun' on failure,+-- and ignoring any remaining non-consumed characters.+type Run'_ :: PParser s r -> Symbol -> Either TE.ErrorMessage r+type Run'_ p str = Run'_Inner (Run' p str)++type Run'_Inner :: Either PERun (a, b) -> Either TE.ErrorMessage a+type family Run'_Inner eeab where+ Run'_Inner (Right '(a, b)) = Right a+ Run'_Inner (Left e) = Left (RenderPDoc (PrettyERun e))+ -- | Run the singled version of type-level parser on the given 'String', -- returning an 'ERun' on failure. --
symparsec.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack name: symparsec-version: 1.1.0+version: 1.1.1 synopsis: Type level string parser combinators description: Please see README.md. category: Types, Data@@ -30,7 +30,9 @@ library exposed-modules: Symparsec+ Symparsec.Example.Expr Symparsec.Parser+ Symparsec.Parser.Apply Symparsec.Parser.Common Symparsec.Parser.Count Symparsec.Parser.End