Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
Symparsec.Parser.Or
Synopsis
- type family pl :<|>: pr where ...
- type Or' plCh plEnd s0l prCh prEnd s0r = 'PParser (OrChSym plCh prCh s0r) (OrEndSym plEnd prCh prEnd s0r) (Left '(s0l, '[]))
- type SOrS ssl ssr = SEither (STuple2 ssl (SList SChar)) ssr
- type OrS sl sr = Either (sl, [Char]) sr
- type SPOr ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r = SParser (SOrS ssl ssr) (SEither srl srr) (Or' plCh plEnd s0l prCh prEnd s0r)
- sOr :: SParser ssl srl ('PParser plCh plEnd s0l) -> SParser ssr srr ('PParser prCh prEnd s0r) -> SPOr ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r
- type family OrCh plCh prCh sr ch s where ...
- type family OrChL prCh s0r chLast chs resl where ...
- type family OrChLReplay prCh chLast chs resr where ...
- sOrChLReplay :: SParserChSym ssr srr prCh -> SChar chLast -> SList SChar chs -> SResult ssr srr resr -> SResult (SOrS ssl ssr) (SEither srl srr) (OrChLReplay prCh chLast chs resr)
- type EOrR er = EIn "Or(R)" er
- eOrR :: SE er -> SE (EOrR er)
- type EOrStillReplaying = EBase "Or" (Text "right parser much consume at least as much as the failed left parser")
- eOrStillReplaying :: SE EOrStillReplaying
- type family OrChR resr where ...
- sOrChR :: SResult ssr srr resr -> SResult (SOrS ssl ssr) (SEither srl srr) (OrChR resr)
- type family OrEnd plEnd prCh prEnd sr res where ...
- type family OrEndR resr where ...
- sOrEndR :: SResultEnd srr resr -> SResultEnd (SEither srl srr) (OrEndR resr)
- type family OrEndL prCh prEnd s0r chs resl where ...
- sOrEndL :: SParserChSym ssr srr prCh -> SParserEndSym ssr srr prEnd -> ssr s0r -> SList SChar chs -> SResultEnd srl resl -> SResultEnd (SEither srl srr) (OrEndL prCh prEnd s0r chs resl)
- type family OrEndLReplay prCh prEnd chs resr where ...
- sOrEndLReplay :: SParserChSym ssr srr prCh -> SParserEndSym ssr srr prEnd -> SList SChar chs -> SResult ssr srr resr -> SResultEnd (SEither srl srr) (OrEndLReplay prCh prEnd chs resr)
- type family OrEndLReplay' prEnd resr where ...
- data OrChSym plCh prCh s0r f
- data OrChSym1 plCh prCh sr ch s
- sOrChSym :: SParserChSym ssl srl plCh -> SParserChSym ssr srr prCh -> ssr s0r -> SParserChSym (SOrS ssl ssr) (SEither srl srr) (OrChSym plCh prCh s0r)
- sOrChL :: SParserChSym ssr srr prCh -> ssr s0r -> SChar chLast -> SList SChar chs -> SResult ssl srl resl -> SResult (SOrS ssl ssr) (SEither srl srr) (OrChL prCh s0r chLast chs resl)
- data OrEndSym plEnd prCh prEnd s0r s
- sOrEndSym :: SParserEndSym ssl srl plEnd -> SParserChSym ssr srr prCh -> SParserEndSym ssr srr prEnd -> ssr s0r -> SParserEndSym (SOrS ssl ssr) (SEither srl srr) (OrEndSym plEnd prCh prEnd s0r)
Documentation
type family pl :<|>: pr where ... infixl 3 Source #
Limited parser choice. Try left; if it fails, backtrack and try right. However, _the right choice must consume at least as much as the left choice._ If it doesn't, then even if the right parser succeeds, it will emit an error.
This behaviour is due to the parser runner not supporting backtracking. We can emulate it by storing a record of the characters parsed so far, and "replaying" these on the right parser if the left parser fails. If the right parser ends before we finish replaying, we will have consumed extra characters that we can't ask the runner to revert.
For example, Literal "abcd" :|: Literal "ab"
is bad. An input of abcX
will
trigger the consumption error.
I can't think of another way to implement this with the current parser design. I
think it's the best we have. A more complex parser design may permit changing
internal running state, so we could save and load state (this would permit a
Try p
parser). But that's scary. And you're better off designing your
type-level string schemas to permit non-backtracking parsing anyway...
Also problematic is that we never emit a left parser error, so errors can degrade. Perhaps your string was one character off a successful left parse; but if it fails, you won't see that error.
type Or' plCh plEnd s0l prCh prEnd s0r = 'PParser (OrChSym plCh prCh s0r) (OrEndSym plEnd prCh prEnd s0r) (Left '(s0l, '[])) Source #
type SPOr ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r = SParser (SOrS ssl ssr) (SEither srl srr) (Or' plCh plEnd s0l prCh prEnd s0r) Source #
sOr :: SParser ssl srl ('PParser plCh plEnd s0l) -> SParser ssr srr ('PParser prCh prEnd s0r) -> SPOr ssl srl ssr srr plCh plEnd s0l prCh prEnd s0r Source #
type family OrChLReplay prCh chLast chs resr where ... Source #
Equations
OrChLReplay prCh chLast (ch : chs) (Cont sr) = OrChLReplay prCh chLast chs ((prCh @@ ch) @@ sr) | |
OrChLReplay prCh chLast '[] (Cont sr) = OrChR ((prCh @@ chLast) @@ sr) | |
OrChLReplay prCh chLast chs (Err er) = Err (EOrR er) | |
OrChLReplay prCh chLast chs (Done rr) = Err EOrStillReplaying |
sOrChLReplay :: SParserChSym ssr srr prCh -> SChar chLast -> SList SChar chs -> SResult ssr srr resr -> SResult (SOrS ssl ssr) (SEither srl srr) (OrChLReplay prCh chLast chs resr) Source #
type EOrStillReplaying = EBase "Or" (Text "right parser much consume at least as much as the failed left parser") Source #
sOrEndR :: SResultEnd srr resr -> SResultEnd (SEither srl srr) (OrEndR resr) Source #
sOrEndL :: SParserChSym ssr srr prCh -> SParserEndSym ssr srr prEnd -> ssr s0r -> SList SChar chs -> SResultEnd srl resl -> SResultEnd (SEither srl srr) (OrEndL prCh prEnd s0r chs resl) Source #
type family OrEndLReplay prCh prEnd chs resr where ... Source #
Equations
OrEndLReplay prCh prEnd (ch : chs) (Cont sr) = OrEndLReplay prCh prEnd chs ((prCh @@ ch) @@ sr) | |
OrEndLReplay prCh prEnd '[] resr = OrEndLReplay' prEnd resr | |
OrEndLReplay prCh prEnd chs (Err er) = Left (EOrR er) | |
OrEndLReplay prCh prEnd chs (Done rr) = Left EOrStillReplaying |
sOrEndLReplay :: SParserChSym ssr srr prCh -> SParserEndSym ssr srr prEnd -> SList SChar chs -> SResult ssr srr resr -> SResultEnd (SEither srl srr) (OrEndLReplay prCh prEnd chs resr) Source #
type family OrEndLReplay' prEnd resr where ... Source #
Equations
OrEndLReplay' prEnd (Cont sr) = OrEndR (prEnd @@ sr) | |
OrEndLReplay' prEnd (Done rr) = Right (Right rr) | |
OrEndLReplay' prEnd (Err er) = Left (EOrR er) |
data OrChSym plCh prCh s0r f Source #
Instances
(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 # | |
type App (OrChSym plCh prCh s0r :: FunKind Char (OrS sl sr ~> PResult (OrS sl sr) (Either rl rr)) -> Type) (f :: Char) Source # | |
type PR (Or' plCh plEnd s0l prCh prEnd s0r :: PParser (OrS sl sr) (Either rl rr)) Source # | |
type PS (Or' plCh plEnd s0l prCh prEnd s0r :: PParser (OrS sl sr) (Either rl rr)) Source # | |
sOrChSym :: SParserChSym ssl srl plCh -> SParserChSym ssr srr prCh -> ssr s0r -> SParserChSym (SOrS ssl ssr) (SEither srl srr) (OrChSym plCh prCh s0r) Source #
sOrChL :: SParserChSym ssr srr prCh -> ssr s0r -> SChar chLast -> SList SChar chs -> SResult ssl srl resl -> SResult (SOrS ssl ssr) (SEither srl srr) (OrChL prCh s0r chLast chs resl) Source #
data OrEndSym plEnd prCh prEnd s0r s Source #
Instances
(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 # | |
type App (OrEndSym plEnd prCh prEnd s0r :: FunKind (Either (sl, [Char]) sr) (PResultEnd (Either rl rr)) -> Type) (s :: Either (sl, [Char]) sr) Source # | |
type PR (Or' plCh plEnd s0l prCh prEnd s0r :: PParser (OrS sl sr) (Either rl rr)) Source # | |
type PS (Or' plCh plEnd s0l prCh prEnd s0r :: PParser (OrS sl sr) (Either rl rr)) Source # | |
sOrEndSym :: SParserEndSym ssl srl plEnd -> SParserChSym ssr srr prCh -> SParserEndSym ssr srr prEnd -> ssr s0r -> SParserEndSym (SOrS ssl ssr) (SEither srl srr) (OrEndSym plEnd prCh prEnd s0r) Source #