All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.java_cup.internal.lalr_item Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 * 
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License. You can obtain
 * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html
 * or glassfish/bootstrap/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 * 
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt.
 * Sun designates this particular file as subject to the "Classpath" exception
 * as provided by Sun in the GPL Version 2 section of the License file that
 * accompanied this code.  If applicable, add the following below the License
 * Header, with the fields enclosed by brackets [] replaced by your own
 * identifying information: "Portions Copyrighted [year]
 * [name of copyright owner]"
 * 
 * Contributor(s):
 * 
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.java_cup.internal;

import java.util.Stack;
import java.util.Enumeration;

/** This class represents an LALR item. Each LALR item consists of 
 *  a production, a "dot" at a position within that production, and
 *  a set of lookahead symbols (terminal).  (The first two of these parts
 *  are provide by the super class).  An item is designed to represent a 
 *  configuration that the parser may be in.  For example, an item of the 
 *  form: 
 *    [A ::= B * C d E  , {a,b,c}]
 *  
* indicates that the parser is in the middle of parsing the production
 *    A ::= B C d E
 *  
* that B has already been parsed, and that we will expect to see a lookahead * of either a, b, or c once the complete RHS of this production has been * found.

* * Items may initially be missing some items from their lookahead sets. * Links are maintained from each item to the set of items that would need * to be updated if symbols are added to its lookahead set. During * "lookahead propagation", we add symbols to various lookahead sets and * propagate these changes across these dependency links as needed. * * @see com.sun.java_cup.internal.lalr_item_set * @see com.sun.java_cup.internal.lalr_state * @version last updated: 11/25/95 * @author Scott Hudson */ public class lalr_item extends lr_item_core { /*-----------------------------------------------------------*/ /*--- Constructor(s) ----------------------------------------*/ /*-----------------------------------------------------------*/ /** Full constructor. * @param prod the production for the item. * @param pos the position of the "dot" within the production. * @param look the set of lookahead symbols. */ public lalr_item(production prod, int pos, terminal_set look) throws internal_error { super(prod, pos); _lookahead = look; _propagate_items = new Stack(); needs_propagation = true; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Constructor with default position (dot at start). * @param prod the production for the item. * @param look the set of lookahead symbols. */ public lalr_item(production prod, terminal_set look) throws internal_error { this(prod,0,look); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Constructor with default position and empty lookahead set. * @param prod the production for the item. */ public lalr_item(production prod) throws internal_error { this(prod,0,new terminal_set()); } /*-----------------------------------------------------------*/ /*--- (Access to) Instance Variables ------------------------*/ /*-----------------------------------------------------------*/ /** The lookahead symbols of the item. */ protected terminal_set _lookahead; /** The lookahead symbols of the item. */ public terminal_set lookahead() {return _lookahead;} /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Links to items that the lookahead needs to be propagated to. */ protected Stack _propagate_items; /** Links to items that the lookahead needs to be propagated to */ public Stack propagate_items() {return _propagate_items;} /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Flag to indicate that this item needs to propagate its lookahead * (whether it has changed or not). */ protected boolean needs_propagation; /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Add a new item to the set of items we propagate to. */ public void add_propagate(lalr_item prop_to) { _propagate_items.push(prop_to); needs_propagation = true; } /*-----------------------------------------------------------*/ /*--- General Methods ---------------------------------------*/ /*-----------------------------------------------------------*/ /** Propagate incoming lookaheads through this item to others need to * be changed. * @params incoming symbols to potentially be added to lookahead of this item. */ public void propagate_lookaheads(terminal_set incoming) throws internal_error { boolean change = false; /* if we don't need to propagate, then bail out now */ if (!needs_propagation && (incoming == null || incoming.empty())) return; /* if we have null incoming, treat as an empty set */ if (incoming != null) { /* add the incoming to the lookahead of this item */ change = lookahead().add(incoming); } /* if we changed or need it anyway, propagate across our links */ if (change || needs_propagation) { /* don't need to propagate again */ needs_propagation = false; /* propagate our lookahead into each item we are linked to */ for (int i = 0; i < propagate_items().size(); i++) ((lalr_item)propagate_items().elementAt(i)) .propagate_lookaheads(lookahead()); } } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Produce the new lalr_item that results from shifting the dot one position * to the right. */ public lalr_item shift() throws internal_error { lalr_item result; /* can't shift if we have dot already at the end */ if (dot_at_end()) throw new internal_error("Attempt to shift past end of an lalr_item"); /* create the new item w/ the dot shifted by one */ result = new lalr_item(the_production(), dot_pos()+1, new terminal_set(lookahead())); /* change in our lookahead needs to be propagated to this item */ add_propagate(result); return result; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Calculate lookahead representing symbols that could appear after the * symbol that the dot is currently in front of. Note: this routine must * not be invoked before first sets and nullability has been calculated * for all non terminals. */ public terminal_set calc_lookahead(terminal_set lookahead_after) throws internal_error { terminal_set result; int pos; production_part part; symbol sym; /* sanity check */ if (dot_at_end()) throw new internal_error( "Attempt to calculate a lookahead set with a completed item"); /* start with an empty result */ result = new terminal_set(); /* consider all nullable symbols after the one to the right of the dot */ for (pos = dot_pos()+1; pos < the_production().rhs_length(); pos++) { part = the_production().rhs(pos); /* consider what kind of production part it is -- skip actions */ if (!part.is_action()) { sym = ((symbol_part)part).the_symbol(); /* if its a terminal add it in and we are done */ if (!sym.is_non_term()) { result.add((terminal)sym); return result; } else { /* otherwise add in first set of the non terminal */ result.add(((non_terminal)sym).first_set()); /* if its nullable we continue adding, if not, we are done */ if (!((non_terminal)sym).nullable()) return result; } } } /* if we get here everything past the dot was nullable we add in the lookahead for after the production and we are done */ result.add(lookahead_after); return result; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Determine if everything from the symbol one beyond the dot all the * way to the end of the right hand side is nullable. This would indicate * that the lookahead of this item must be included in the lookaheads of * all items produced as a closure of this item. Note: this routine should * not be invoked until after first sets and nullability have been * calculated for all non terminals. */ public boolean lookahead_visible() throws internal_error { production_part part; symbol sym; /* if the dot is at the end, we have a problem, but the cleanest thing to do is just return true. */ if (dot_at_end()) return true; /* walk down the rhs and bail if we get a non-nullable symbol */ for (int pos = dot_pos() + 1; pos < the_production().rhs_length(); pos++) { part = the_production().rhs(pos); /* skip actions */ if (!part.is_action()) { sym = ((symbol_part)part).the_symbol(); /* if its a terminal we fail */ if (!sym.is_non_term()) return false; /* if its not nullable we fail */ if (!((non_terminal)sym).nullable()) return false; } } /* if we get here its all nullable */ return true; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Equality comparison -- here we only require the cores to be equal since * we need to do sets of items based only on core equality (ignoring * lookahead sets). */ public boolean equals(lalr_item other) { if (other == null) return false; return super.equals(other); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Generic equality comparison. */ public boolean equals(Object other) { if (!(other instanceof lalr_item)) return false; else return equals((lalr_item)other); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Return a hash code -- here we only hash the core since we only test core * matching in LALR items. */ public int hashCode() { return super.hashCode(); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Convert to string. */ public String toString() { String result = ""; // additional output for debugging: // result += "(" + obj_hash() + ")"; result += "["; result += super.toString(); result += ", "; if (lookahead() != null) { result += "{"; for (int t = 0; t < terminal.number(); t++) if (lookahead().contains(t)) result += terminal.find(t).name() + " "; result += "}"; } else result += "NULL LOOKAHEAD!!"; result += "]"; // additional output for debugging: // result += " -> "; // for (int i = 0; i





© 2015 - 2024 Weber Informatics LLC | Privacy Policy