1/* 2 * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 27package com.sun.java_cup.internal.runtime; 28 29import java.util.Stack; 30 31/** This class implements a temporary or "virtual" parse stack that 32 * replaces the top portion of the actual parse stack (the part that 33 * has been changed by some set of operations) while maintaining its 34 * original contents. This data structure is used when the parse needs 35 * to "parse ahead" to determine if a given error recovery attempt will 36 * allow the parse to continue far enough to consider it successful. Once 37 * success or failure of parse ahead is determined the system then 38 * reverts to the original parse stack (which has not actually been 39 * modified). Since parse ahead does not execute actions, only parse 40 * state is maintained on the virtual stack, not full Symbol objects. 41 * 42 * @see com.sun.java_cup.internal.runtime.lr_parser 43 * @author Frank Flannery 44 */ 45 46public class virtual_parse_stack { 47 /*-----------------------------------------------------------*/ 48 /*--- Constructor(s) ----------------------------------------*/ 49 /*-----------------------------------------------------------*/ 50 51 /** Constructor to build a virtual stack out of a real stack. */ 52 public virtual_parse_stack(Stack shadowing_stack) throws java.lang.Exception 53 { 54 /* sanity check */ 55 if (shadowing_stack == null) 56 throw new Exception( 57 "Internal parser error: attempt to create null virtual stack"); 58 59 /* set up our internals */ 60 real_stack = shadowing_stack; 61 vstack = new Stack(); 62 real_next = 0; 63 64 /* get one element onto the virtual portion of the stack */ 65 get_from_real(); 66 } 67 68 /*-----------------------------------------------------------*/ 69 /*--- (Access to) Instance Variables ------------------------*/ 70 /*-----------------------------------------------------------*/ 71 72 /** The real stack that we shadow. This is accessed when we move off 73 * the bottom of the virtual portion of the stack, but is always left 74 * unmodified. 75 */ 76 protected Stack real_stack; 77 78 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 79 80 /** Top of stack indicator for where we leave off in the real stack. 81 * This is measured from top of stack, so 0 would indicate that no 82 * elements have been "moved" from the real to virtual stack. 83 */ 84 protected int real_next; 85 86 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 87 88 /** The virtual top portion of the stack. This stack contains Integer 89 * objects with state numbers. This stack shadows the top portion 90 * of the real stack within the area that has been modified (via operations 91 * on the virtual stack). When this portion of the stack becomes empty we 92 * transfer elements from the underlying stack onto this stack. 93 */ 94 protected Stack vstack; 95 96 /*-----------------------------------------------------------*/ 97 /*--- General Methods ---------------------------------------*/ 98 /*-----------------------------------------------------------*/ 99 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 { 105 Symbol stack_sym; 106 107 /* don't transfer if the real stack is empty */ 108 if (real_next >= real_stack.size()) 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-real_next); 112 113 /* record the transfer */ 114 real_next++; 115 116 /* put the state number from the Symbol onto the virtual stack */ 117 vstack.push(stack_sym.parse_state); 118 } 119 120 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 121 122 /** Indicate whether the stack is empty. */ 123 public boolean empty() 124 { 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 { 135 if (vstack.empty()) 136 throw new Exception( 137 "Internal parser error: top() called on empty virtual stack"); 138 139 return ((Integer)vstack.peek()).intValue(); 140 } 141 142 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 143 144 /** Pop the stack. */ 145 public void pop() throws java.lang.Exception 146 { 147 if (vstack.empty()) 148 throw new Exception( 149 "Internal parser error: pop from empty virtual stack"); 150 151 /* pop it */ 152 vstack.pop(); 153 154 /* if we are now empty transfer an element (if there is one) */ 155 if (vstack.empty()) 156 get_from_real(); 157 } 158 159 /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ 160 161 /** Push a state number onto the stack. */ 162 public void push(int state_num) 163 { 164 vstack.push(state_num); 165 } 166 167 /*-----------------------------------------------------------*/ 168 169} 170