00001 package java_cup.runtime; 00002 00003 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 00004 * Bandera, a Java(TM) analysis and transformation toolkit * 00005 * Copyright (C) 1998-2001 SAnToS Laboratories (santos@cis.ksu.edu) * 00006 00007 * All rights reserved. * 00008 * * 00009 * This work was done as a project in the SAnToS Laboratory, * 00010 * Department of Computing and Information Sciences, Kansas State * 00011 * University, USA (http://www.cis.ksu.edu/santos). * 00012 * It is understood that any modification not identified as such is * 00013 * not covered by the preceding statement. * 00014 * * 00015 * This work is free software; you can redistribute it and/or * 00016 * modify it under the terms of the GNU Library General Public * 00017 * License as published by the Free Software Foundation; either * 00018 * version 2 of the License, or (at your option) any later version. * 00019 * * 00020 * This work is distributed in the hope that it will be useful, * 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00023 * Library General Public License for more details. * 00024 * * 00025 * You should have received a copy of the GNU Library General Public * 00026 * License along with this toolkit; if not, write to the * 00027 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * 00028 * Boston, MA 02111-1307, USA. * 00029 * * 00030 * Java is a trademark of Sun Microsystems, Inc. * 00031 * * 00032 * To submit a bug report, send a comment, or get the latest news on * 00033 * this project and other SAnToS projects, please visit the web-site * 00034 * http://www.cis.ksu.edu/santos * 00035 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 00036 import java.util.Stack; 00037 00038 /** This class implements a temporary or "virtual" parse stack that 00039 * replaces the top portion of the actual parse stack (the part that 00040 * has been changed by some set of operations) while maintaining its 00041 * original contents. This data structure is used when the parse needs 00042 * to "parse ahead" to determine if a given error recovery attempt will 00043 * allow the parse to continue far enough to consider it successful. Once 00044 * success or failure of parse ahead is determined the system then 00045 * reverts to the original parse stack (which has not actually been 00046 * modified). Since parse ahead does not execute actions, only parse 00047 * state is maintained on the virtual stack, not full Symbol objects. 00048 * 00049 * @see java_cup.runtime.lr_parser 00050 * @version last updated: 7/3/96 00051 * @author Frank Flannery 00052 */ 00053 00054 public class virtual_parse_stack { 00055 /*-----------------------------------------------------------*/ 00056 /*--- (Access to) Instance Variables ------------------------*/ 00057 /*-----------------------------------------------------------*/ 00058 00059 /** The real stack that we shadow. This is accessed when we move off 00060 * the bottom of the virtual portion of the stack, but is always left 00061 * unmodified. 00062 */ 00063 protected Stack real_stack; 00064 00065 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 00066 00067 /** Top of stack indicator for where we leave off in the real stack. 00068 * This is measured from top of stack, so 0 would indicate that no 00069 * elements have been "moved" from the real to virtual stack. 00070 */ 00071 protected int real_next; 00072 00073 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 00074 00075 /** The virtual top portion of the stack. This stack contains Integer 00076 * objects with state numbers. This stack shadows the top portion 00077 * of the real stack within the area that has been modified (via operations 00078 * on the virtual stack). When this portion of the stack becomes empty we 00079 * transfer elements from the underlying stack onto this stack. 00080 */ 00081 protected Stack vstack; 00082 00083 /*-----------------------------------------------------------*/ 00084 00085 /*-----------------------------------------------------------*/ 00086 /*--- Constructor(s) ----------------------------------------*/ 00087 /*-----------------------------------------------------------*/ 00088 00089 /** Constructor to build a virtual stack out of a real stack. */ 00090 public virtual_parse_stack(Stack shadowing_stack) throws java.lang.Exception 00091 { 00092 /* sanity check */ 00093 if (shadowing_stack == null) 00094 throw new Exception( 00095 "Internal parser error: attempt to create null virtual stack"); 00096 00097 /* set up our internals */ 00098 real_stack = shadowing_stack; 00099 vstack = new Stack(); 00100 real_next = 0; 00101 00102 /* get one element onto the virtual portion of the stack */ 00103 get_from_real(); 00104 } 00105 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 00106 00107 /** Indicate whether the stack is empty. */ 00108 public boolean empty() 00109 { 00110 /* if vstack is empty then we were unable to transfer onto it and 00111 the whole thing is empty. */ 00112 return vstack.empty(); 00113 } 00114 /*-----------------------------------------------------------*/ 00115 /*--- General Methods ---------------------------------------*/ 00116 /*-----------------------------------------------------------*/ 00117 00118 /** Transfer an element from the real to the virtual stack. This assumes 00119 * that the virtual stack is currently empty. 00120 */ 00121 protected void get_from_real() 00122 { 00123 Symbol stack_sym; 00124 00125 /* don't transfer if the real stack is empty */ 00126 if (real_next >= real_stack.size()) return; 00127 00128 /* get a copy of the first Symbol we have not transfered */ 00129 stack_sym = (Symbol)real_stack.elementAt(real_stack.size()-1-real_next); 00130 00131 /* record the transfer */ 00132 real_next++; 00133 00134 /* put the state number from the Symbol onto the virtual stack */ 00135 vstack.push(new Integer(stack_sym.parse_state)); 00136 } 00137 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 00138 00139 /** Pop the stack. */ 00140 public void pop() throws java.lang.Exception 00141 { 00142 if (vstack.empty()) 00143 throw new Exception( 00144 "Internal parser error: pop from empty virtual stack"); 00145 00146 /* pop it */ 00147 vstack.pop(); 00148 00149 /* if we are now empty transfer an element (if there is one) */ 00150 if (vstack.empty()) 00151 get_from_real(); 00152 } 00153 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 00154 00155 /** Push a state number onto the stack. */ 00156 public void push(int state_num) 00157 { 00158 vstack.push(new Integer(state_num)); 00159 } 00160 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 00161 00162 /** Return value on the top of the stack (without popping it). */ 00163 public int top() throws java.lang.Exception 00164 { 00165 if (vstack.empty()) 00166 throw new Exception( 00167 "Internal parser error: top() called on empty virtual stack"); 00168 00169 return ((Integer)vstack.peek()).intValue(); 00170 } 00171 }