summaryrefslogtreecommitdiff
path: root/grammar
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2023-02-12 12:07:34 +0800
committerJSDurand <mmemmew@gmail.com>2023-02-12 12:07:34 +0800
commit987c84f3454c687cca0efe0d471fcf00e052ecab (patch)
tree04b9cf073a12adfb5d07ae308c3809e88cf4ebd2 /grammar
parent265ff8f87dc7392fdf701f811eb2bf54d7bc6678 (diff)
Added the functionality of split or clone.
I need more than the ability to clone nodes: I also need to split the nodes. Now this seems to be correctly added.
Diffstat (limited to 'grammar')
-rw-r--r--grammar/src/label.rs40
-rw-r--r--grammar/src/lib.rs9
2 files changed, 44 insertions, 5 deletions
diff --git a/grammar/src/label.rs b/grammar/src/label.rs
index 3f89d9a..058baaf 100644
--- a/grammar/src/label.rs
+++ b/grammar/src/label.rs
@@ -12,6 +12,15 @@ pub enum GrammarLabelType {
Rule(usize),
}
+impl Display for GrammarLabelType {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ match self {
+ Self::TNT(tnt) => write!(f, "{tnt}"),
+ Self::Rule(pos) => write!(f, "R({pos})"),
+ }
+ }
+}
+
// Some convenient conversions
impl From<usize> for GrammarLabelType {
@@ -71,11 +80,17 @@ pub struct GrammarLabel {
impl core::fmt::Display for GrammarLabel {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- // Simply displaying this without the help of a grammar is not
- // of much help, so we just use the debug method to cheat,
- // haha.
-
- write!(f, "{:?}", self)
+ write!(
+ f,
+ "{}, {}, {}",
+ self.label,
+ self.start,
+ if let Some(end) = self.end {
+ format!("{end}")
+ } else {
+ "ε".to_owned()
+ }
+ )
}
}
@@ -89,6 +104,15 @@ impl GrammarLabel {
Self { label, start, end }
}
+ /// Construct a new label with an ending position.
+ #[inline]
+ pub fn new_closed(label: impl Into<GrammarLabelType>, start: usize, end: usize) -> Self {
+ let label = label.into();
+ let end = Some(end);
+
+ Self { label, start, end }
+ }
+
/// Return the end in the input.
#[inline]
pub fn end(&self) -> Option<usize> {
@@ -113,6 +137,12 @@ impl GrammarLabel {
self.end = Some(end);
}
+ /// Remove the ending boundary.
+ #[inline]
+ pub fn open_end(&mut self) {
+ self.end = None;
+ }
+
/// Return a string description with the help of the associated
/// grammar.
pub fn to_string(&self, grammar: &Grammar) -> Result<String, Error> {
diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs
index a8e0fd7..ab0f693 100644
--- a/grammar/src/lib.rs
+++ b/grammar/src/lib.rs
@@ -538,6 +538,15 @@ impl Grammar {
Ok(self.reduction_map.get(&(pos1, pos2)).map(AsRef::as_ref))
}
+ /// Set the reduction information.
+ ///
+ /// This is used to set the reduction information for the virtual
+ /// nodes that are added after the left closure has been computed.
+ #[inline]
+ pub fn set_reduction(&mut self, pos1: usize, pos2: usize, info: Vec<usize>) {
+ self.reduction_map.insert((pos1, pos2), info);
+ }
+
// REVIEW: Do we have a better way to record expansion and
// reduction information than to compute the transitive closure?