001    package org.apache.commons.ognl;
002    
003    /*
004     * Licensed to the Apache Software Foundation (ASF) under one
005     * or more contributor license agreements.  See the NOTICE file
006     * distributed with this work for additional information
007     * regarding copyright ownership.  The ASF licenses this file
008     * to you under the Apache License, Version 2.0 (the
009     * "License"); you may not use this file except in compliance
010     * with the License.  You may obtain a copy of the License at
011     *
012     * http://www.apache.org/licenses/LICENSE-2.0
013     *
014     * Unless required by applicable law or agreed to in writing,
015     * software distributed under the License is distributed on an
016     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017     * KIND, either express or implied.  See the License for the
018     * specific language governing permissions and limitations
019     * under the License.
020     */
021    
022    /* Generated By:JavaCC: Do not edit this line. JJTOgnlParserState.java Version 4.1d1 */
023    
024    import java.util.ArrayList;
025    import java.util.List;
026    
027    /**
028     * $Id: JJTOgnlParserState.java 1194866 2011-10-29 10:51:32Z mcucchiara $
029     */
030    public class JJTOgnlParserState
031    {
032        private List<Node> nodes;
033    
034        private List<Integer> marks;
035    
036        private int numNodesOnStack;
037    
038        private int currentMark;
039    
040        private boolean nodeCreated;
041    
042        public JJTOgnlParserState()
043        {
044            nodes = new ArrayList<Node>();
045            marks = new ArrayList<Integer>();
046            numNodesOnStack = 0;
047            currentMark = 0;
048        }
049    
050        /*
051         * Determines whether the current node was actually closed and pushed. This should only be called in the final user
052         * action of a node scope.
053         */
054        public boolean nodeCreated()
055        {
056            return nodeCreated;
057        }
058    
059        /*
060         * Call this to reinitialize the node stack. It is called automatically by the parser's ReInit() method.
061         */
062        public void reset()
063        {
064            nodes.clear();
065            marks.clear();
066            numNodesOnStack = 0;
067            currentMark = 0;
068        }
069    
070        /*
071         * Returns the root node of the AST. It only makes sense to call this after a successful parse.
072         */
073        public Node rootNode()
074        {
075            return nodes.get( 0 );
076        }
077    
078        /* Pushes a node on to the stack. */
079        public void pushNode( Node node )
080        {
081            nodes.add( node );
082            ++numNodesOnStack;
083        }
084    
085        /*
086         * Returns the node on the top of the stack, and remove it from the stack.
087         */
088        public Node popNode()
089        {
090            if ( --numNodesOnStack < currentMark )
091            {
092                currentMark = marks.remove( marks.size() - 1 );
093            }
094            return nodes.remove( nodes.size() - 1 );
095        }
096    
097        /* Returns the node currently on the top of the stack. */
098        public Node peekNode()
099        {
100            return nodes.get( nodes.size() - 1 );
101        }
102    
103        /*
104         * Returns the number of children on the stack in the current node scope.
105         */
106        public int nodeArity()
107        {
108            return numNodesOnStack - currentMark;
109        }
110    
111        public void clearNodeScope( Node unused )
112        {
113            while ( numNodesOnStack > currentMark )
114            {
115                popNode();
116            }
117            currentMark = marks.remove( marks.size() - 1 );
118        }
119    
120        public void openNodeScope( Node node )
121        {
122            marks.add( currentMark );
123            currentMark = numNodesOnStack;
124            node.jjtOpen();
125        }
126    
127        /*
128         * A definite node is constructed from a specified number of children. That number of nodes are popped from the
129         * stack and made the children of the definite node. Then the definite node is pushed on to the stack.
130         */
131        public void closeNodeScope( Node node, int num )
132        {
133            currentMark = marks.remove( marks.size() - 1 );
134            while ( num-- > 0 )
135            {
136                Node poppedNode = popNode();
137                poppedNode.jjtSetParent( node );
138                node.jjtAddChild( poppedNode, num );
139            }
140            node.jjtClose();
141            pushNode( node );
142            nodeCreated = true;
143        }
144    
145        /*
146         * A conditional node is constructed if its condition is true. All the nodes that have been pushed since the node
147         * was opened are made children of the conditional node, which is then pushed on to the stack. If the condition is
148         * false the node is not constructed and they are left on the stack.
149         */
150        public void closeNodeScope( Node node, boolean condition )
151        {
152            if ( condition )
153            {
154                int arity = nodeArity();
155                currentMark = marks.remove( marks.size() - 1 );
156                while ( arity-- > 0 )
157                {
158                    Node poppedNode = popNode();
159                    poppedNode.jjtSetParent( node );
160                    node.jjtAddChild( poppedNode, arity );
161                }
162                node.jjtClose();
163                pushNode( node );
164                nodeCreated = true;
165            }
166            else
167            {
168                currentMark = marks.remove( marks.size() - 1 );
169                nodeCreated = false;
170            }
171        }
172    }
173    /* JavaCC - OriginalChecksum=61071c68a05e7c9104307c34a2e37165 (do not edit this line) */