summaryrefslogtreecommitdiff
path: root/chain/src/item/default
diff options
context:
space:
mode:
Diffstat (limited to 'chain/src/item/default')
-rw-r--r--chain/src/item/default/extract.rs16
-rw-r--r--chain/src/item/default/mod.rs3
-rw-r--r--chain/src/item/default/splone.rs26
3 files changed, 41 insertions, 4 deletions
diff --git a/chain/src/item/default/extract.rs b/chain/src/item/default/extract.rs
index 96f5119..b99c541 100644
--- a/chain/src/item/default/extract.rs
+++ b/chain/src/item/default/extract.rs
@@ -188,11 +188,25 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
1 => {
let child = *roots_stack.first().unwrap();
- builder.add_vertex(self.vertex_label(child)?.ok_or(Error::NodeNoLabel(child))?);
+ // Make this a plain node.
+ //
+ // This situation will be handled properly in
+ // later codes.
+
+ let plain_child_label = ForestLabel::new(
+ self.vertex_label(child)?
+ .ok_or(Error::NodeNoLabel(child))?
+ .label(),
+ ForestLabelType::Plain,
+ );
+
+ builder.add_vertex(plain_child_label);
}
_ => {
let builder_root = builder.add_vertex(original_root_label);
+ // The clone indices have to be preserved so that
+ // we can track those nodes later.
for child in roots_stack.iter().copied() {
let child_node = builder.add_vertex(
self.vertex_label(child)?.ok_or(Error::NodeNoLabel(child))?,
diff --git a/chain/src/item/default/mod.rs b/chain/src/item/default/mod.rs
index 0781dd2..7369c6f 100644
--- a/chain/src/item/default/mod.rs
+++ b/chain/src/item/default/mod.rs
@@ -1,3 +1,4 @@
+#![debugger_visualizer(gdb_script_file = "printer.py")]
//! This module provides a default implementation of iten derivation
//! forest.
@@ -72,6 +73,8 @@ impl From<ForestLabelError> for Error {
}
}
+// FIXME: Provide a better Debug implementation.
+
/// A default implementation of forest.
#[derive(Debug, Clone, Graph)]
pub struct DefaultForest<T: GraphLabel> {
diff --git a/chain/src/item/default/splone.rs b/chain/src/item/default/splone.rs
index 09fca0b..c73bd9f 100644
--- a/chain/src/item/default/splone.rs
+++ b/chain/src/item/default/splone.rs
@@ -290,7 +290,8 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
///
/// 2. Preserve the old children as specified by `edge_index + 1`.
///
- /// 3. For each parent, clone the parent. Replace the original
+ /// 3. If the new node is closed or if the new node is not cloned,
+ /// then for each parent, clone the parent. Replace the original
/// child of the parent, which pointed to the old node, by this
/// new node. Other children are inherited from the old parent.
///
@@ -305,15 +306,16 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
completingp: bool,
) -> Result<usize, Error> {
let end = new_label.label().end();
+ let new_node_is_clone = new_label.clone_index().is_some();
let mut builder = PLGBuilderMut::from_graph_mut(&mut self.graph);
let new_node = builder.add_vertex(new_label);
- let new_packed = if new_label.clone_index().is_some() {
+ let new_packed = if new_node_is_clone {
let packed = builder
.query_label(ForestLabel::new(new_label.label(), ForestLabelType::Packed))
- .unwrap();
+ .unwrap_or_else(|| panic!("A cloned node {new_node} without packed nodes"));
builder.add_edge(packed, new_node, new_label)?;
@@ -328,6 +330,24 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
builder.add_edge(new_node, child, new_label)?;
}
+ // NOTE: If the label of the parent is closed while the node
+ // label is open ended, we need to use an opened parent
+ // instead.
+ //
+ // To be specific, we only need to split the parent if the new
+ // label is closed. This can be seen from the fact that this
+ // function only deals with the situation that the new label
+ // and the old label are different. In this situation, if the
+ // new label is closed, it means we are closing a node under
+ // an open node, and we need to clone that parent indeed. On
+ // the other hand, if we are opening a node under a closed
+ // node, that parent does not need to connect to this new
+ // node.
+
+ if end.is_none() && new_node_is_clone {
+ return Ok(new_node);
+ }
+
let parents: Vec<_> = {
if let Some(label) = self.vertex_label(node)? {
if label.clone_index().is_some() {