Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
Symparsec.Parser
Description
Base definitions for Symparsec parsers.
Some types are useable both on term-level, and promoted on type-level e.g.
Result
. For ease of use, you can access the promoted version via type synonyms
like PResult
(for promoted X). (This pattern is copied from singletons
.)
Some definitions I use:
- "defun symbol": Short for "defunctionalization symbol". A method of passing
type-level functions (type families) around, without applying them. We use
phadej's
defun
library for the basic functionality. - "consuming [parser]": A parser which must consume its input. Symparsec
parsers are always consuming, as it helps keep parser running simple. This
is problematic, as you can define non-consuming parsers e.g.
Take 0
. We handle this by preprocessing initial parser state, to check for such cases.
Synopsis
- data Parser str s r = Parser {}
- data PParser s r = PParser {
- pparserCh :: ParserChSym s r
- pparserEnd :: ParserEndSym s r
- pparserS0 :: s
- type ResultOf (p :: PParser s r) = r
- data SParser ss sr p where
- SParser :: SParserChSym ss sr pCh -> SParserEndSym ss sr pEnd -> ss s0 -> SParser ss sr ('PParser pCh pEnd s0)
- type ParserCh str s r = Char -> s -> Result str s r
- type PParserCh s r = ParserCh Symbol s r
- type ParserChSym s r = Char ~> (s ~> PResult s r)
- type ParserChSym1 s r = Char -> s ~> PResult s r
- type SParserChSym ss sr pCh = Lam2 SChar ss (SResult ss sr) pCh
- type SParserChSym1 ch ss sr pCh = SChar ch -> Lam ss (SResult ss sr) (pCh ch)
- type ParserEnd str s r = s -> ResultEnd str r
- type PParserEnd s r = ParserEnd Symbol s r
- type ParserEndSym s r = s ~> PResultEnd r
- type SParserEndSym ss sr pEnd = Lam ss (SResultEnd sr) pEnd
- type ParserSInit s0 s = s0 -> PResultSInit s
- type ParserSInitSym s0 s = s0 ~> PResultSInit s
- type SParserSInitSym ss0 ss sInit = Lam ss0 (SResultSInit ss) sInit
- data Result str s r
- type PResult = Result Symbol
- data SResult (ss :: s -> Type) (sr :: r -> Type) (res :: PResult s r) where
- type PResultEnd = Either PE
- type SResultEnd = SEither SE
- type PResultSInit s = Either (PE, s) s
- type SResultSInit ss = SEither (STuple2 SE ss) ss
- data E str
- type PE = E Symbol
- data SE (e :: PE) where
- demoteSE :: SE e -> E String
- class SingE (e :: PE) where
- withSingE :: forall e r. SE e -> (SingE e => r) -> r
- class SingParser (p :: PParser s r) where
- singParser :: forall {s} {r} (p :: PParser s r). SingParser p => SParser (PS p) (PR p) p
Parser
A type-level parser, containing defunctionalization symbols.
Only intended for promoted use. For singled term-level parsers, use
SParser
. (Symparsec doesn't provide "regular" term-level parsers.)
I would make this demotable, but the defun symbols get in the way.
Constructors
PParser | |
Fields
|
type ResultOf (p :: PParser s r) = r Source #
The result type of a type-level parser. (Sometimes handy.)
data SParser ss sr p where Source #
A singled parser.
TODO consider swapping for STuple3...? this is much easier though
Constructors
SParser :: SParserChSym ss sr pCh -> SParserEndSym ss sr pEnd -> ss s0 -> SParser ss sr ('PParser pCh pEnd s0) |
type ParserChSym s r = Char ~> (s ~> PResult s r) Source #
A defunctionalization symbol for a ParserCh
.
type ParserChSym1 s r = Char -> s ~> PResult s r Source #
A partially-applied defunctionalization symbol for a ParserCh
.
type ParserEnd str s r = s -> ResultEnd str r Source #
What a parser should do at the end of a Symbol
.
type PParserEnd s r = ParserEnd Symbol s r Source #
type ParserEndSym s r = s ~> PResultEnd r Source #
A defunctionalization symbol for a ParserEnd
.
type SParserEndSym ss sr pEnd = Lam ss (SResultEnd sr) pEnd Source #
type ParserSInit s0 s = s0 -> PResultSInit s Source #
type ParserSInitSym s0 s = s0 ~> PResultSInit s Source #
type SParserSInitSym ss0 ss sInit = Lam ss0 (SResultSInit ss) sInit Source #
The result of a single step of a parser.
Promotable. Instantiate with String
for term-level, Symbol
for
type-level.
Note that a Done
indicates the parser has not consumed the character. In
the original design, it did consume it, and parsers did their own "lookahead"
to handle this. The non-consuming behaviour simplifies permitting
non-consuming parsers such as Take 0
.
Constructors
Cont s | OK, consumed, continue with state |
Done r | OK, not consumed, parse succeeded with result |
Err (E str) | parse error |
Instances
type PResultEnd = Either PE Source #
type SResultEnd = SEither SE Source #
type PResultSInit s = Either (PE, s) s Source #
Error
Constructors
EBase | Base parser error. |
Fields
| |
EIn | Inner parser error inside combinator. |
Fields
|
Instances
Singling
class SingParser (p :: PParser s r) where Source #
Promoted parsers with singled implementations.
Associated Types
type PS p :: s -> Type Source #
A singleton for the parser state.
type PR p :: r -> Type Source #
A singleton for the parser return type.
Instances
SingParser End Source # | |
KnownNat n => SingParser (Take n :: PParser TakeS Symbol) Source # | |
KnownNat n => SingParser (Skip n :: PParser Natural ()) Source # | |
KnownSymbol str => SingParser (Literal str :: PParser Symbol ()) Source # | |
(p ~ 'PParser pCh pEnd s0, SingParser p, SingChPred chPred) => SingParser (While' chPred pCh pEnd s0 :: PParser s r) Source # | |
SingParser TakeRest Source # | |
(KnownNat base, SingParseDigit parseDigit) => SingParser (NatBase base parseDigit :: PParser (Maybe Natural) Natural) Source # | |
(p ~ 'PParser pCh pEnd s0, KnownNat n, SingParser p) => SingParser (Isolate' n pCh pEnd s0 :: PParser (Natural, s) r) Source # | |
(pl ~ 'PParser plCh plEnd s0l, pr ~ 'PParser prCh prEnd s0r, SingParser pl, SingParser pr) => SingParser (ThenVR' plCh plEnd s0l prCh prEnd s0r :: PParser (Either sl (r, sr)) r) Source # | |
(pl ~ 'PParser plCh plEnd s0l, pr ~ 'PParser prCh prEnd s0r, SingParser pl, SingParser pr) => SingParser (ThenVL' plCh plEnd s0l prCh prEnd s0r :: PParser (Either sl sr) r) Source # | |
(p ~ 'PParser pCh pEnd s0, SingParser p, KnownNat n) => SingParser (Count' n pCh pEnd s0 :: PParser (CountS k r) [r]) Source # | |
(pl ~ 'PParser plCh plEnd s0l, pr ~ 'PParser prCh prEnd s0r, SingParser pl, SingParser pr) => SingParser (Then' plCh plEnd s0l prCh prEnd s0r :: PParser (Either sl (rl, sr)) (rl, rr)) Source # | |
(pl ~ 'PParser plCh plEnd s0l, pr ~ 'PParser prCh prEnd s0r, SingParser pl, SingParser pr) => SingParser (Or' plCh plEnd s0l prCh prEnd s0r :: PParser (OrS sl sr) (Either rl rr)) Source # | |
singParser :: forall {s} {r} (p :: PParser s r). SingParser p => SParser (PS p) (PR p) p Source #
Get the singled version of the requested parser.
singParser'
with better type application ergonomics.