Back to index

texmacs  1.0.7.15
tree_modify.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tree_modify.cpp
00004 * DESCRIPTION: high level tree modification subroutines
00005 * COPYRIGHT  : (C) 2010  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "tree_modify.hpp"
00013 #include "drd_std.hpp"
00014 #include "path.hpp"
00015 
00016 extern tree the_et;
00017 
00018 /******************************************************************************
00019 * DRD-based correction of trees
00020 ******************************************************************************/
00021 
00022 void
00023 correct_concat_node (tree& t, int done) {
00024   //cout << "Correct " << t << ", " << done << "\n";
00025   int i, n= N(t);
00026   if (n == 0) {
00027     assign (t, "");
00028     return;
00029   }
00030   for (i=done; i<n; i++) {
00031     if (t[i] == "") {
00032       remove (t, i, 1);
00033       correct_concat_node (t, i);
00034       return;
00035     }
00036     if ((i<n-1) && is_atomic (t[i]) && is_atomic (t[i+1])) {
00037       join (t, i);
00038       correct_concat_node (t, i);
00039       return;
00040     }
00041     if (is_concat (t[i])) {
00042       insert_node (t, 0, CONCAT);
00043       split (t, 0, i);
00044       split (t, 1, 1);
00045       remove_node (t[1], 0);
00046       if (t[0] == tree (CONCAT)) remove (t, 0, 1);
00047       else join (t, 0);
00048       if (t[1] == tree (CONCAT)) remove (t, 1, 1);
00049       else join (t, 0);
00050       remove_node (t, 0);
00051       correct_concat_node (t, max (i-1, 0));
00052       return;
00053     }    
00054   }
00055 }
00056 
00057 void
00058 correct_node (tree& t) {
00059   // NOTE: this routine should only modify t and its descendants,
00060   // but not any ancestors
00061   if (is_compound (t)) {
00062     if (the_drd->contains (as_string (L(t))) &&
00063        !the_drd->correct_arity (L(t), N(t)))
00064       assign (t, "");
00065     if (is_concat (t))
00066       correct_concat_node (t, 0);
00067   }
00068 }
00069 
00070 void
00071 correct_downwards (tree& t) {
00072   if (is_compound (t))
00073     for (int i=0; i<N(t); i++)
00074       correct_downwards (t[i]);
00075   correct_node (t);
00076 }
00077 
00078 void
00079 correct_upwards (tree& t) {
00080   correct_node (t);
00081   path ip= obtain_ip (t);
00082   if (ip_attached (ip) && !is_nil (ip))
00083     correct_upwards (subtree (the_et, reverse (ip->next)));
00084 }