aboutsummaryrefslogtreecommitdiff
path: root/runtime/Java/src/main/java/org/antlr/runtime/tree/CommonTree.java
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/Java/src/main/java/org/antlr/runtime/tree/CommonTree.java')
-rw-r--r--runtime/Java/src/main/java/org/antlr/runtime/tree/CommonTree.java185
1 files changed, 185 insertions, 0 deletions
diff --git a/runtime/Java/src/main/java/org/antlr/runtime/tree/CommonTree.java b/runtime/Java/src/main/java/org/antlr/runtime/tree/CommonTree.java
new file mode 100644
index 0000000..91c59de
--- /dev/null
+++ b/runtime/Java/src/main/java/org/antlr/runtime/tree/CommonTree.java
@@ -0,0 +1,185 @@
+/*
+ [The "BSD license"]
+ Copyright (c) 2005-2009 Terence Parr
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. The name of the author may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package org.antlr.runtime.tree;
+
+import org.antlr.runtime.Token;
+
+/** A tree node that is wrapper for a Token object. After 3.0 release
+ * while building tree rewrite stuff, it became clear that computing
+ * parent and child index is very difficult and cumbersome. Better to
+ * spend the space in every tree node. If you don't want these extra
+ * fields, it's easy to cut them out in your own BaseTree subclass.
+ */
+public class CommonTree extends BaseTree {
+ /** A single token is the payload */
+ public Token token;
+
+ /** What token indexes bracket all tokens associated with this node
+ * and below?
+ */
+ protected int startIndex=-1, stopIndex=-1;
+
+ /** Who is the parent node of this node; if null, implies node is root */
+ public CommonTree parent;
+
+ /** What index is this node in the child list? Range: 0..n-1 */
+ public int childIndex = -1;
+
+ public CommonTree() { }
+
+ public CommonTree(CommonTree node) {
+ super(node);
+ this.token = node.token;
+ this.startIndex = node.startIndex;
+ this.stopIndex = node.stopIndex;
+ }
+
+ public CommonTree(Token t) {
+ this.token = t;
+ }
+
+ public Token getToken() {
+ return token;
+ }
+
+ public Tree dupNode() {
+ return new CommonTree(this);
+ }
+
+ public boolean isNil() {
+ return token==null;
+ }
+
+ public int getType() {
+ if ( token==null ) {
+ return Token.INVALID_TOKEN_TYPE;
+ }
+ return token.getType();
+ }
+
+ public String getText() {
+ if ( token==null ) {
+ return null;
+ }
+ return token.getText();
+ }
+
+ public int getLine() {
+ if ( token==null || token.getLine()==0 ) {
+ if ( getChildCount()>0 ) {
+ return getChild(0).getLine();
+ }
+ return 0;
+ }
+ return token.getLine();
+ }
+
+ public int getCharPositionInLine() {
+ if ( token==null || token.getCharPositionInLine()==-1 ) {
+ if ( getChildCount()>0 ) {
+ return getChild(0).getCharPositionInLine();
+ }
+ return 0;
+ }
+ return token.getCharPositionInLine();
+ }
+
+ public int getTokenStartIndex() {
+ if ( startIndex==-1 && token!=null ) {
+ return token.getTokenIndex();
+ }
+ return startIndex;
+ }
+
+ public void setTokenStartIndex(int index) {
+ startIndex = index;
+ }
+
+ public int getTokenStopIndex() {
+ if ( stopIndex==-1 && token!=null ) {
+ return token.getTokenIndex();
+ }
+ return stopIndex;
+ }
+
+ public void setTokenStopIndex(int index) {
+ stopIndex = index;
+ }
+
+ /** For every node in this subtree, make sure it's start/stop token's
+ * are set. Walk depth first, visit bottom up. Only updates nodes
+ * with at least one token index < 0.
+ */
+ public void setUnknownTokenBoundaries() {
+ if ( children==null ) {
+ if ( startIndex<0 || stopIndex<0 ) {
+ startIndex = stopIndex = token.getTokenIndex();
+ }
+ return;
+ }
+ for (int i=0; i<children.size(); i++) {
+ ((CommonTree)children.get(i)).setUnknownTokenBoundaries();
+ }
+ if ( startIndex>=0 && stopIndex>=0 ) return; // already set
+ if ( children.size() > 0 ) {
+ CommonTree firstChild = (CommonTree)children.get(0);
+ CommonTree lastChild = (CommonTree)children.get(children.size()-1);
+ startIndex = firstChild.getTokenStartIndex();
+ stopIndex = lastChild.getTokenStopIndex();
+ }
+ }
+
+ public int getChildIndex() {
+ return childIndex;
+ }
+
+ public Tree getParent() {
+ return parent;
+ }
+
+ public void setParent(Tree t) {
+ this.parent = (CommonTree)t;
+ }
+
+ public void setChildIndex(int index) {
+ this.childIndex = index;
+ }
+
+ public String toString() {
+ if ( isNil() ) {
+ return "nil";
+ }
+ if ( getType()==Token.INVALID_TOKEN_TYPE ) {
+ return "<errornode>";
+ }
+ if ( token==null ) {
+ return null;
+ }
+ return token.getText();
+ }
+}