source: tools/prettyprinter/filter.cc@ fda8168

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new stuck-waitfor-destruct with_gc
Last change on this file since fda8168 was fda8168, checked in by Peter A. Buhr <pabuhr@…>, 9 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.