pub struct ParserState<R: RuleType> { /* private fields */ }
Expand description
The complete state of a Parser
.
Implementations§
Source§impl<R: RuleType> ParserState<R>
impl<R: RuleType> ParserState<R>
Sourcepub fn new(input: Arc<str>) -> Box<Self>
pub fn new(input: Arc<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: Arc<str> = Arc::from("");
let state: Box<pest::ParserState<&str>> = pest::ParserState::new(input);
Sourcepub fn position(&self) -> &Position
pub fn position(&self) -> &Position
Returns a reference to the current Position
of the ParserState
.
§Examples
enum Rule {
ab
}
let input: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("a");
let pairs: Vec<_> = pest::state(input, |state| {
state.rule(Rule::a, |s| Ok(s))
}).unwrap().collect();
assert_eq!(pairs.len(), 1);
Examples found in repository?
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::paren, |s| {
s.sequence(|s| {
s.match_string("(")
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.lookahead(true, |s| s.match_string("("))
.and_then(|s| s.repeat(|s| paren(s)))
})
})
})
.and_then(|s| s.rule(Rule::paren_end, |s| s.match_string(")")))
})
})
}
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: Arc<str> = Arc::from("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);
Examples found in repository?
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn expr(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.sequence(|s| s.repeat(|s| paren(s)).and_then(|s| s.end_of_input()))
}
fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::paren, |s| {
s.sequence(|s| {
s.match_string("(")
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.lookahead(true, |s| s.match_string("("))
.and_then(|s| s.repeat(|s| paren(s)))
})
})
})
.and_then(|s| s.rule(Rule::paren_end, |s| s.match_string(")")))
})
})
}
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: Arc<str> = Arc::from("aab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
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.clone());
result = state.repeat(|s| {
s.match_string("b")
});
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 0);
Examples found in repository?
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn expr(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.sequence(|s| s.repeat(|s| paren(s)).and_then(|s| s.end_of_input()))
}
fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::paren, |s| {
s.sequence(|s| {
s.match_string("(")
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.lookahead(true, |s| s.match_string("("))
.and_then(|s| s.repeat(|s| paren(s)))
})
})
})
.and_then(|s| s.rule(Rule::paren_end, |s| s.match_string(")")))
})
})
}
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: Arc<str> = Arc::from("ab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
let result = state.optional(|s| {
s.match_string("ab")
});
assert!(result.is_ok());
state = pest::ParserState::new(input.clone());
let result = state.optional(|s| {
s.match_string("ac")
});
assert!(result.is_ok());
Examples found in repository?
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::paren, |s| {
s.sequence(|s| {
s.match_string("(")
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.lookahead(true, |s| s.match_string("("))
.and_then(|s| s.repeat(|s| paren(s)))
})
})
})
.and_then(|s| s.rule(Rule::paren_end, |s| s.match_string(")")))
})
})
}
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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("❤");
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: Arc<str> = Arc::from("ab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
let mut result = state.match_string("ab");
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
state = pest::ParserState::new(input.clone());
result = state.match_string("ac");
assert!(result.is_err());
assert_eq!(result.unwrap_err().position().pos(), 0);
Examples found in repository?
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::paren, |s| {
s.sequence(|s| {
s.match_string("(")
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.lookahead(true, |s| s.match_string("("))
.and_then(|s| s.repeat(|s| paren(s)))
})
})
})
.and_then(|s| s.rule(Rule::paren_end, |s| s.match_string(")")))
})
})
}
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: Arc<str> = Arc::from("ab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
let mut result = state.match_insensitive("AB");
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 2);
state = pest::ParserState::new(input.clone());
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.
§Examples
enum Rule {}
let input: Arc<str> = Arc::from("ab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
let mut result = state.match_range('a'..'z');
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
state = pest::ParserState::new(input.clone());
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: Arc<str> = Arc::from("ab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
let mut result = state.skip(1);
assert!(result.is_ok());
assert_eq!(result.unwrap().position().pos(), 1);
state = pest::ParserState::new(input.clone());
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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("ab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
let mut result = state.start_of_input();
assert!(result.is_ok());
state = pest::ParserState::new(input.clone());
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: Arc<str> = Arc::from("ab");
let mut state: Box<pest::ParserState<Rule>> = pest::ParserState::new(input.clone());
let mut result = state.end_of_input();
assert!(result.is_err());
state = pest::ParserState::new(input.clone());
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: Arc<str> = Arc::from("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);
Examples found in repository?
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
fn paren(state: Box<ParserState<Rule>>) -> ParseResult<Box<ParserState<Rule>>> {
state.rule(Rule::paren, |s| {
s.sequence(|s| {
s.match_string("(")
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.lookahead(true, |s| s.match_string("("))
.and_then(|s| s.repeat(|s| paren(s)))
})
})
})
.and_then(|s| s.rule(Rule::paren_end, |s| s.match_string(")")))
})
})
}
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
.
§Examples
enum Rule {
a
}
let input: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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
enum Rule {}
let input: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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: Arc<str> = Arc::from("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());