Index: tools/prettyprinter/filter.cc
===================================================================
--- tools/prettyprinter/filter.cc	(revision fda816874a6a323b57c9ce0409b20c6c3ddea4cf)
+++ tools/prettyprinter/filter.cc	(revision fda816874a6a323b57c9ce0409b20c6c3ddea4cf)
@@ -0,0 +1,241 @@
+//                              -*- Mode: C++ -*- 
+// 
+// Pretty Printer, Copyright (C) Peter A. Buhr 2002
+// 
+// filter.cc -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Tue Apr  9 22:33:44 2002
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Dec 17 11:25:50 2002
+// Update Count     : 60
+// 
+
+#include "filter.h"
+#include "yacc.tab.h" 
+
+
+void (*filter)( Token *tree ) = 0;
+
+
+void freeTree( Token *tree ) {				// postfix tree traversal
+    if ( tree == NULL ) return;
+    if ( tree->down != NULL ) freeTree( tree->down );
+    if ( tree->left != NULL ) freeTree( tree->left );
+    //cerr << "free token: \"" << tree->getText() << "\" : " << tree->getKind() << endl;
+    delete tree;
+} // freeTree
+
+
+void Identity( Token *tree ) {				// prefix tree traversal
+    if ( tree == NULL ) return;
+    // print only the terminals
+    if ( tree->isTerminal() ) cout << tree->getWS() << tree->getText();
+    if ( tree->down != NULL ) Identity( tree->down );
+    if ( tree->left != NULL ) Identity( tree->left );
+} // Identity
+
+
+static void Parse_Tree1( Token *tree, int indent ) {	// prefix tree traversal
+    cout << string( indent, ' ' );
+    if ( tree->isTerminal() ) {				// terminals
+	cout << "\"" << tree->getText() << "\"";
+    } else {						// non-terminals
+	cout << tree->getText();
+    } // if
+    cout << " : " << tree->getKind()
+	 //<< " \"" << tree->getWS() << " \""
+	 << endl;
+    if ( tree->down != NULL ) Parse_Tree1( tree->down, indent + 2 );
+    if ( tree->left != NULL ) Parse_Tree1( tree->left, indent );
+} // Parse_Tree1
+
+void Parse_Tree( Token *tree ) {
+    if ( tree == NULL ) return;
+    Parse_Tree1( tree, 0 );
+} // Parse_Tree
+
+
+void Nocode( Token *tree ) {				// prefix tree traversal
+    static bool declprt = true;
+    if ( tree == NULL ) return;
+
+    if ( tree->isTerminal() ) {				// terminals
+	cout << tree->getWS() << tree->getText();
+    } else {						// non-terminals
+	switch ( tree->getKind() ) {
+	  case _RHS: {
+	      int first = 0;				// first RHS after ':' or '|' treated specially
+	      int push = 0, pop = 0;
+	      for ( Token *i = tree->down; i != 0; i = i->left ) {
+		  switch ( i->getKind() ) {
+		    case _ACTION:
+		      cout << string( (push * 4 + pop * 3) / 7, '\t' );
+		      push = pop = 0;
+		      cout << i->down->getComment();	// ignore code but print its comment, if any
+		      break;
+		    case _PREC:
+		      Nocode( i->down );		// print verbatim
+		      break;
+		    case '|':				// start of alternative and special case
+		      first = 0;
+		    case ';':				// print with whitespace
+		      cout << string( (push * 4 + pop * 3) / 7, '\t' );
+		      push = pop = 0;
+		      cout << i->getWS() << i->getText();
+		      break;
+		    default:
+		      if ( i->getKind() == IDENTIFIER ) {
+			  if ( i->getText() == "push" ) {
+			      push += 1;
+			      if ( first == 0 ) {	// first RHS after ':' or '|' ?
+				  cout << i->getComment(); // ignore rhs but print its comment, if any
+			      } // if 
+			      break;
+			  } else if ( i->getText() == "pop" ) {
+			      pop += 1;
+			      if ( first == 0 ) {	// first RHS after ':' or '|' ?
+				  cout << i->getComment(); // ignore rhs but print its comment, if any
+			      } // if 
+			      break;
+			  } // if
+		      } // if
+		      // If there is a comment or this is the first RHS after
+		      // ':' or '|', then include the whitespace before the
+		      // token. Otherwise, fold the token onto the same line
+		      // separated with a blank.
+		      string t1( i->getText() );
+		      if ( i->isComment() || first == 0 ) {
+			  first = t1.length();
+			  cout << i->getWS() << t1;
+		      } else {
+			  if ( first + t1.length() <= 100 ) { // check for long lines during folding
+			      first += t1.length();
+			      cout << " " << t1;
+			  } else {
+			      first = t1.length();
+			      cout << endl << "\t\t\t\t" << t1;
+			  } // if
+		      } // if
+		  } // switch
+	      } // for
+	      break;
+	  }
+	  case _LITERALBLOCK:				// ignore code but print its comment, if any
+	    cout << tree->down->getComment();
+	    break;
+	  case _DECLARATION: {				// ignore certain declarations
+	      int kind = tree->down->getKind();		// get kind of declaration
+	      if ( kind != UNION && kind != TYPE ) {
+		  declprt = true;
+		  Nocode( tree->down );			// print verbatim
+	      } else if ( declprt ) {			// ignore declaration but print its comment, if any
+		  declprt = false;
+		  cout << tree->down->getComment();
+	      } // if
+	      break;
+	  }
+	  case _USERSECTION_OPT:			// ignore but add newline at the end
+	    cout << endl;
+	    break;
+	  default:
+	    if ( tree->down != NULL ) Nocode( tree->down );
+	} // switch
+    } // if
+    if ( tree->left != NULL ) Nocode( tree->left );
+} // Nocode
+
+
+void LaTeX( Token *tree ) {				// prefix tree traversal
+    if ( tree == NULL ) return;
+
+    if ( tree->isTerminal() ) {				// terminals
+	cout << tree->getWS() << tree->getText();
+	if ( tree->getKind() == IDENTIFIER ) {
+	    string id( tree->getText() );
+	    cout << "\\(\\index{" << id << "@\\protect\\LGbegin\\protect\\lgrinde\\)" << id << "\\(\\protect\\endlgrinde\\protect\\LGend{}}\\)";
+	} // if
+    } else {						// non-terminals
+	switch ( tree->getKind() ) {
+	  case _RHS: {
+	      int first = 0;				// first RHS after ':' or '|' treated specially
+	      int push = 0, pop = 0;
+	      Token *prev = 0;
+	      for ( Token *i = tree->down; i != 0; prev = i, i = i->left ) {
+		  switch ( i->getKind() ) {
+		    case _ACTION:
+		      cout << i->down->getComment();	// ignore code but print its comment, if any
+		      break;
+		    case _PREC:
+		      LaTeX( i->down );			// print verbatim
+		      break;
+		    case '|':				// start of alternative and special case
+		      first = 0;
+		      push = pop = 0;
+		    case ';':				// print with whitespace
+		      cout << i->getWS() << i->getText();
+		      break;
+		    default:
+		      if ( i->getKind() == IDENTIFIER ) {
+			  if ( i->getText() == "push" ) {
+			      push += 1;
+			      break;
+			  } else if ( i->getText() == "pop" ) {
+			      pop += 1;
+			      break;
+			  } // if
+		      } // if
+		      // If there is a comment or this is the first RHS after
+		      // ':' or '|', then include the whitespace before the
+		      // token. Otherwise, fold the token onto the same line
+		      // separated with a blank.
+		      string t1( i->getText() );
+		      if ( i->isComment() || first == 0 ) {
+			  first = t1.length();
+			  cout << i->getWS() << t1;
+			  if ( i->getKind() == IDENTIFIER ) {
+			      string id( tree->getText() );
+			      cout << "\\(\\index{" << id << "@\"\\verb=" << id << "=}\\)";
+			  } // if
+		      } else {
+			  if ( first + t1.length() <= 100 ) { // check for long lines during folding
+			      first += t1.length();
+			      cout << " " << t1;
+			  } else {
+			      first = t1.length();
+			      cout << endl << "\t\t\t\t" << t1;
+			  } // if
+		      } // if
+		  } // switch
+	      } // for
+	      break;
+	  }
+	  case _LITERALBLOCK:				// ignore code but print its comment, if any
+	    cout << tree->down->getComment();
+	    break;
+	  case _DECLARATION: {				// ignore certain declarations
+	      int kind = tree->down->getKind();	// get kind of declaration
+	      if ( kind != UNION && kind != TYPE ) {
+		  LaTeX( tree->down );		// print verbatim
+	      } // if
+	      break;
+	  }
+	  case _USERSECTION_OPT:			// ignore but add newline at the end
+	    cout << endl;
+	    break;
+	  default:
+	    if ( tree->down != NULL ) LaTeX( tree->down );
+	} // switch
+    } // if
+    if ( tree->left != NULL ) LaTeX( tree->left );
+} // LaTeX
+
+
+void HTML( Token *tree ) {				// prefix tree traversal
+    cerr << "ERROR: html style not implemented" << endl;
+} // HTML
+
+
+// Local Variables: //
+// compile-command: "gmake" //
+// End: //
