-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathASTPrinter.java
173 lines (141 loc) · 4.39 KB
/
ASTPrinter.java
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/* -*- jde -*- ASTPrinter.java.in */
import java.util.*;
/*
* Import your grammar packages here
*/
import minipython.analysis.*;
import minipython.node.*;
/**
* Text display of the AST, with (optionally) color output.
*
* To print the AST we do a reverse depth first traversal. We do this
* because it is easier to know which element is the last child in any
* node. This makes it easier to do nice indenting.
*
* @author Roger Keays <[email protected]>
* 7/9/2001
*/
public class ASTPrinter extends ReversedDepthFirstAdapter
{
//---Constants------------------------------------------------
public static char ESC = 27;
// Text attributes
public static final int NORMAL = 0;
public static final int BOLD = 1;
public static final int UNDERSCORE = 4;
public static final int BLINK = 5;
public static final int REVERSE = 7;
public static final int CONCEALED = 8;
// Foreground colors
public static final int FG_BLACK = 30;
public static final int FG_RED = 31;
public static final int FG_GREEN = 32;
public static final int FG_YELLOW = 33;
public static final int FG_BLUE = 34;
public static final int FG_MAGENTA = 35;
public static final int FG_CYAN = 36;
public static final int FG_WHITE = 37;
// Background colors
public static final int BG_BLACK = 40;
public static final int BG_RED = 41;
public static final int BG_GREEN = 42;
public static final int BG_YELLOW = 43;
public static final int BG_BLUE = 44;
public static final int BG_MAGENTA = 45;
public static final int BG_CYAN = 46;
public static final int BG_WHITE = 47;
// variables. We use a stack to push on indent tokens...
private String indent = "", output ="";
private boolean last = false;
private Stack indentchar = new Stack();
private boolean color = false;
/*
* The last node we visit. It prints out the entire text that we
* have built.
*/
public void outStart(Start node)
{
System.out.println( treeColor() + "\n >" + output.substring
(3, output.length()) + "\n" + resetColor());
}
/*
* As we visit each non-terminal node push on the indent we need
* for this node. The next node we visit will always be the last
* child of this node.
*/
public void defaultIn(Node node)
{
if (last) indentchar.push ("`");
else indentchar.push("|");
indent = indent + " ";
last = true;
}
/*
* As we leave a non-terminal node, we pull off the indent
* character and prepend this nodes line to the output text.
*/
public void defaultOut(Node node)
{
// replace the current indent with the one from the stack
indent = indent.substring(0, indent.length() - 3);
indent = indent.substring(0, indent.length() - 1) +
(String) indentchar.pop();
// prepend this line to the output.
output = indent + "- " + setColor(BOLD, FG_CYAN, BG_BLACK) +
node.getClass().getName().substring
(node.getClass().getName().lastIndexOf('.') + 1) + treeColor() +
"\n" + output;
// replace any ` with a |
indent = indent.substring(0, indent.length() - 1) + '|';
}
/*
* When we visit a terminals we just print it out. We always set
* last to false after this because the next node we visit will
* never be the last sibling.
*/
public void defaultCase(Node node)
{
// last sibling has a ` instead of a |
if (last)
indent = indent.substring(0, indent.length() - 1) + '`';
// prepend this line to the output
output = indent + "- " + setColor(BOLD, FG_GREEN, BG_BLACK) +
((Token) node).getText() + treeColor() + "\n" + output;
// replace any ` with a |
indent = indent.substring(0, indent.length() - 1) + '|';
last = false;
}
public void caseEOF(EOF node)
{
last = false;
}
/*
* A method to change the color codes. This only works on
* color-enabled terminals. In Windows/MS-DOS you need to load the
* ansi.sys driver from config.sys or c:\winnt\system32\config.nt
* (NT/win2k). ANSI.sys only works under Win2k in DOS mode. In UNIX,
* you need an ansi-enabled terminal...
*/
public String setColor(int style, int fgColor, int bgColor)
{
if (color)
return ESC + "[" + style + ";" + fgColor + ";" + bgColor +
"m";
else return "";
}
public String resetColor()
{
return (setColor(NORMAL, FG_WHITE, BG_BLACK));
}
public String treeColor()
{
return (setColor(NORMAL, FG_YELLOW, BG_BLACK));
}
/*
* Not everyone wants color. It is disabled by default
*/
public void setColor(boolean b)
{
color = b;
}
}