aboutsummaryrefslogtreecommitdiff
path: root/src/monkey/seaspider/org/gnunet/seaspider/parser/visitors/TreeDumper.java
blob: c2e7c15587f6f47bb936fb0084f3c294a50ff81d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//
// Generated by JTB 1.3.2
//
package org.gnunet.seaspider.parser.visitors;

import org.gnunet.seaspider.parser.nodes.*;

import java.util.*;
import java.io.*;

/**
 * Dumps the syntax tree to a Writer using the location information in
 * each NodeToken.
 */
public class TreeDumper extends DepthFirstVisitor {
   protected PrintWriter out;
   private int curLine = 1;
   private int curColumn = 1;
   private boolean startAtNextToken = false;
   private boolean printSpecials = true;

   /**
    * The default constructor uses System.out as its output location.
    * You may specify your own Writer or OutputStream using one of the
    * other constructors.
    */
   public TreeDumper()       { out = new PrintWriter(System.out, true); }
   public TreeDumper(Writer o)        { out = new PrintWriter(o, true); }
   public TreeDumper(OutputStream o)  { out = new PrintWriter(o, true); }

   /**
    * Flushes the OutputStream or Writer that this TreeDumper is using.
    */
   public void flushWriter()        { out.flush(); }

   /**
    * Allows you to specify whether or not to print special tokens.
    */
   public void printSpecials(boolean b)   { printSpecials = b; }

   /**
    * Starts the tree dumper on the line containing the next token
    * visited.  For example, if the next token begins on line 50 and the
    * dumper is currently on line 1 of the file, it will set its current
    * line to 50 and continue printing from there, as opposed to
    * printing 49 blank lines and then printing the token.
    */
   public void startAtNextToken()   { startAtNextToken = true; }

   /**
    * Resets the position of the output "cursor" to the first line and
    * column.  When using a dumper on a syntax tree more than once, you
    * either need to call this method or startAtNextToken() between each
    * dump.
    */
   public void resetPosition()      { curLine = curColumn = 1; }

   /**
    * Dumps the current NodeToken to the output stream being used.
    *
    * @throws  IllegalStateException   if the token position is invalid
    *   relative to the current position, i.e. its location places it
    *   before the previous token.
    */
   public void visit(NodeToken n) {
      if ( n.beginLine == -1 || n.beginColumn == -1 ) {
         printToken(n.tokenImage);
         return;
      }

      //
      // Handle special tokens
      //
      if ( printSpecials && n.numSpecials() > 0 )
         for ( Enumeration<NodeToken> e = n.specialTokens.elements(); e.hasMoreElements(); )
            visit(e.nextElement());

      //
      // Handle startAtNextToken option
      //
      if ( startAtNextToken ) {
         curLine = n.beginLine;
         curColumn = 1;
         startAtNextToken = false;

         if ( n.beginColumn < curColumn )
            out.println();
      }

      //
      // Check for invalid token position relative to current position.
      //
      if ( n.beginLine < curLine )
         throw new IllegalStateException("at token \"" + n.tokenImage +
            "\", n.beginLine = " + Integer.toString(n.beginLine) +
            ", curLine = " + Integer.toString(curLine));
      else if ( n.beginLine == curLine && n.beginColumn < curColumn )
         throw new IllegalStateException("at token \"" + n.tokenImage +
            "\", n.beginColumn = " +
            Integer.toString(n.beginColumn) + ", curColumn = " +
            Integer.toString(curColumn));

      //
      // Move output "cursor" to proper location, then print the token
      //
      if ( curLine < n.beginLine ) {
         curColumn = 1;
         for ( ; curLine < n.beginLine; ++curLine )
            out.println();
      }

      for ( ; curColumn < n.beginColumn; ++curColumn )
         out.print(" ");

      printToken(n.tokenImage);
   }

   private void printToken(String s) {
      for ( int i = 0; i < s.length(); ++i ) { 
         if ( s.charAt(i) == '\n' ) {
            ++curLine;
            curColumn = 1;
         }
         else
            curColumn++;

         out.print(s.charAt(i));
      }

      out.flush();
   }
}