From f28155105134b90fd86049c65478d307e0d8dbbc Mon Sep 17 00:00:00 2001 From: JSDurand Date: Sat, 28 Jan 2023 10:17:24 +0800 Subject: a prototype of an item derivation forest It seems to be complete now, but still awaits more tests to see where the errors are, which should be plenty, haha. --- grammar/src/label.rs | 75 +++++++++++++++++++++++++++++++--------------------- grammar/src/lib.rs | 3 +++ 2 files changed, 48 insertions(+), 30 deletions(-) (limited to 'grammar') diff --git a/grammar/src/label.rs b/grammar/src/label.rs index 05b0b1e..3f89d9a 100644 --- a/grammar/src/label.rs +++ b/grammar/src/label.rs @@ -12,15 +12,50 @@ pub enum GrammarLabelType { Rule(usize), } +// Some convenient conversions + +impl From for GrammarLabelType { + #[inline] + fn from(r: usize) -> Self { + Self::Rule(r) + } +} + +impl From for GrammarLabelType { + #[inline] + fn from(tnt: TNT) -> Self { + Self::TNT(tnt) + } +} + impl GrammarLabelType { /// Return the name of this label with the help of the associated /// grammar. + #[inline] pub fn name(&self, grammar: &Grammar) -> Result { match self { Self::TNT(tnt) => grammar.name_of_tnt(*tnt), Self::Rule(pos) => grammar.rule_pos_to_string(*pos), } } + + /// Return the contained TNT, if any. + #[inline] + pub fn tnt(&self) -> Option { + match self { + Self::TNT(tnt) => Some(*tnt), + Self::Rule(_) => None, + } + } + + /// Return the contained rule position, if any. + #[inline] + pub fn rule(&self) -> Option { + match self { + Self::TNT(_) => None, + Self::Rule(pos) => Some(*pos), + } + } } /// The label to be used in a forest. @@ -32,8 +67,6 @@ pub struct GrammarLabel { start: usize, /// The end in the input that this label correponds to. end: Option, - /// A node in the forest might be a packed node. - packed_p: bool, } impl core::fmt::Display for GrammarLabel { @@ -48,54 +81,44 @@ impl core::fmt::Display for GrammarLabel { impl GrammarLabel { /// Construct a new label. - pub fn new(label: GrammarLabelType, start: usize) -> Self { + #[inline] + pub fn new(label: impl Into, start: usize) -> Self { + let label = label.into(); let end = None; - let packed_p = false; - Self { - label, - start, - end, - packed_p, - } + Self { label, start, end } } /// Return the end in the input. + #[inline] pub fn end(&self) -> Option { self.end } /// Return the start in the input. + #[inline] pub fn start(&self) -> usize { self.start } /// Return the actual label. + #[inline] pub fn label(&self) -> GrammarLabelType { self.label } /// Update the end. + #[inline] pub fn set_end(&mut self, end: usize) { self.end = Some(end); } - /// Check whether the node is a packed node. - pub fn is_packed(&self) -> bool { - self.packed_p - } - - /// Update the packed status. - pub fn set_packed_p(&mut self, packed_p: bool) { - self.packed_p = packed_p; - } - /// Return a string description with the help of the associated /// grammar. pub fn to_string(&self, grammar: &Grammar) -> Result { // First calculate the length of the resulting string. - let mut num = 2 + 7 + 14 + 6; + let mut num = 16 + 6; num += self.label().name(grammar)?.len(); @@ -111,15 +134,7 @@ impl GrammarLabel { let mut s = String::with_capacity(num); - s.push_str("a "); - - if self.is_packed() { - s.push_str("packed "); - } else { - s.push_str("normal "); - } - - s.push_str("node labelled "); + s.push_str("a node labelled "); s.push_str(&self.label().name(grammar)?); diff --git a/grammar/src/lib.rs b/grammar/src/lib.rs index b29fc69..2c17a5f 100644 --- a/grammar/src/lib.rs +++ b/grammar/src/lib.rs @@ -486,6 +486,9 @@ impl Grammar { .contains(&None)) } + // FIXME: We shall use a label to query this information as well, + // probably. + /// Query the expansion information from the position `pos1` to /// the position `pos2` . #[inline] -- cgit v1.2.3-18-g5258