diff options
Diffstat (limited to 'grammar')
-rw-r--r-- | grammar/src/label.rs | 40 | ||||
-rw-r--r-- | grammar/src/lib.rs | 9 |
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? |