source: tools/prettyprinter/filter.cc @ fda8168

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since fda8168 was fda8168, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

format tool for pretty printing grammar

  • Property mode set to 100644
File size: 7.6 KB
Line 
1//                              -*- Mode: C++ -*-
2//
3// Pretty Printer, Copyright (C) Peter A. Buhr 2002
4//
5// filter.cc --
6//
7// Author           : Peter A. Buhr
8// Created On       : Tue Apr  9 22:33:44 2002
9// Last Modified By : Peter A. Buhr
10// Last Modified On : Tue Dec 17 11:25:50 2002
11// Update Count     : 60
12//
13
14#include "filter.h"
15#include "yacc.tab.h"
16
17
18void (*filter)( Token *tree ) = 0;
19
20
21void freeTree( Token *tree ) {                          // postfix tree traversal
22    if ( tree == NULL ) return;
23    if ( tree->down != NULL ) freeTree( tree->down );
24    if ( tree->left != NULL ) freeTree( tree->left );
25    //cerr << "free token: \"" << tree->getText() << "\" : " << tree->getKind() << endl;
26    delete tree;
27} // freeTree
28
29
30void Identity( Token *tree ) {                          // prefix tree traversal
31    if ( tree == NULL ) return;
32    // print only the terminals
33    if ( tree->isTerminal() ) cout << tree->getWS() << tree->getText();
34    if ( tree->down != NULL ) Identity( tree->down );
35    if ( tree->left != NULL ) Identity( tree->left );
36} // Identity
37
38
39static void Parse_Tree1( Token *tree, int indent ) {    // prefix tree traversal
40    cout << string( indent, ' ' );
41    if ( tree->isTerminal() ) {                         // terminals
42        cout << "\"" << tree->getText() << "\"";
43    } else {                                            // non-terminals
44        cout << tree->getText();
45    } // if
46    cout << " : " << tree->getKind()
47         //<< " \"" << tree->getWS() << " \""
48         << endl;
49    if ( tree->down != NULL ) Parse_Tree1( tree->down, indent + 2 );
50    if ( tree->left != NULL ) Parse_Tree1( tree->left, indent );
51} // Parse_Tree1
52
53void Parse_Tree( Token *tree ) {
54    if ( tree == NULL ) return;
55    Parse_Tree1( tree, 0 );
56} // Parse_Tree
57
58
59void Nocode( Token *tree ) {                            // prefix tree traversal
60    static bool declprt = true;
61    if ( tree == NULL ) return;
62
63    if ( tree->isTerminal() ) {                         // terminals
64        cout << tree->getWS() << tree->getText();
65    } else {                                            // non-terminals
66        switch ( tree->getKind() ) {
67          case _RHS: {
68              int first = 0;                            // first RHS after ':' or '|' treated specially
69              int push = 0, pop = 0;
70              for ( Token *i = tree->down; i != 0; i = i->left ) {
71                  switch ( i->getKind() ) {
72                    case _ACTION:
73                      cout << string( (push * 4 + pop * 3) / 7, '\t' );
74                      push = pop = 0;
75                      cout << i->down->getComment();    // ignore code but print its comment, if any
76                      break;
77                    case _PREC:
78                      Nocode( i->down );                // print verbatim
79                      break;
80                    case '|':                           // start of alternative and special case
81                      first = 0;
82                    case ';':                           // print with whitespace
83                      cout << string( (push * 4 + pop * 3) / 7, '\t' );
84                      push = pop = 0;
85                      cout << i->getWS() << i->getText();
86                      break;
87                    default:
88                      if ( i->getKind() == IDENTIFIER ) {
89                          if ( i->getText() == "push" ) {
90                              push += 1;
91                              if ( first == 0 ) {       // first RHS after ':' or '|' ?
92                                  cout << i->getComment(); // ignore rhs but print its comment, if any
93                              } // if
94                              break;
95                          } else if ( i->getText() == "pop" ) {
96                              pop += 1;
97                              if ( first == 0 ) {       // first RHS after ':' or '|' ?
98                                  cout << i->getComment(); // ignore rhs but print its comment, if any
99                              } // if
100                              break;
101                          } // if
102                      } // if
103                      // If there is a comment or this is the first RHS after
104                      // ':' or '|', then include the whitespace before the
105                      // token. Otherwise, fold the token onto the same line
106                      // separated with a blank.
107                      string t1( i->getText() );
108                      if ( i->isComment() || first == 0 ) {
109                          first = t1.length();
110                          cout << i->getWS() << t1;
111                      } else {
112                          if ( first + t1.length() <= 100 ) { // check for long lines during folding
113                              first += t1.length();
114                              cout << " " << t1;
115                          } else {
116                              first = t1.length();
117                              cout << endl << "\t\t\t\t" << t1;
118                          } // if
119                      } // if
120                  } // switch
121              } // for
122              break;
123          }
124          case _LITERALBLOCK:                           // ignore code but print its comment, if any
125            cout << tree->down->getComment();
126            break;
127          case _DECLARATION: {                          // ignore certain declarations
128              int kind = tree->down->getKind();         // get kind of declaration
129              if ( kind != UNION && kind != TYPE ) {
130                  declprt = true;
131                  Nocode( tree->down );                 // print verbatim
132              } else if ( declprt ) {                   // ignore declaration but print its comment, if any
133                  declprt = false;
134                  cout << tree->down->getComment();
135              } // if
136              break;
137          }
138          case _USERSECTION_OPT:                        // ignore but add newline at the end
139            cout << endl;
140            break;
141          default:
142            if ( tree->down != NULL ) Nocode( tree->down );
143        } // switch
144    } // if
145    if ( tree->left != NULL ) Nocode( tree->left );
146} // Nocode
147
148
149void LaTeX( Token *tree ) {                             // prefix tree traversal
150    if ( tree == NULL ) return;
151
152    if ( tree->isTerminal() ) {                         // terminals
153        cout << tree->getWS() << tree->getText();
154        if ( tree->getKind() == IDENTIFIER ) {
155            string id( tree->getText() );
156            cout << "\\(\\index{" << id << "@\\protect\\LGbegin\\protect\\lgrinde\\)" << id << "\\(\\protect\\endlgrinde\\protect\\LGend{}}\\)";
157        } // if
158    } else {                                            // non-terminals
159        switch ( tree->getKind() ) {
160          case _RHS: {
161              int first = 0;                            // first RHS after ':' or '|' treated specially
162              int push = 0, pop = 0;
163              Token *prev = 0;
164              for ( Token *i = tree->down; i != 0; prev = i, i = i->left ) {
165                  switch ( i->getKind() ) {
166                    case _ACTION:
167                      cout << i->down->getComment();    // ignore code but print its comment, if any
168                      break;
169                    case _PREC:
170                      LaTeX( i->down );                 // print verbatim
171                      break;
172                    case '|':                           // start of alternative and special case
173                      first = 0;
174                      push = pop = 0;
175                    case ';':                           // print with whitespace
176                      cout << i->getWS() << i->getText();
177                      break;
178                    default:
179                      if ( i->getKind() == IDENTIFIER ) {
180                          if ( i->getText() == "push" ) {
181                              push += 1;
182                              break;
183                          } else if ( i->getText() == "pop" ) {
184                              pop += 1;
185                              break;
186                          } // if
187                      } // if
188                      // If there is a comment or this is the first RHS after
189                      // ':' or '|', then include the whitespace before the
190                      // token. Otherwise, fold the token onto the same line
191                      // separated with a blank.
192                      string t1( i->getText() );
193                      if ( i->isComment() || first == 0 ) {
194                          first = t1.length();
195                          cout << i->getWS() << t1;
196                          if ( i->getKind() == IDENTIFIER ) {
197                              string id( tree->getText() );
198                              cout << "\\(\\index{" << id << "@\"\\verb=" << id << "=}\\)";
199                          } // if
200                      } else {
201                          if ( first + t1.length() <= 100 ) { // check for long lines during folding
202                              first += t1.length();
203                              cout << " " << t1;
204                          } else {
205                              first = t1.length();
206                              cout << endl << "\t\t\t\t" << t1;
207                          } // if
208                      } // if
209                  } // switch
210              } // for
211              break;
212          }
213          case _LITERALBLOCK:                           // ignore code but print its comment, if any
214            cout << tree->down->getComment();
215            break;
216          case _DECLARATION: {                          // ignore certain declarations
217              int kind = tree->down->getKind(); // get kind of declaration
218              if ( kind != UNION && kind != TYPE ) {
219                  LaTeX( tree->down );          // print verbatim
220              } // if
221              break;
222          }
223          case _USERSECTION_OPT:                        // ignore but add newline at the end
224            cout << endl;
225            break;
226          default:
227            if ( tree->down != NULL ) LaTeX( tree->down );
228        } // switch
229    } // if
230    if ( tree->left != NULL ) LaTeX( tree->left );
231} // LaTeX
232
233
234void HTML( Token *tree ) {                              // prefix tree traversal
235    cerr << "ERROR: html style not implemented" << endl;
236} // HTML
237
238
239// Local Variables: //
240// compile-command: "gmake" //
241// End: //
Note: See TracBrowser for help on using the repository browser.