pub struct ParserState<'i, R: RuleType> { /* private fields */ }
Expand description
The complete state of a Parser
.
Implementations§
Source§impl<'i, R: RuleType> ParserState<'i, R>
impl<'i, R: RuleType> ParserState<'i, R>
Sourcepub fn new(input: &'i str) -> Box<Self>
pub fn new(input: &'i str) -> Box<Self>
Allocates a fresh ParserState
object to the heap and returns the owned Box
. This Box
will be passed from closure to closure based on the needs of the specified Parser
.
§Examples
let input = "";
let state: Box<pest::ParserState<&str>> = pest::ParserState::new(input);
Sourcepub fn position(&self) -> &Position<'i>
pub fn position(&self) -> &Position<'i>
Returns a reference to the current Position
of the ParserState
.
§Examples
enum Rule {
ab
}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let position = state.position();
assert_eq!(position.pos(), 0);
Sourcepub fn atomicity(&self) -> Atomicity
pub fn atomicity(&self) -> Atomicity
Returns the current atomicity of the ParserState
.
§Examples
enum Rule {
ab
}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let atomicity = state.atomicity();
assert_eq!(atomicity, Atomicity::NonAtomic);
Sourcepub fn rule<F>(self: Box<Self>, rule: R, f: F) -> ParseResult<Box<Self>>
pub fn rule<F>(self: Box<Self>, rule: R, f: F) -> ParseResult<Box<Self>>
Wrapper needed to generate tokens. This will associate the R
type rule to the closure
meant to match the rule.
§Examples
enum Rule {
a
}
let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
state.rule(Rule::a, |s| Ok(s))
}).unwrap().collect();
assert_eq!(pairs.len(), 1);
Sourcepub fn tag_node(self: Box<Self>, tag: &'i str) -> ParseResult<Box<Self>>
pub fn tag_node(self: Box<Self>, tag: &'i str) -> ParseResult<Box<Self>>
Tag current node
§Examples
Try to recognize the one specified in a set of characters
use pest::{state, ParseResult, ParserState, iterators::Pair};
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
character,
}
fn mark_c(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.sequence(|state| {
character(state)
.and_then(|state| character(state))
.and_then(|state| character(state))
.and_then(|state| state.tag_node("c"))
.and_then(|state| character(state))
})
}
fn character(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::character, |state| state.match_range('a'..'z'))
}
let input = "abcd";
let pairs = state(input, mark_c).unwrap();
// find all node tag as `c`
let find: Vec<Pair<Rule>> = pairs.filter(|s| s.as_node_tag() == Some("c")).collect();
assert_eq!(find[0].as_str(), "c")
Sourcepub fn sequence<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
pub fn sequence<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
Starts a sequence of transformations provided by f
from the Box<ParserState>
. Returns
the same Result
returned by f
in the case of an Ok
, or Err
with the current
Box<ParserState>
otherwise.
This method is useful to parse sequences that only match together which usually come in the
form of chained Result
s with
Result::and_then
.
§Examples
enum Rule {
a
}
let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
state.sequence(|s| {
s.rule(Rule::a, |s| Ok(s)).and_then(|s| {
s.match_string("b")
})
}).or_else(|s| {
Ok(s)
})
}).unwrap().collect();
assert_eq!(pairs.len(), 0);
Sourcepub fn repeat<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
pub fn repeat<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
Repeatedly applies the transformation provided by f
from the Box<ParserState>
. Returns
Ok
with the updated Box<ParserState>
returned by f
wrapped up in an Err
.
§Examples
enum Rule {
ab
}
let input = "aab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.repeat(|s| {
s.match_string("a")
});
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
state = pest::ParserState::new(input);
result = state.repeat(|s| {
s.match_string("b")
});
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 0);
Sourcepub fn optional<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
pub fn optional<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
Optionally applies the transformation provided by f
from the Box<ParserState>
. Returns
Ok
with the updated Box<ParserState>
returned by f
regardless of the Result
.
§Examples
enum Rule {
ab
}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let result = state.optional(|s| {
s.match_string("ab")
});
assert!(result.is_ok());
state = pest::ParserState::new(input);
let result = state.optional(|s| {
s.match_string("ac")
});
assert!(result.is_ok());
Sourcepub fn match_char_by<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
pub fn match_char_by<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
Attempts to match a single character based on a filter function. Returns Ok
with the
updated Box<ParserState>
if successful, or Err
with the updated Box<ParserState>
otherwise.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let result = state.match_char_by(|c| c.is_ascii());
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
let input = "❤";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let result = state.match_char_by(|c| c.is_ascii());
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
Sourcepub fn match_string(self: Box<Self>, string: &str) -> ParseResult<Box<Self>>
pub fn match_string(self: Box<Self>, string: &str) -> ParseResult<Box<Self>>
Attempts to match the given string. Returns Ok
with the updated Box<ParserState>
if
successful, or Err
with the updated Box<ParserState>
otherwise.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.match_string("ab");
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
state = pest::ParserState::new(input);
result = state.match_string("ac");
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
Sourcepub fn match_insensitive(
self: Box<Self>,
string: &str,
) -> ParseResult<Box<Self>>
pub fn match_insensitive( self: Box<Self>, string: &str, ) -> ParseResult<Box<Self>>
Attempts to case-insensitively match the given string. Returns Ok
with the updated
Box<ParserState>
if successful, or Err
with the updated Box<ParserState>
otherwise.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.match_insensitive("AB");
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
state = pest::ParserState::new(input);
result = state.match_insensitive("AC");
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
Sourcepub fn match_range(
self: Box<Self>,
range: Range<char>,
) -> ParseResult<Box<Self>>
pub fn match_range( self: Box<Self>, range: Range<char>, ) -> ParseResult<Box<Self>>
Attempts to match a single character from the given range. Returns Ok
with the updated
Box<ParserState>
if successful, or Err
with the updated Box<ParserState>
otherwise.
§Caution
The provided range
is interpreted as inclusive.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.match_range('a'..'z');
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
state = pest::ParserState::new(input);
result = state.match_range('A'..'Z');
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
Sourcepub fn skip(self: Box<Self>, n: usize) -> ParseResult<Box<Self>>
pub fn skip(self: Box<Self>, n: usize) -> ParseResult<Box<Self>>
Attempts to skip n
characters forward. Returns Ok
with the updated Box<ParserState>
if successful, or Err
with the updated Box<ParserState>
otherwise.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.skip(1);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
state = pest::ParserState::new(input);
result = state.skip(3);
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
Sourcepub fn skip_until(self: Box<Self>, strings: &[&str]) -> ParseResult<Box<Self>>
pub fn skip_until(self: Box<Self>, strings: &[&str]) -> ParseResult<Box<Self>>
Attempts to skip forward until one of the given strings is found. Returns Ok
with the
updated Box<ParserState>
whether or not one of the strings is found.
§Examples
enum Rule {}
let input = "abcd";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.skip_until(&["c", "d"]);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
Sourcepub fn start_of_input(self: Box<Self>) -> ParseResult<Box<Self>>
pub fn start_of_input(self: Box<Self>) -> ParseResult<Box<Self>>
Attempts to match the start of the input. Returns Ok
with the current Box<ParserState>
if the parser has not yet advanced, or Err
with the current Box<ParserState>
otherwise.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.start_of_input();
assert!(result.is_ok());
state = pest::ParserState::new(input);
state = state.match_string("ab").unwrap();
result = state.start_of_input();
assert!(result.is_err());
Sourcepub fn end_of_input(self: Box<Self>) -> ParseResult<Box<Self>>
pub fn end_of_input(self: Box<Self>) -> ParseResult<Box<Self>>
Attempts to match the end of the input. Returns Ok
with the current Box<ParserState>
if
there is no input remaining, or Err
with the current Box<ParserState>
otherwise.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.end_of_input();
assert!(result.is_err());
state = pest::ParserState::new(input);
state = state.match_string("ab").unwrap();
result = state.end_of_input();
assert!(result.is_ok());
Sourcepub fn lookahead<F>(
self: Box<Self>,
is_positive: bool,
f: F,
) -> ParseResult<Box<Self>>
pub fn lookahead<F>( self: Box<Self>, is_positive: bool, f: F, ) -> ParseResult<Box<Self>>
Starts a lookahead transformation provided by f
from the Box<ParserState>
. It returns
Ok
with the current Box<ParserState>
if f
also returns an Ok
, or Err
with the current
Box<ParserState>
otherwise. If is_positive
is false
, it swaps the Ok
and Err
together, negating the Result
.
§Examples
enum Rule {
a
}
let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
state.lookahead(true, |state| {
state.rule(Rule::a, |s| Ok(s))
})
}).unwrap().collect();
assert_eq!(pairs.len(), 0);
Sourcepub fn atomic<F>(
self: Box<Self>,
atomicity: Atomicity,
f: F,
) -> ParseResult<Box<Self>>
pub fn atomic<F>( self: Box<Self>, atomicity: Atomicity, f: F, ) -> ParseResult<Box<Self>>
Transformation which stops Token
s from being generated according to is_atomic
.
Used as wrapper over rule
(or even another atomic
) call.
§Examples
enum Rule {
a
}
let input = "a";
let pairs: Vec<_> = pest::state(input, |state| {
state.atomic(Atomicity::Atomic, |s| {
s.rule(Rule::a, |s| Ok(s))
})
}).unwrap().collect();
assert_eq!(pairs.len(), 0);
Sourcepub fn stack_push<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
pub fn stack_push<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
Evaluates the result of closure f
and pushes the span of the input consumed from before
f
is called to after f
is called to the stack. Returns Ok(Box<ParserState>)
if f
is
called successfully, or Err(Box<ParserState>)
otherwise.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a"));
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
Sourcepub fn stack_peek(self: Box<Self>) -> ParseResult<Box<Self>>
pub fn stack_peek(self: Box<Self>) -> ParseResult<Box<Self>>
Peeks the top of the stack and attempts to match the string. Returns Ok(Box<ParserState>)
if the string is matched successfully, or Err(Box<ParserState>)
otherwise.
§Examples
enum Rule {}
let input = "aa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(
|state| state.stack_peek()
);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
Sourcepub fn stack_pop(self: Box<Self>) -> ParseResult<Box<Self>>
pub fn stack_pop(self: Box<Self>) -> ParseResult<Box<Self>>
Pops the top of the stack and attempts to match the string. Returns Ok(Box<ParserState>)
if the string is matched successfully, or Err(Box<ParserState>)
otherwise.
§Examples
enum Rule {}
let input = "aa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(
|state| state.stack_pop()
);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
Sourcepub fn stack_match_peek_slice(
self: Box<Self>,
start: i32,
end: Option<i32>,
match_dir: MatchDir,
) -> ParseResult<Box<Self>>
pub fn stack_match_peek_slice( self: Box<Self>, start: i32, end: Option<i32>, match_dir: MatchDir, ) -> ParseResult<Box<Self>>
Matches part of the state of the stack.
§Examples
enum Rule {}
let input = "abcd cd cb";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state
.stack_push(|state| state.match_string("a"))
.and_then(|state| state.stack_push(|state| state.match_string("b")))
.and_then(|state| state.stack_push(|state| state.match_string("c")))
.and_then(|state| state.stack_push(|state| state.match_string("d")))
.and_then(|state| state.match_string(" "))
.and_then(|state| state.stack_match_peek_slice(2, None, MatchDir::BottomToTop))
.and_then(|state| state.match_string(" "))
.and_then(|state| state.stack_match_peek_slice(1, Some(-1), MatchDir::TopToBottom));
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 10);
Sourcepub fn stack_match_peek(self: Box<Self>) -> ParseResult<Box<Self>>
pub fn stack_match_peek(self: Box<Self>) -> ParseResult<Box<Self>>
Matches the full state of the stack.
§Examples
enum Rule {}
let input = "abba";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state
.stack_push(|state| state.match_string("a"))
.and_then(|state| { state.stack_push(|state| state.match_string("b")) })
.and_then(|state| state.stack_match_peek());
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 4);
Sourcepub fn stack_match_pop(self: Box<Self>) -> ParseResult<Box<Self>>
pub fn stack_match_pop(self: Box<Self>) -> ParseResult<Box<Self>>
Matches the full state of the stack. This method will clear the stack as it evaluates.
§Examples
/// # use pest;
enum Rule {}
let input = "aaaa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(|state| {
state.stack_push(|state| state.match_string("a"))
}).and_then(|state| state.stack_match_peek());
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 4);
Sourcepub fn stack_drop(self: Box<Self>) -> ParseResult<Box<Self>>
pub fn stack_drop(self: Box<Self>) -> ParseResult<Box<Self>>
Drops the top of the stack. Returns Ok(Box<ParserState>)
if there was a value to drop, or
Err(Box<ParserState>)
otherwise.
§Examples
enum Rule {}
let input = "aa";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.stack_push(|state| state.match_string("a")).and_then(
|state| state.stack_drop()
);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
Sourcepub fn restore_on_err<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
pub fn restore_on_err<F>(self: Box<Self>, f: F) -> ParseResult<Box<Self>>
Restores the original state of the ParserState
when f
returns an Err
. Currently,
this method only restores the stack.
§Examples
enum Rule {}
let input = "ab";
let mut state: Box<pest::ParserState<'_, Rule>> = pest::ParserState::new(input);
let mut result = state.restore_on_err(|state| state.stack_push(|state|
state.match_string("a")).and_then(|state| state.match_string("a"))
);
assert!(result.is_err());
// Since the the rule doesn't match, the "a" pushed to the stack will be removed.
let catch_panic = std::panic::catch_unwind(|| result.unwrap_err().stack_pop());
assert!(catch_panic.is_err());