summaryrefslogtreecommitdiff
path: root/src/parse/parser.rs
diff options
context:
space:
mode:
authorMartin Haug <mhaug@live.de>2021-11-06 16:07:21 +0100
committerMartin Haug <mhaug@live.de>2021-11-06 16:07:21 +0100
commiteba7fc34effbec3bcc6d5c40d831b1e15af77c4d (patch)
tree5e44d0862637ce7bfeb090069f3ad2dce9017ab8 /src/parse/parser.rs
parent7016ab0d123ba06d0bbc6ed5001fa02fbd261bfa (diff)
Incremental-safety based approach
Diffstat (limited to 'src/parse/parser.rs')
-rw-r--r--src/parse/parser.rs24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/parse/parser.rs b/src/parse/parser.rs
index af8a7c5c..f391c473 100644
--- a/src/parse/parser.rs
+++ b/src/parse/parser.rs
@@ -21,6 +21,8 @@ pub struct Parser<'s> {
groups: Vec<GroupEntry>,
/// The children of the currently built node.
children: Vec<Green>,
+ /// Whether the last group was terminated.
+ last_group_terminated: bool,
}
impl<'s> Parser<'s> {
@@ -36,6 +38,7 @@ impl<'s> Parser<'s> {
current_start: 0,
groups: vec![],
children: vec![],
+ last_group_terminated: true,
}
}
@@ -44,6 +47,15 @@ impl<'s> Parser<'s> {
self.children
}
+ /// End the parsing process and return multiple children.
+ pub fn eject(self) -> Option<Vec<Green>> {
+ if self.eof() && self.group_success() {
+ Some(self.children)
+ } else {
+ None
+ }
+ }
+
/// Create a new marker.
pub fn marker(&mut self) -> Marker {
Marker(self.children.len())
@@ -190,6 +202,11 @@ impl<'s> Parser<'s> {
self.tokens.scanner().column(index)
}
+ /// Set the tokenizer's mode.
+ pub fn set_mode(&mut self, mode: TokenMode) {
+ self.tokens.set_mode(mode);
+ }
+
/// Continue parsing in a group.
///
/// When the end delimiter of the group is reached, all subsequent calls to
@@ -225,6 +242,7 @@ impl<'s> Parser<'s> {
let group = self.groups.pop().expect("no started group");
self.tokens.set_mode(group.prev_mode);
self.repeek();
+ self.last_group_terminated = true;
let mut rescan = self.tokens.mode() != group_mode;
@@ -243,6 +261,7 @@ impl<'s> Parser<'s> {
rescan = false;
} else if required {
self.push_error(format_eco!("expected {}", end));
+ self.last_group_terminated = false;
}
}
@@ -260,6 +279,11 @@ impl<'s> Parser<'s> {
}
}
+ /// Check if the group processing was successfully terminated.
+ pub fn group_success(&self) -> bool {
+ self.last_group_terminated && self.groups.is_empty()
+ }
+
/// Low-level bump that consumes exactly one token without special trivia
/// handling.
fn bump(&mut self) {