Back to index

texmacs  1.0.7.15
packrat_serializer.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : packrat_serializer.cpp
00004 * DESCRIPTION: serializing trees as strings
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 "packrat_parser.hpp"
00013 #include "analyze.hpp"
00014 #include "drd_std.hpp"
00015 
00016 /******************************************************************************
00017 * Useful subroutines
00018 ******************************************************************************/
00019 
00020 static path
00021 as_path (tree t) {
00022   ASSERT (is_tuple (t), "invalid path");
00023   path p;
00024   int i, n= N(t);
00025   for (i=n-1; i>=0; i--)
00026     p= path (as_int (t[i]), p);
00027   return p;
00028 }
00029 
00030 /******************************************************************************
00031 * Serialization
00032 ******************************************************************************/
00033 
00034 void
00035 packrat_parser_rep::serialize_compound (tree t, path p) {
00036   tree r= the_drd->get_syntax (t, p);
00037   if (r != UNINIT)
00038     serialize (r, path (-1));
00039   else if (is_func (t, QUASI, 2)) {
00040     tree tt= t[0];
00041     path pp= as_path (t[1]);
00042     serialize (tt, pp);
00043   }
00044   else {
00045     current_string << "<\\" << as_string (L(t)) << ">";
00046     for (int i=0; i<N(t); i++) {
00047       if (i != 0) current_string << "<|>";
00048       serialize (t[i], p * i);
00049     }
00050     current_string << "</>";
00051   }
00052 }
00053 
00054 void
00055 packrat_parser_rep::serialize (tree t, path p) {
00056   if (is_nil (p) || p->item != -1)
00057     current_start (p)= N(current_string);
00058   if (is_atomic (t)) {
00059     int begin= N(current_string);
00060     int pos=0;
00061     string s= t->label;
00062     while (true) {  
00063       if (N(current_string) != begin + pos)
00064         if (is_nil (p) || p->item != -1) {
00065           //cout << p * pos << " <-> " << N(current_string) << LF;
00066           //cout << "  " << s (0, pos) << LF;
00067           //cout << "  " << current_string (begin, N(current_string)) << LF;
00068           current_path_pos (p * pos)= N(current_string);
00069           current_pos_path (N(current_string))= p * pos;
00070         }
00071       if (pos >= N(s)) break;
00072       int start= pos;
00073       tm_char_forwards (s, pos);
00074       if (pos == start+1)
00075        current_string << s[start];
00076       else {
00077        string ss= s (start, pos);
00078         tree r= the_drd->get_syntax (ss);
00079         //if (r != UNINIT) cout << "Rewrite " << ss << " -> " << r << "\n";
00080         if (r == UNINIT) current_string << ss;
00081         else serialize (r, path (-1));
00082       }
00083     }
00084   }
00085   else switch (L(t)) {
00086     case RAW_DATA:
00087       current_string << "<\\rawdata></>";
00088       break;
00089     case DOCUMENT:
00090     case PARA:
00091       for (int i=0; i<N(t); i++) {
00092         serialize (t[i], p * i);
00093         current_string << "\n";
00094       }
00095       break;
00096     case SURROUND:
00097       serialize (t[0], p * 0);
00098       serialize (t[2], p * 2);
00099       serialize (t[1], p * 1);
00100       break;
00101     case CONCAT:
00102       for (int i=0; i<N(t); i++)
00103         serialize (t[i], p * i);
00104       break;
00105     case RIGID:
00106       serialize (t[0], p * 0);
00107       break;
00108     case HIDDEN:
00109       break;
00110     case FREEZE:
00111     case UNFREEZE:
00112       serialize (t[0], p * 0);
00113       break;
00114     case HSPACE:
00115     case VAR_VSPACE:
00116     case VSPACE:
00117     case SPACE:
00118     case HTAB:
00119       break;
00120     case MOVE:
00121     case SHIFT:
00122     case RESIZE:
00123     case CLIPPED:
00124       serialize (t[0], p * 0);
00125       break;
00126 
00127     case WITH_LIMITS:
00128     case LINE_BREAK:
00129     case NEW_LINE:
00130     case NEXT_LINE:
00131     case NO_BREAK:
00132     case YES_INDENT:
00133     case NO_INDENT:
00134     case VAR_YES_INDENT:
00135     case VAR_NO_INDENT:
00136     case VAR_PAGE_BREAK:
00137     case PAGE_BREAK:
00138     case VAR_NO_PAGE_BREAK:
00139     case NO_PAGE_BREAK:
00140     case VAR_NEW_PAGE:
00141     case NEW_PAGE:
00142     case VAR_NEW_DPAGE:
00143     case NEW_DPAGE:
00144       break;
00145 
00146     case SYNTAX:
00147       serialize (t[1], path (-1));
00148       break;
00149     case TFORMAT:
00150     case TWITH:
00151     case CWITH:
00152     case CELL:
00153       serialize (t[N(t)-1], p * (N(t)-1));
00154       break;
00155 
00156     case WITH:
00157       if (t[0] == "mode" && t[1] != "math");
00158       else serialize (t[N(t)-1], p * (N(t)-1));
00159       break;
00160     case VALUE: {
00161       tree r= the_drd->get_syntax (t);
00162       //if (r != UNINIT) cout << "Rewrite " << t << " -> " << r << "\n";
00163       if (r != UNINIT) serialize (r, path (-1));
00164       else serialize_compound (t, p);
00165       break;
00166     }
00167 
00168     case STYLE_WITH:
00169     case VAR_STYLE_WITH:
00170     case LOCUS:
00171       serialize (t[N(t)-1], p * (N(t)-1));
00172       break;
00173     case ID:
00174     case HARD_ID:
00175     case LINK:
00176     case URL:
00177     case SCRIPT:
00178       break;
00179     case HLINK:
00180     case ACTION:
00181       serialize (t[0], p * 0);
00182       break;
00183     case SET_BINDING:
00184     case GET_BINDING:
00185     case LABEL:
00186     case REFERENCE:
00187     case PAGEREF:
00188     case WRITE:
00189       break;
00190 
00191     case SPECIFIC:
00192       serialize (t[1], p * 1);
00193       break;
00194     case FLAG:
00195       break;
00196 
00197     default:
00198       serialize_compound (t, p);
00199       break;
00200     }
00201   if (is_nil (p) || p->item != -1)
00202     current_end (p)= N(current_string);
00203 }