001: /*
002: * Copyright 2003-2005 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.java_cup.internal.runtime;
027:
028: import java.util.Stack;
029:
030: /** This class implements a temporary or "virtual" parse stack that
031: * replaces the top portion of the actual parse stack (the part that
032: * has been changed by some set of operations) while maintaining its
033: * original contents. This data structure is used when the parse needs
034: * to "parse ahead" to determine if a given error recovery attempt will
035: * allow the parse to continue far enough to consider it successful. Once
036: * success or failure of parse ahead is determined the system then
037: * reverts to the original parse stack (which has not actually been
038: * modified). Since parse ahead does not execute actions, only parse
039: * state is maintained on the virtual stack, not full Symbol objects.
040: *
041: * @see com.sun.java_cup.internal.runtime.lr_parser
042: * @version last updated: 7/3/96
043: * @author Frank Flannery
044: */
045:
046: public class virtual_parse_stack {
047: /*-----------------------------------------------------------*/
048: /*--- Constructor(s) ----------------------------------------*/
049: /*-----------------------------------------------------------*/
050:
051: /** Constructor to build a virtual stack out of a real stack. */
052: public virtual_parse_stack(Stack shadowing_stack)
053: throws java.lang.Exception {
054: /* sanity check */
055: if (shadowing_stack == null)
056: throw new Exception(
057: "Internal parser error: attempt to create null virtual stack");
058:
059: /* set up our internals */
060: real_stack = shadowing_stack;
061: vstack = new Stack();
062: real_next = 0;
063:
064: /* get one element onto the virtual portion of the stack */
065: get_from_real();
066: }
067:
068: /*-----------------------------------------------------------*/
069: /*--- (Access to) Instance Variables ------------------------*/
070: /*-----------------------------------------------------------*/
071:
072: /** The real stack that we shadow. This is accessed when we move off
073: * the bottom of the virtual portion of the stack, but is always left
074: * unmodified.
075: */
076: protected Stack real_stack;
077:
078: /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
079:
080: /** Top of stack indicator for where we leave off in the real stack.
081: * This is measured from top of stack, so 0 would indicate that no
082: * elements have been "moved" from the real to virtual stack.
083: */
084: protected int real_next;
085:
086: /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
087:
088: /** The virtual top portion of the stack. This stack contains Integer
089: * objects with state numbers. This stack shadows the top portion
090: * of the real stack within the area that has been modified (via operations
091: * on the virtual stack). When this portion of the stack becomes empty we
092: * transfer elements from the underlying stack onto this stack.
093: */
094: protected Stack vstack;
095:
096: /*-----------------------------------------------------------*/
097: /*--- General Methods ---------------------------------------*/
098: /*-----------------------------------------------------------*/
099:
100: /** Transfer an element from the real to the virtual stack. This assumes
101: * that the virtual stack is currently empty.
102: */
103: protected void get_from_real() {
104: Symbol stack_sym;
105:
106: /* don't transfer if the real stack is empty */
107: if (real_next >= real_stack.size())
108: return;
109:
110: /* get a copy of the first Symbol we have not transfered */
111: stack_sym = (Symbol) real_stack.elementAt(real_stack.size() - 1
112: - real_next);
113:
114: /* record the transfer */
115: real_next++;
116:
117: /* put the state number from the Symbol onto the virtual stack */
118: vstack.push(new Integer(stack_sym.parse_state));
119: }
120:
121: /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
122:
123: /** Indicate whether the stack is empty. */
124: public boolean empty() {
125: /* if vstack is empty then we were unable to transfer onto it and
126: the whole thing is empty. */
127: return vstack.empty();
128: }
129:
130: /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
131:
132: /** Return value on the top of the stack (without popping it). */
133: public int top() throws java.lang.Exception {
134: if (vstack.empty())
135: throw new Exception(
136: "Internal parser error: top() called on empty virtual stack");
137:
138: return ((Integer) vstack.peek()).intValue();
139: }
140:
141: /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
142:
143: /** Pop the stack. */
144: public void pop() throws java.lang.Exception {
145: if (vstack.empty())
146: throw new Exception(
147: "Internal parser error: pop from empty virtual stack");
148:
149: /* pop it */
150: vstack.pop();
151:
152: /* if we are now empty transfer an element (if there is one) */
153: if (vstack.empty())
154: get_from_real();
155: }
156:
157: /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/
158:
159: /** Push a state number onto the stack. */
160: public void push(int state_num) {
161: vstack.push(new Integer(state_num));
162: }
163:
164: /*-----------------------------------------------------------*/
165:
166: }
|