001: /* Generated By:JJTree: Do not edit this line. D:/jython/CVS.parser/org/python/parser\JJTPythonGrammarState.java */
002:
003: // Modified by hand. The two closeNodeScope method have been rewritten
004: // completely and is used when building the AST tree bottom-up.
005: package org.python.parser;
006:
007: class JJTPythonGrammarState {
008: private java.util.Stack nodes;
009: private IntStack marks;
010: private IntStack lines;
011: private IntStack columns;
012:
013: private int sp; // number of nodes on stack
014: private int mk; // current mark
015: private boolean node_created;
016:
017: private TreeBuilder builder;
018:
019: JJTPythonGrammarState() {
020: nodes = new java.util.Stack();
021: marks = new IntStack();
022: lines = new IntStack();
023: columns = new IntStack();
024: sp = 0;
025: mk = 0;
026: builder = new TreeBuilder(this );
027: }
028:
029: /* Determines whether the current node was actually closed and
030: pushed. This should only be called in the final user action of a
031: node scope. */
032: boolean nodeCreated() {
033: return node_created;
034: }
035:
036: /* Call this to reinitialize the node stack. It is called
037: automatically by the parser's ReInit() method. */
038: void reset() {
039: nodes.removeAllElements();
040: marks.removeAllElements();
041: sp = 0;
042: mk = 0;
043: }
044:
045: /* Returns the root node of the AST. It only makes sense to call
046: this after a successful parse. */
047: Node rootNode() {
048: return (Node) nodes.elementAt(0);
049: }
050:
051: /* Pushes a node on to the stack. */
052: void pushNode(Node n) {
053: nodes.push(n);
054: ++sp;
055: }
056:
057: /* Returns the node on the top of the stack, and remove it from the
058: stack. */
059: Node popNode() {
060: if (--sp < mk) {
061: mk = marks.pop();
062: }
063: return (Node) nodes.pop();
064: }
065:
066: /* Returns the node currently on the top of the stack. */
067: Node peekNode() {
068: return (Node) nodes.peek();
069: }
070:
071: /* Returns the number of children on the stack in the current node
072: scope. */
073: int nodeArity() {
074: return sp - mk;
075: }
076:
077: void pushNodePos(int line, int col) {
078: lines.push(line);
079: columns.push(col);
080: }
081:
082: void setNodePos() {
083: SimpleNode n = (SimpleNode) peekNode();
084: n.beginLine = lines.pop();
085: n.beginColumn = columns.pop();
086: }
087:
088: void clearNodeScope(Node n) {
089: while (sp > mk) {
090: popNode();
091: }
092: mk = marks.pop();
093: }
094:
095: void openNodeScope(Node n) {
096: marks.push(mk);
097: mk = sp;
098: }
099:
100: /* A definite node is constructed from a specified number of
101: children. That number of nodes are popped from the stack and
102: made the children of the definite node. Then the definite node
103: is pushed on to the stack. */
104: void closeNodeScope(Node n, int num) throws ParseException {
105: SimpleNode sn = (SimpleNode) n;
106: mk = marks.pop();
107: SimpleNode newNode = null;
108: try {
109: newNode = builder.closeNode(sn, num);
110: } catch (ParseException exc) {
111: throw exc;
112: } catch (Exception exc) {
113: exc.printStackTrace();
114: throw new ParseException("Internal error:" + exc);
115: }
116: if (newNode == null) {
117: throw new ParseException("Internal AST builder error");
118: }
119: pushNode(newNode);
120: node_created = true;
121: }
122:
123: /* A conditional node is constructed if its condition is true. All
124: the nodes that have been pushed since the node was opened are
125: made children of the the conditional node, which is then pushed
126: on to the stack. If the condition is false the node is not
127: constructed and they are left on the stack. */
128: void closeNodeScope(Node n, boolean condition)
129: throws ParseException {
130: SimpleNode sn = (SimpleNode) n;
131: if (condition) {
132: SimpleNode newNode = null;
133: try {
134: newNode = builder.closeNode(sn, nodeArity());
135: } catch (ParseException exc) {
136: throw exc;
137: } catch (Exception exc) {
138: exc.printStackTrace();
139: throw new ParseException("Internal error:" + exc);
140: }
141: if (newNode == null) {
142: throw new ParseException("Internal AST builder error");
143: }
144: mk = marks.pop();
145: pushNode(newNode);
146: node_created = true;
147: } else {
148: mk = marks.pop();
149: node_created = false;
150: }
151: }
152:
153: public void dumpTop(String reason) {
154: int a = nodeArity();
155: System.out.println("dumpTop:" + reason);
156: System.out.println("arity:" + a);
157: for (int i = 0; i < a; i++) {
158: Node n = (Node) nodes.elementAt(nodes.size() - i - 1);
159: System.out.println(" " + n);
160: }
161: }
162:
163: public Node openNode(int id) {
164: return builder.openNode(id);
165: }
166:
167: public void dump(String reason) {
168: int a = nodeArity();
169: System.out.println("dump:" + reason);
170: System.out.println(" mk:" + mk + " sp:" + sp);
171: for (int i = 0; i < nodes.size(); i++) {
172: Node n = (Node) nodes.elementAt(i);
173: System.out.println(" " + n);
174: }
175: for (int i = 0; i < marks.size(); i++) {
176: System.out.println(" " + marks.elementAt(i));
177: }
178: }
179: }
180:
181: class IntStack {
182: int[] stack;
183: int sp = 0;
184:
185: public IntStack() {
186: stack = new int[50];
187: }
188:
189: public void removeAllElements() {
190: sp = 0;
191: }
192:
193: public int size() {
194: return sp;
195: }
196:
197: public int elementAt(int idx) {
198: return stack[idx];
199: }
200:
201: public void push(int val) {
202: if (sp >= stack.length) {
203: int[] newstack = new int[sp * 2];
204: System.arraycopy(stack, 0, newstack, 0, sp);
205: stack = newstack;
206: }
207: stack[sp++] = val;
208: }
209:
210: public int pop() {
211: return stack[--sp];
212: }
213: }
|