001: /*
002: * Copyright 2002-2006 The Apache Software Foundation.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: /* Generated By:JJTree: Do not edit this line. JJTParserState.java */
017:
018: package org.apache.commons.jexl.parser;
019:
020: import java.util.Stack;
021:
022: class JJTParserState {
023: private final Stack nodes;
024:
025: private final Stack marks;
026:
027: private int sp; // number of nodes on stack
028:
029: private int mk; // current mark
030:
031: private boolean node_created;
032:
033: JJTParserState() {
034: nodes = new Stack();
035: marks = new Stack();
036: sp = 0;
037: mk = 0;
038: }
039:
040: /*
041: * Determines whether the current node was actually closed and pushed. This
042: * should only be called in the final user action of a node scope.
043: */
044: boolean nodeCreated() {
045: return node_created;
046: }
047:
048: /*
049: * Call this to reinitialize the node stack. It is called automatically by
050: * the parser's ReInit() method.
051: */
052: void reset() {
053: nodes.removeAllElements();
054: marks.removeAllElements();
055: sp = 0;
056: mk = 0;
057: }
058:
059: /*
060: * Returns the root node of the AST. It only makes sense to call this after
061: * a successful parse.
062: */
063: Node rootNode() {
064: return (Node) nodes.elementAt(0);
065: }
066:
067: /* Pushes a node on to the stack. */
068: void pushNode(Node n) {
069: nodes.push(n);
070: ++sp;
071: }
072:
073: /*
074: * Returns the node on the top of the stack, and remove it from the stack.
075: */
076: Node popNode() {
077: if (--sp < mk) {
078: mk = ((Integer) marks.pop()).intValue();
079: }
080: return (Node) nodes.pop();
081: }
082:
083: /* Returns the node currently on the top of the stack. */
084: Node peekNode() {
085: return (Node) nodes.peek();
086: }
087:
088: /*
089: * Returns the number of children on the stack in the current node scope.
090: */
091: int nodeArity() {
092: return sp - mk;
093: }
094:
095: void clearNodeScope(Node n) {
096: while (sp > mk) {
097: popNode();
098: }
099: mk = ((Integer) marks.pop()).intValue();
100: }
101:
102: void openNodeScope(Node n) {
103: marks.push(new Integer(mk));
104: mk = sp;
105: n.jjtOpen();
106: }
107:
108: /*
109: * A definite node is constructed from a specified number of children. That
110: * number of nodes are popped from the stack and made the children of the
111: * definite node. Then the definite node is pushed on to the stack.
112: */
113: void closeNodeScope(Node n, int num) {
114: mk = ((Integer) marks.pop()).intValue();
115: while (num-- > 0) {
116: Node c = popNode();
117: c.jjtSetParent(n);
118: n.jjtAddChild(c, num);
119: }
120: n.jjtClose();
121: pushNode(n);
122: node_created = true;
123: }
124:
125: /*
126: * A conditional node is constructed if its condition is true. All the nodes
127: * that have been pushed since the node was opened are made children of the
128: * the conditional node, which is then pushed on to the stack. If the
129: * condition is false the node is not constructed and they are left on the
130: * stack.
131: */
132: void closeNodeScope(Node n, boolean condition) {
133: if (condition) {
134: int a = nodeArity();
135: mk = ((Integer) marks.pop()).intValue();
136: while (a-- > 0) {
137: Node c = popNode();
138: c.jjtSetParent(n);
139: n.jjtAddChild(c, a);
140: }
141: n.jjtClose();
142: pushNode(n);
143: node_created = true;
144: } else {
145: mk = ((Integer) marks.pop()).intValue();
146: node_created = false;
147: }
148: }
149: }
|