License | BSD-3-Clause |
---|---|
Maintainer | Jamie Willis, Gigaparsec Maintainers |
Stability | stable |
Safe Haskell | Safe |
Language | Haskell2010 |
This module contains all the functionality and operations for using and manipulating references.
These often have a role in performing context-sensitive parsing tasks, where a Turing-powerful system is required. Whilst a generic state monad is capable of such parsing, it is much less efficient than the use of references, though slightly more flexible.
Synopsis
- data Ref r a
- make :: a -> (forall r. Ref r a -> Parsec b) -> Parsec b
- unsafeMake :: (forall r. Ref r a -> Parsec b) -> Parsec b
- get :: Ref r a -> Parsec a
- gets :: Ref r a -> (a -> b) -> Parsec b
- set :: Ref r a -> a -> Parsec ()
- sets :: Ref r b -> (a -> b) -> Parsec a -> Parsec ()
- update :: Ref r a -> (a -> a) -> Parsec ()
- updateDuring :: Ref r a -> (a -> a) -> Parsec b -> Parsec b
- setDuring :: Ref r a -> a -> Parsec b -> Parsec b
- rollback :: Ref r a -> Parsec b -> Parsec b
- forP :: Parsec a -> Parsec (a -> Bool) -> Parsec (a -> a) -> Parsec b -> Parsec [b]
- forP' :: Parsec a -> Parsec (a -> Bool) -> Parsec (a -> a) -> (a -> Parsec b) -> Parsec [b]
- forP_ :: Parsec a -> Parsec (a -> Bool) -> Parsec (a -> a) -> Parsec b -> Parsec ()
- forP'_ :: Parsec a -> Parsec (a -> Bool) -> Parsec (a -> a) -> (a -> Parsec b) -> Parsec ()
Documentation
References
The Ref type describes pieces of state that are threaded through a parser. The creation and basic combinators of references are also found here.
:: a |
|
-> (forall r. Ref r a -> Parsec b) |
|
-> Parsec b | a parser that produces a |
Run a parser f
parameterised by a reference with initial value x
.
The function f
effectively defines a parser that has access to a new reference of type a
, whose initial value is x
.
The parameterization of Ref
by r
ensures that the reference cannot escape the scope of the inner parser defined by f
.
unsafeMake :: (forall r. Ref r a -> Parsec b) -> Parsec b Source #
Run a parser f
parameterised by a reference, which is uninitialised.
The function f
effectively defines a parser that has access to a new uninitialised reference of type a
.
This reference must be initialised by f
before it is read from, otherwise an error
will be thrown.
The parameterization of Ref
by r
ensures that the reference cannot escape the scope of the inner parser defined by f
.
This function is unsafe, meaning it will throw a GHC error
if the reference is read before it is set.
get :: Ref r a -> Parsec a Source #
Return the current value of a reference.
Given a reference ref
, this produces a parser that simply returns the current value of ref
.
This parser consumes no input and always succeeds.
:: Ref r a |
|
-> (a -> b) |
|
-> Parsec b | a parser returning the result of |
Get a specific component of the reference, using a projection function supplied.
Given a reference ref
, and a function f
, this function produces a parser which returns the
value of applying f
to the current value of ref
.
This parser consumes no input and always succeeds.
set :: Ref r a -> a -> Parsec () Source #
Replace the value of the given reference.
Given a reference ref
, and a value x
, this function replaces the current value of ref
with x
.
This produces a parser which changes the value of ref
during any subsequent parsing.
This parser consumes no input and always succeeds.
:: Ref r b |
|
-> (a -> b) |
|
-> Parsec a |
|
-> Parsec () | a parser which runs |
Replace the value of the reference by the result of applying a function to the result of the given parser.
Given a parser p
, a function f
, and reference ref
:
run the parser p
, which produces a result of type a
;
then replace the value of ref
by that of f
applied to the result of p
.
This produces a parser which changes the value of ref
during any subsequent parsing.
This parser consumes input and fails if and only if the given parser p
does also.
update :: Ref r a -> (a -> a) -> Parsec () Source #
Set the new value of the reference to be the result of applying a function to the old value.
Given a function f
and reference ref
; the current value of ref
is replaced by that of applying f
to this value.
This parser consumes no input and always succeeds.
:: Ref r a |
|
-> (a -> a) |
|
-> Parsec b |
|
-> Parsec b | a parser which runs |
Run the given parser p
with a modified value of the reference, and then reset this value if p
succeeds.
Behaves like update
, except the scope of the update of the reference ref
is limited just to the given parser p
,
assuming that p
succeeds.
If the parser p
fails, then the value of the reference ref
is not reset to its original value.
In summary, this parser unconditionally modifies the value of ref
, and resets the value of ref
only when p
succeeds.
This parser consumes input and fails if and only if the given parser p
does also.
:: Ref r a |
|
-> a |
|
-> Parsec b |
|
-> Parsec b | a parser which runs |
Run the given parser p
with a new value of the reference, and then reset this value if p
succeeds.
Behaves like updateDuring
, except the value of the reference is simply replaced by the given value x
.
If the parser p
fails, then the value of the reference ref
is not reset to its original value.
This parser consumes input and fails if and only if the given parser p
does also.
:: Ref r a |
|
-> Parsec b |
|
-> Parsec b | a parser that runs |
Run a parser, and if it fails without consuming input, undo its modifications to the given reference.
This parser consumes input only if p
does also; it fails if and only if p
fails having consumed input.
Reference-Based Combinators
The following are variants of Text.Gigaparsec.Combinator combinators, made much more efficient using references.
:: Parsec a |
|
-> Parsec (a -> Bool) |
|
-> Parsec (a -> a) |
|
-> Parsec b |
|
-> Parsec [b] | a parser that repeatedly parses |
Repeatedly execute a parser in a loop until the condition passes.
behaves much like a traditional for loop using forP
ini cond step bodyini
, cond
, step
,
and body
as parsers which control the loop itself.
In pseudocode, this would be equivalent to:
results = [] for (i: a := ini ; not (cond i) ; i := step i ) { r <- body results.append r } return results
:: Parsec a |
|
-> Parsec (a -> Bool) |
|
-> Parsec (a -> a) |
|
-> (a -> Parsec b) |
|
-> Parsec [b] | a parser that repeatedly parses |
Repeatedly execute a parser in a loop until the condition passes.
forP'
is similar to forP
, except the body
of the loop is able to access the value of the iterator.
In pseudocode, this would be equivalent to:
results = [] for (i: a := ini ; not (cond i) ; i := step i ) { r <- body i results.append r } return results
:: Parsec a |
|
-> Parsec (a -> Bool) |
|
-> Parsec (a -> a) |
|
-> Parsec b |
|
-> Parsec () | a parser that repeatedly parses |
:: Parsec a |
|
-> Parsec (a -> Bool) |
|
-> Parsec (a -> a) |
|
-> (a -> Parsec b) |
|
-> Parsec () | a parser that repeatedly parses |