summaryrefslogtreecommitdiff
path: root/grammar
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2023-01-28 10:17:24 +0800
committerJSDurand <mmemmew@gmail.com>2023-01-28 10:22:57 +0800
commitf28155105134b90fd86049c65478d307e0d8dbbc (patch)
tree72b3b4872d5dba89413eca70bcaae9e421def7ee /grammar
parente8ea01319b3a9032a3f4f69f65e9ca96562b87b9 (diff)
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.
Diffstat (limited to 'grammar')
-rw-r--r--grammar/src/label.rs75
-rw-r--r--grammar/src/lib.rs3
2 files changed, 48 insertions, 30 deletions
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<usize> for GrammarLabelType {
+ #[inline]
+ fn from(r: usize) -> Self {
+ Self::Rule(r)
+ }
+}
+
+impl From<TNT> 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<String, Error> {
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<TNT> {
+ match self {
+ Self::TNT(tnt) => Some(*tnt),
+ Self::Rule(_) => None,
+ }
+ }
+
+ /// Return the contained rule position, if any.
+ #[inline]
+ pub fn rule(&self) -> Option<usize> {
+ 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<usize>,
- /// 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<GrammarLabelType>, 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<usize> {
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<String, Error> {
// 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]