GlueGen v2.6.0-rc-20250712
GlueGen, Native Binding Generator for Java™ (public API).
TNode.java
Go to the documentation of this file.
1package com.jogamp.gluegen.cgram;
2
3import antlr.collections.AST;
4import antlr.CommonAST;
5import antlr.Token;
6
7import java.lang.reflect.*;
8import java.util.Hashtable;
9import java.util.Enumeration;
10
11import com.jogamp.gluegen.ASTLocusTag;
12import com.jogamp.gluegen.ASTLocusTag.ASTLocusTagProvider;
13import com.jogamp.gluegen.GlueGen;
14
15/**
16 Class TNode is an implementation of the AST interface
17 and adds many useful features:
18
19 It is double-linked for reverse searching.
20 (this is currently incomplete, in that method doubleLink() must
21 be called after any changes to the tree to maintain the
22 reverse links).
23
24 It can store a definition node (defNode), so that nodes such
25 as scoped names can refer to the node that defines the name.
26
27 It stores line numbers for nodes.
28
29 Searches for parents and children of a tree can be done
30 based on their type.
31
32 The tree can be printed to System.out using a lisp-style syntax.
33
34
35
36 */
37@SuppressWarnings("serial")
38public class TNode extends CommonAST implements ASTLocusTagProvider {
39 protected int ttype;
40 protected String text;
41 protected int lineNum = 0;
42 protected TNode defNode;
43 protected TNode up;
44 protected TNode left;
45 protected boolean marker = false;
46 protected Hashtable<String, Object> attributes = null;
47 static String tokenVocabulary;
48
49 /**
50 * {@inheritDoc}
51 * <p>
52 * If <i>source</i> is not available,
53 * implementation returns {@code null}.
54 * </p>
55 */
56 @Override
58 final Object s = getAttribute("source");
59 if( null != s ) {
60 return new ASTLocusTag(s, getLineNum(), -1, getText());
61 } else {
62 return null;
63 }
64 }
65
66
67 /** Set the token vocabulary to a tokentypes class
68 generated by antlr.
69 */
70 public static void setTokenVocabulary(final String s) {
71 tokenVocabulary = s;
72 }
73
74
75@Override
76public void initialize(final Token token) {
77 final CToken tok = (CToken) token;
78 setText(tok.getText());
79 setType(tok.getType());
80 setLineNum(tok.getLine());
81 setAttribute("source", tok.getSource());
82 setAttribute("tokenNumber", new Integer(tok.getTokenNumber()));
83}
84@Override
85public void initialize(final AST tr) {
86 final TNode t = (TNode) tr;
87 setText(t.getText());
88 setType(t.getType());
89 setLineNum(t.getLineNum());
90 setDefNode(t.getDefNode());
91 this.attributes = t.getAttributesTable();
92}
93
94
95 /** Get the token type for this node */
96 @Override
97 public int getType() { return ttype; }
98
99 /** Set the token type for this node */
100 @Override
101 public void setType(final int ttype_) {
102 ttype = ttype_;
103 }
104
105 /** Get the marker value for this node.
106 This member is a general-use marker.
107 */
108 public boolean getMarker() { return marker; }
109
110 /** Set the marker value for this node.
111 This property is a general-use boolean marker.
112 */
113 public void setMarker(final boolean marker_) {
114 marker = marker_;
115 }
116
117 /** get the hashtable that holds attribute values.
118 */
119 public Hashtable<String, Object> getAttributesTable() {
120 if(attributes == null)
121 attributes = new Hashtable<String, Object>(7);
122 return attributes;
123 }
124
125 /** set an attribute in the attribute table.
126 */
127 public void setAttribute(final String attrName, final Object value) {
128 if(attributes == null)
129 attributes = new Hashtable<String, Object>(7);
130 attributes.put(attrName,value);
131 }
132
133 /** lookup the attribute name in the attribute table.
134 If the value does not exist, it returns null.
135 */
136 public Object getAttribute(final String attrName) {
137 if(attributes == null)
138 return null;
139 else
140 return attributes.get(attrName);
141 }
142
143 /** Get the line number for this node.
144 If the line number is 0, search for a non-zero line num among children */
145 public int getLineNum() {
146 if(lineNum != 0)
147 return lineNum;
148 else
149 if(down == null)
150 return lineNum;
151 else
152 return ((TNode)down).getLocalLineNum();
153 }
154
155 public int getLocalLineNum() {
156 if(lineNum != 0)
157 return lineNum;
158 else
159 if(down == null)
160 if(right == null)
161 return lineNum;
162 else
163 return ((TNode)right).getLocalLineNum();
164 else
165 return ((TNode)down).getLocalLineNum();
166 }
167
168 /** Set the line number for this node */
169 public void setLineNum(final int lineNum_) {
170 lineNum = lineNum_;
171 }
172
173 /** Get the token text for this node */
174 @Override
175 public String getText() { return text; }
176
177 /** Set the token text for this node */
178 @Override
179 public void setText(final String text_) {
180 text = text_;
181 }
182
183 static class DebugASTVisitor {
184 protected int level;
185 private String tabs(final StringBuilder sb) {
186 sb.setLength(0);
187 for (int i = 0; i < level; i++) {
188 sb.append(" ");
189 }
190 return sb.toString();
191 }
192 DebugASTVisitor(final int level) {
193 this.level = level;
194 }
195 void visit(final AST node) {
196 final StringBuilder sb = new StringBuilder();
197 AST node2;
198 for (node2 = node; node2 != null; node2 = node2.getNextSibling()) {
199 if (node2.getText() == null) {
200 System.err.printf("%03d: %snil [%d]%n", level, tabs(sb), node2.getType());
201 } else {
202 System.err.printf("%03d: %s%s [%d]%n", level, tabs(sb), node2.getText(), node2.getType());
203 }
204 if (node2.getFirstChild() != null) {
205 level++;
206 visit(node2.getFirstChild());
207 level--;
208 }
209 }
210 }
211 }
212
213 /**
214 * Returns the text for this node, its children and siblings.
215 * <p>
216 * Implementation converts the AST LISP notation to serialized form.
217 * </p>
218 */
219 public String getAllChildrenText(final String name) {
220 if( GlueGen.debug() ) {
221 System.err.println("TNode.XXX: "+name);
222 new DebugASTVisitor(1).visit(getFirstChild());
223 }
224 final StringBuilder buf = new StringBuilder();
225 final TNode down = (TNode) this.getFirstChild();
226 if( null == down ) {
227 buf.append(this.getText());
228 } else {
229 getAllChildrenText(buf, this, down);
230 }
231 return buf.toString();
232 }
233 private static void getAllChildrenText(final StringBuilder buf,
234 final TNode upNode, TNode thisNode) {
235 boolean first = true;
236 while( null != thisNode ) {
237 final boolean isClosing = HeaderParserTokenTypes.RPAREN == thisNode.getType();
238 final boolean isGroupStart = HeaderParserTokenTypes.NExpressionGroup == thisNode.getType();
239
240 final TNode nextNode = (TNode) thisNode.getNextSibling();
241 final TNode downNode = (TNode) thisNode.getFirstChild();
242 if( !isClosing &&
243 ( null == downNode && null == nextNode || // unary
244 !first // binary
245 )
246 ) {
247 buf.append(" ").append(upNode.getText());
248 }
249 if( null != downNode ) {
250 if( !isGroupStart ) {
251 buf.append(" (");
252 }
253 getAllChildrenText(buf, thisNode, downNode);
254 if( !isGroupStart ) {
255 buf.append(" )");
256 }
257 } else if( !isClosing ) {
258 buf.append(" ").append(thisNode.getText());
259 }
260 thisNode = nextNode;
261 first = false;
262 }
263 }
264
265 /** return the last child of this node, or null if there is none */
267 final TNode down = (TNode)getFirstChild();
268 if(down != null)
269 return down.getLastSibling();
270 else
271 return null;
272 }
273
274 /** return the last sibling of this node, which is
275 this if the next sibling is null */
277 final TNode next = (TNode)getNextSibling();
278 if(next != null)
279 return next.getLastSibling();
280 else
281 return this;
282 }
283
284 /** return the first sibling of this node, which is
285 this if the prev sibling is null */
287 final TNode prev = left;
288 if(prev != null)
289 return prev.getFirstSibling();
290 else
291 return this;
292 }
293
294
295 /** return the parent node of this node */
296 public TNode getParent() {
297 return getFirstSibling().up;
298 }
299
300
301 /** add the new node as a new sibling, inserting it ahead of any
302 existing next sibling. This method maintains double-linking.
303 if node is null, nothing happens. If the node has siblings,
304 then they are added in as well.
305 */
306 public void addSibling(final AST node) {
307 if(node == null) return;
308 final TNode next = (TNode)right;
309 right = (TNode)node;
310 ((TNode)node).left = this;
311 final TNode nodeLastSib = ((TNode)node).getLastSibling();
312 nodeLastSib.right = next;
313 if(next != null)
314 next.left = nodeLastSib;
315 }
316
317
318 /** return the number of children of this node */
319 public int numberOfChildren() {
320 int count = 0;
321 AST child = getFirstChild();
322 while(child != null) {
323 count++;
324 child = child.getNextSibling();
325 }
326 return count;
327 }
328
329
330 /** remove this node from the tree, resetting sibling and parent
331 pointers as necessary. This method maintains double-linking */
332 public void removeSelf() {
333 final TNode parent = up;
334 final TNode prev = left;
335 final TNode next = (TNode)right;
336
337 if(parent != null) {
338 parent.down = next;
339 if(next != null) {
340 next.up = parent;
341 next.left = prev; // which should be null
342 }
343 }
344 else {
345 if(prev != null)
346 prev.right = next;
347 if(next != null)
348 next.left = prev;
349 }
350 }
351
352
353 /** return the def node for this node */
354 public TNode getDefNode() {
355 return defNode;
356 }
357
358 /** set the def node for this node */
359 public void setDefNode(final TNode n) {
360 defNode = n;
361 }
362
363
364 /** return a deep copy of this node, and all sub nodes.
365 New tree is doubleLinked, with no parent or siblings.
366 Marker value is not copied!
367 */
368 public TNode deepCopy() {
369 final TNode copy = new TNode();
370 copy.ttype = ttype;
371 copy.text = text;
372 copy.lineNum = lineNum;
373 copy.defNode = defNode;
374 if(attributes != null)
375 copy.attributes = new Hashtable<String, Object>(attributes);
376 if(down != null)
377 copy.down = ((TNode)down).deepCopyWithRightSiblings();
378 copy.doubleLink();
379 return copy;
380 }
381
382
383 /** return a deep copy of this node, all sub nodes,
384 and right siblings.
385 New tree is doubleLinked, with no parent or left siblings.
386 defNode is not copied */
388 final TNode copy = new TNode();
389 copy.ttype = ttype;
390 copy.text = text;
391 copy.lineNum = lineNum;
392 copy.defNode = defNode;
393 if(attributes != null)
394 copy.attributes = new Hashtable<String, Object>(attributes);
395 if(down != null)
396 copy.down = ((TNode)down).deepCopyWithRightSiblings();
397 if(right != null)
398 copy.right = ((TNode)right).deepCopyWithRightSiblings();
399 copy.doubleLink();
400 return copy;
401 }
402
403
404 /** return a short string representation of the node */
405 @Override
406 public String toString() {
407 final StringBuilder str = new StringBuilder( getNameForType(getType()) +
408 "[" + getText() + ", " + "]");
409
410 if(this.getLineNum() != 0)
411 str.append(" line:" + (this.getLineNum() ) );
412
413 final Enumeration<String> keys = (this.getAttributesTable().keys());
414 while (keys.hasMoreElements()) {
415 final String key = keys.nextElement();
416 str.append(" " + key + ":" + (this.getAttribute(key)));
417 }
418
419 return str.toString();
420 }
421
422
423 /** print given tree to System.out */
424 public static void printTree(final AST t) {
425 if (t == null) return;
426 printASTNode(t,0);
427 System.out.print("\n");
428 }
429
430
431 /** protected method that does the work of printing */
432 protected static void printASTNode(final AST t, final int indent) {
433 AST child1, next;
434 child1 = t.getFirstChild();
435
436 System.out.print("\n");
437 for(int i = 0; i < indent; i++)
438 System.out.print(" ");
439
440 if(child1 != null)
441 System.out.print("(");
442
443 final String s = t.getText();
444 if(s != null && s.length() > 0) {
445 System.out.print(getNameForType(t.getType()));
446 System.out.print(": \"" + s + "\"");
447 }
448 else
449 System.out.print(getNameForType(t.getType()));
450 if(((TNode)t).getLineNum() != 0)
451 System.out.print(" line:" + ((TNode)t).getLineNum() );
452
453 final Enumeration<String> keys = ((TNode)t).getAttributesTable().keys();
454 while (keys.hasMoreElements()) {
455 final String key = keys.nextElement();
456 System.out.print(" " + key + ":" + ((TNode)t).getAttribute(key));
457 }
458 final TNode def = ((TNode)t).getDefNode();
459 if(def != null)
460 System.out.print("[" + getNameForType(def.getType()) + "]");
461
462
463 if(child1 != null) {
464 printASTNode(child1,indent + 1);
465
466 System.out.print("\n");
467 for(int i = 0; i < indent; i++)
468 System.out.print(" ");
469 System.out.print(")");
470 }
471
472 next = t.getNextSibling();
473 if(next != null) {
474 printASTNode(next,indent);
475 }
476 }
477
478 /** converts an int tree token type to a name.
479 Does this by reflecting on nsdidl.IDLTreeTokenTypes,
480 and is dependent on how ANTLR 2.00 outputs that class. */
481 public static String getNameForType(final int t) {
482 try{
483 final Class<?> c = Class.forName(tokenVocabulary);
484 final Field[] fields = c.getDeclaredFields();
485 if(t-2 < fields.length)
486 return fields[t-2].getName();
487 } catch (final Exception e) { System.out.println(e); }
488 return "unfoundtype: " + t;
489 }
490
491
492 /** set up reverse links between this node and its first
493 child and its first sibling, and link those as well */
494 public void doubleLink() {
495 final TNode right = (TNode)getNextSibling();
496 if(right != null) {
497 right.left = this;
498 right.doubleLink();
499 }
500 final TNode down = (TNode)getFirstChild();
501 if(down != null) {
502 down.up = this;
503 down.doubleLink();
504 }
505 }
506
507 /** find first parent of the given type,
508 return null on failure */
509 public TNode parentOfType(final int type) {
510 if(up == null) {
511 if(left == null)
512 return null;
513 else
514 return left.parentOfType(type);
515 }
516 if(up.getType() == type)
517 return up;
518 return up.parentOfType(type);
519 }
520
521 /** find the first child of the node
522 of the given type, return null on failure */
523 public TNode firstChildOfType(final int type) {
524 final TNode down = (TNode)getFirstChild();
525 if(down == null)
526 return null;
527 if(down.getType() == type)
528 return down;
529 return down.firstSiblingOfType(type);
530 }
531
532 /** find the first sibling of the node
533 of the given type, return null on failure */
534 public TNode firstSiblingOfType(final int type) {
535 final TNode right = (TNode)getNextSibling();
536 if(right == null)
537 return null;
538 if(right.getType() == type)
539 return right;
540 return right.firstSiblingOfType(type);
541 }
542
543}
Glue code generator for C functions and data structures.
Definition: GlueGen.java:59
Class TNode is an implementation of the AST interface and adds many useful features:
Definition: TNode.java:38
void setDefNode(final TNode n)
set the def node for this node
Definition: TNode.java:359
TNode getParent()
return the parent node of this node
Definition: TNode.java:296
void initialize(final Token token)
Definition: TNode.java:76
TNode deepCopyWithRightSiblings()
return a deep copy of this node, all sub nodes, and right siblings.
Definition: TNode.java:387
int getType()
Get the token type for this node.
Definition: TNode.java:97
void setText(final String text_)
Set the token text for this node.
Definition: TNode.java:179
ASTLocusTag getASTLocusTag()
Returns this instance's ASTLocusTag, if available, otherwise returns null.
Definition: TNode.java:57
TNode parentOfType(final int type)
find first parent of the given type, return null on failure
Definition: TNode.java:509
static void printTree(final AST t)
print given tree to System.out
Definition: TNode.java:424
TNode getLastSibling()
return the last sibling of this node, which is this if the next sibling is null
Definition: TNode.java:276
void initialize(final AST tr)
Definition: TNode.java:85
String getAllChildrenText(final String name)
Returns the text for this node, its children and siblings.
Definition: TNode.java:219
static void setTokenVocabulary(final String s)
Set the token vocabulary to a tokentypes class generated by antlr.
Definition: TNode.java:70
void doubleLink()
set up reverse links between this node and its first child and its first sibling, and link those as w...
Definition: TNode.java:494
TNode firstSiblingOfType(final int type)
find the first sibling of the node of the given type, return null on failure
Definition: TNode.java:534
TNode firstChildOfType(final int type)
find the first child of the node of the given type, return null on failure
Definition: TNode.java:523
int numberOfChildren()
return the number of children of this node
Definition: TNode.java:319
TNode getFirstSibling()
return the first sibling of this node, which is this if the prev sibling is null
Definition: TNode.java:286
int getLineNum()
Get the line number for this node.
Definition: TNode.java:145
void setLineNum(final int lineNum_)
Set the line number for this node.
Definition: TNode.java:169
TNode deepCopy()
return a deep copy of this node, and all sub nodes.
Definition: TNode.java:368
void setAttribute(final String attrName, final Object value)
set an attribute in the attribute table.
Definition: TNode.java:127
String getText()
Get the token text for this node.
Definition: TNode.java:175
static String getNameForType(final int t)
converts an int tree token type to a name.
Definition: TNode.java:481
void removeSelf()
remove this node from the tree, resetting sibling and parent pointers as necessary.
Definition: TNode.java:332
void addSibling(final AST node)
add the new node as a new sibling, inserting it ahead of any existing next sibling.
Definition: TNode.java:306
TNode getDefNode()
return the def node for this node
Definition: TNode.java:354
Hashtable< String, Object > getAttributesTable()
get the hashtable that holds attribute values.
Definition: TNode.java:119
Object getAttribute(final String attrName)
lookup the attribute name in the attribute table.
Definition: TNode.java:136
boolean getMarker()
Get the marker value for this node.
Definition: TNode.java:108
void setType(final int ttype_)
Set the token type for this node.
Definition: TNode.java:101
static void printASTNode(final AST t, final int indent)
protected method that does the work of printing
Definition: TNode.java:432
String toString()
return a short string representation of the node
Definition: TNode.java:406
TNode getLastChild()
return the last child of this node, or null if there is none
Definition: TNode.java:266
void setMarker(final boolean marker_)
Set the marker value for this node.
Definition: TNode.java:113
Represents a field in a struct or union.
Definition: Field.java:47
String getName()
Name of this field in the containing data structure.
Definition: Field.java:98
Interface tag for ASTLocusTag provider.