-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Detect and auto complete "nullable" productions (#113)
* improve `AppendOnlyVec` to use it in more places * separate "term matching" from "state" * rename `State` to `Traversal` because it was confusing me (this may be controversial! please let's talk about it!) * detect "nullable" productions, and autocomplete them during parsing * added "tracing" !
- Loading branch information
1 parent
b0a53db
commit 64073eb
Showing
13 changed files
with
1,282 additions
and
686 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,3 +5,5 @@ filter: covered | |
output-type: lcov | ||
output-path: ./lcov.info | ||
prefix-dir: /home/user/build/ | ||
ignore: | ||
- "../*" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/// Create a new id type for an [`AppendOnlyVec`], which will be a wrapped [`usize`]. | ||
/// Example usage: `append_only_vec_id!(pub(crate) ProductionId)`; | ||
macro_rules! append_only_vec_id { | ||
($visible:vis $id:ident) => { | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
$visible struct $id(usize); | ||
|
||
impl From<usize> for $id { | ||
fn from(id: usize) -> Self { | ||
Self(id) | ||
} | ||
} | ||
|
||
impl From<$id> for usize { | ||
fn from(id: $id) -> Self { | ||
id.0 | ||
} | ||
} | ||
}; | ||
} | ||
|
||
pub(crate) use append_only_vec_id; | ||
|
||
/// Vector type which does *not* allow item removal during lifetime. | ||
/// Useful for data structures with complex, shared ownership, such as graphs. | ||
#[derive(Debug, Clone)] | ||
pub(crate) struct AppendOnlyVec<T, I> { | ||
vec: Vec<T>, | ||
id_type: std::marker::PhantomData<I>, | ||
} | ||
|
||
impl<T, I> AppendOnlyVec<T, I> | ||
where | ||
I: From<usize> + Into<usize>, | ||
{ | ||
pub fn new() -> Self { | ||
Self::default() | ||
} | ||
pub fn len(&self) -> usize { | ||
self.vec.len() | ||
} | ||
fn next_id(&self) -> I { | ||
I::from(self.len()) | ||
} | ||
pub fn push(&mut self, item: T) -> I { | ||
let id = self.next_id(); | ||
self.vec.push(item); | ||
id | ||
} | ||
pub fn push_with_id<F>(&mut self, build: F) -> &T | ||
where | ||
F: Fn(I) -> T, | ||
{ | ||
let id = self.next_id(); | ||
let item = build(id); | ||
let id = self.push(item); | ||
self.get(id).expect("failed to get appended item") | ||
} | ||
pub fn get(&self, id: I) -> Option<&T> { | ||
self.vec.get::<usize>(id.into()) | ||
} | ||
pub fn iter(&self) -> impl Iterator<Item = &T> { | ||
self.vec.iter() | ||
} | ||
} | ||
|
||
impl<T, K> Default for AppendOnlyVec<T, K> { | ||
fn default() -> Self { | ||
Self::from(vec![]) | ||
} | ||
} | ||
|
||
impl<T, K> From<Vec<T>> for AppendOnlyVec<T, K> { | ||
fn from(vec: Vec<T>) -> Self { | ||
Self { | ||
vec, | ||
id_type: std::marker::PhantomData, | ||
} | ||
} | ||
} | ||
|
||
impl<T, K> IntoIterator for AppendOnlyVec<T, K> { | ||
type Item = <Vec<T> as IntoIterator>::Item; | ||
type IntoIter = <Vec<T> as IntoIterator>::IntoIter; | ||
fn into_iter(self) -> Self::IntoIter { | ||
self.vec.into_iter() | ||
} | ||
} | ||
|
||
impl<'a, T, K> IntoIterator for &'a AppendOnlyVec<T, K> { | ||
type Item = &'a T; | ||
type IntoIter = std::slice::Iter<'a, T>; | ||
fn into_iter(self) -> Self::IntoIter { | ||
self.vec.iter() | ||
} | ||
} | ||
|
||
impl<'a, T, K> IntoIterator for &'a mut AppendOnlyVec<T, K> { | ||
type Item = &'a mut T; | ||
type IntoIter = std::slice::IterMut<'a, T>; | ||
fn into_iter(self) -> Self::IntoIter { | ||
self.vec.iter_mut() | ||
} | ||
} |
Oops, something went wrong.