License | BSD-3-Clause |
---|---|
Maintainer | Jamie Willis |
Stability | stable |
Safe Haskell | Safe-Inferred |
Language | Haskell2010 |
This module exposes combinators designed to work with registers. These are small pieces of state
that are carried through the parsing process. They can be used, for example, to perform indentation
sensitive parsing. In fact, they are a flexible replacement for the monadic combinators, in conjunction
with the Parsley.Selective combinators. In particular, the bind
combinator implements a limited form
of the (>>=)
operation, where the structure of the resulting parser will still be statically
determinable. Registers paired with Parsley.Selective combinators are Turing-Compete.
Since: 0.1.0.0
Synopsis
- data Reg r a
- newRegister :: Parser a -> (forall r. Reg r a -> Parser b) -> Parser b
- get :: Reg r a -> Parser a
- put :: Reg r a -> Parser a -> Parser ()
- newRegister_ :: ParserOps rep => rep a -> (forall r. Reg r a -> Parser b) -> Parser b
- put_ :: ParserOps rep => Reg r a -> rep a -> Parser ()
- gets :: Reg r a -> Parser (a -> b) -> Parser b
- gets_ :: ParserOps rep => Reg r a -> rep (a -> b) -> Parser b
- modify :: Reg r a -> Parser (a -> a) -> Parser ()
- modify_ :: ParserOps rep => Reg r a -> rep (a -> a) -> Parser ()
- move :: Reg r1 a -> Reg r2 a -> Parser ()
- swap :: Reg r1 a -> Reg r2 a -> Parser ()
- local :: Reg r a -> Parser a -> Parser b -> Parser b
- local_ :: ParserOps rep => Reg r a -> rep a -> Parser b -> Parser b
- localModify :: Reg r a -> Parser (a -> a) -> Parser b -> Parser b
- localModify_ :: ParserOps rep => Reg r a -> rep (a -> a) -> Parser b -> Parser b
- bind :: Parser a -> (Parser a -> Parser b) -> Parser b
- rollback :: Reg r a -> Parser b -> Parser b
- for :: Parser a -> Parser (a -> Bool) -> Parser (a -> a) -> Parser () -> Parser ()
Documentation
This is an opaque representation of a parsing register. It cannot be manipulated as a user, and the
type parameter r
is used to ensure that it cannot leak out of the scope it has been created in.
It is the abstracted representation of a runtime storage location.
Since: parsley-core-0.1.0.0
:: Parser a | Parser with which to initialise the register |
-> (forall r. Reg r a -> Parser b) | Used to generate the second parser to execute |
-> Parser b |
Creates a new register initialised with the value obtained from parsing the first argument. This register is provided to the second argument, a function that generates a parser depending on operations derived from the register. This parser is then performed.
Note: The rank-2 type here serves a similar purpose to that in the ST
monad. It prevents the
register from leaking outside of the scope of the function, safely encapsulating the stateful
effect of the register.
Since: 0.1.0.0
get :: Reg r a -> Parser a Source #
Fetches a value from a register and returns it as its result.
Since: 0.1.0.0
put :: Reg r a -> Parser a -> Parser () Source #
Puts the result of the given parser into the given register. The old value in the register will be lost.
Since: 0.1.0.0
newRegister_ :: ParserOps rep => rep a -> (forall r. Reg r a -> Parser b) -> Parser b Source #
Like newRegister
, except the initial value of the register is seeded from a pure value as opposed
to the result of a parser.
Since: 0.1.0.0
put_ :: ParserOps rep => Reg r a -> rep a -> Parser () Source #
Like put
, except the new value of the register is a pure value as opposed to the result of a parser.
Since: 0.1.0.0
gets :: Reg r a -> Parser (a -> b) -> Parser b Source #
gets reg p
first parses p
to get as a result, function f
. Then, taking into account any changes
made during p
, the value is fetched from reg
and applied to f
.
Since: 0.1.0.0
gets_ :: ParserOps rep => Reg r a -> rep (a -> b) -> Parser b Source #
Like gets
, except the adapter function is a pure argument as opposed to the result of a parser.
Since: 0.1.0.0
modify :: Reg r a -> Parser (a -> a) -> Parser () Source #
modify reg p
first parses p
to collect the function f
, then taking into account any changes
made during f
, the value in reg
is modified using the function f
and put back into it.
Since: 0.1.0.0
modify_ :: ParserOps rep => Reg r a -> rep (a -> a) -> Parser () Source #
Like modify
, except the modification function is a pure argument as opposed to the result of a parser.
Since: 0.1.0.0
move :: Reg r1 a -> Reg r2 a -> Parser () Source #
move dst src
takes the value stored in src
and additionally stores it into dst
.
Since: 0.1.0.0
swap :: Reg r1 a -> Reg r2 a -> Parser () Source #
This combinator will swap the values contained in two registers.
Since: 0.1.0.0
local :: Reg r a -> Parser a -> Parser b -> Parser b Source #
local reg p q
first parses p
and stores its value in reg
for the duration of parsing q
.
If q
succeeds, reg
will be restored to its original state before p
was parsed.
Since: 0.1.0.0
local_ :: ParserOps rep => Reg r a -> rep a -> Parser b -> Parser b Source #
local_ reg x p
stores x
in reg
for the duration of parsing p
.
If p
succeeds, reg
will be restored to its original state.
Since: 1.0.2.0
localModify :: Reg r a -> Parser (a -> a) -> Parser b -> Parser b Source #
localModify reg p q
first parses p
and reg
with its returned function for the duration of parsing q
.
If q
succeeds, reg
will be restored to its original state before p
was parsed.
Since: 1.0.2.0
localModify_ :: ParserOps rep => Reg r a -> rep (a -> a) -> Parser b -> Parser b Source #
localModify_ reg x p
modifes reg
using f
for the duration of parsing p
.
If p
succeeds, reg
will be restored to its original state.
Since: 1.0.2.0
bind :: Parser a -> (Parser a -> Parser b) -> Parser b Source #
This combinator uses registers to emulate a restricted form of (
: in a traditional monadic
setting, this would be considered to be the implementation:>>=
)
bind p f = p >>= f . pure
Essentially, the result of p
is available to be summoned purely as many times as needed. However,
it cannot be used to dynamically create structure: the selective combinators can be used to provide
that functionality partially.
Since: 0.1.0.0
rollback :: Reg r a -> Parser b -> Parser b Source #
rollback reg p
will perform p
and if it fails without consuming input, reg
will be restored
to its original state from before p
was parsed, and the combinator will fail. If p
succeeds
the state in reg
will not be restored to an old version.
Since: 0.1.0.0
for :: Parser a -> Parser (a -> Bool) -> Parser (a -> a) -> Parser () -> Parser () Source #
This combinator is like a traditional imperative-style for
-loop. Given for init cond step body
,
init
is first parsed to initialise a register called i
; the parser cond
is then performed to
check that the value in i
adheres to the predicate it returns; if so, then the body
is parsed,
step
modifies the state in i
, and then the process repeats from cond
again. When cond
returns
False
for the predicate applied to i
's state, the loop terminates gracefully. If any component
of this parser fails the loop will fail.
Since: 0.1.0.0