001: /* Generated By:JJTree: Do not edit this line. JJTExpressionParserState.java */
002:
003: package org.codehaus.aspectwerkz.expression.ast;
004:
005: class JJTExpressionParserState {
006: private java.util.Stack nodes;
007:
008: private java.util.Stack marks;
009:
010: private int sp; // number of nodes on stack
011:
012: private int mk; // current mark
013:
014: private boolean node_created;
015:
016: JJTExpressionParserState() {
017: nodes = new java.util.Stack();
018: marks = new java.util.Stack();
019: sp = 0;
020: mk = 0;
021: }
022:
023: /*
024: * Determines whether the current node was actually closed and pushed. This should only be called in the final user
025: * action of a node scope.
026: */
027: boolean nodeCreated() {
028: return node_created;
029: }
030:
031: /*
032: * Call this to reinitialize the node stack. It is called automatically by the parser's ReInit() method.
033: */
034: void reset() {
035: nodes.removeAllElements();
036: marks.removeAllElements();
037: sp = 0;
038: mk = 0;
039: }
040:
041: /*
042: * Returns the root node of the AST. It only makes sense to call this after a successful parse.
043: */
044: Node rootNode() {
045: return (Node) nodes.elementAt(0);
046: }
047:
048: /* Pushes a node on to the stack. */
049: void pushNode(Node n) {
050: nodes.push(n);
051: ++sp;
052: }
053:
054: /*
055: * Returns the node on the top of the stack, and remove it from the stack.
056: */
057: Node popNode() {
058: if (--sp < mk) {
059: mk = ((Integer) marks.pop()).intValue();
060: }
061: return (Node) nodes.pop();
062: }
063:
064: /* Returns the node currently on the top of the stack. */
065: Node peekNode() {
066: return (Node) nodes.peek();
067: }
068:
069: /*
070: * Returns the number of children on the stack in the current node scope.
071: */
072: int nodeArity() {
073: return sp - mk;
074: }
075:
076: void clearNodeScope(Node n) {
077: while (sp > mk) {
078: popNode();
079: }
080: mk = ((Integer) marks.pop()).intValue();
081: }
082:
083: void openNodeScope(Node n) {
084: marks.push(new Integer(mk));
085: mk = sp;
086: n.jjtOpen();
087: }
088:
089: /*
090: * A definite node is constructed from a specified number of children. That number of nodes are popped from the
091: * stack and made the children of the definite node. Then the definite node is pushed on to the stack.
092: */
093: void closeNodeScope(Node n, int num) {
094: mk = ((Integer) marks.pop()).intValue();
095: while (num-- > 0) {
096: Node c = popNode();
097: c.jjtSetParent(n);
098: n.jjtAddChild(c, num);
099: }
100: n.jjtClose();
101: pushNode(n);
102: node_created = true;
103: }
104:
105: /*
106: * A conditional node is constructed if its condition is true. All the nodes that have been pushed since the node
107: * was opened are made children of the the conditional node, which is then pushed on to the stack. If the condition
108: * is false the node is not constructed and they are left on the stack.
109: */
110: void closeNodeScope(Node n, boolean condition) {
111: if (condition) {
112: int a = nodeArity();
113: mk = ((Integer) marks.pop()).intValue();
114: while (a-- > 0) {
115: Node c = popNode();
116: c.jjtSetParent(n);
117: n.jjtAddChild(c, a);
118: }
119: n.jjtClose();
120: pushNode(n);
121: node_created = true;
122: } else {
123: mk = ((Integer) marks.pop()).intValue();
124: node_created = false;
125: }
126: }
127: }
|