FileDocCategorySizeDatePackage
non_terminal.javaAPI DocJava SE 5 API9471Fri Aug 26 14:54:54 BST 2005com.sun.java_cup.internal

non_terminal

public class non_terminal extends symbol
This class represents a non-terminal symbol in the grammar. Each non terminal has a textual name, an index, and a string which indicates the type of object it will be implemented with at runtime (i.e. the class of object that will be pushed on the parse stack to represent it).
version
last updated: 11/25/95
author
Scott Hudson

Fields Summary
protected static Hashtable
_all
Table of all non-terminals -- elements are stored using name strings as the key
protected static Hashtable
_all_by_index
Table of all non terminals indexed by their index number.
protected static int
next_index
Static counter to assign unique indexes.
protected static int
next_nt
Static counter for creating unique non-terminal names
public static final non_terminal
START_nt
special non-terminal for start symbol
public boolean
is_embedded_action
flag non-terminals created to embed action productions
protected Hashtable
_productions
Table of all productions with this non terminal on the LHS.
protected boolean
_nullable
Nullability of this non terminal.
protected terminal_set
_first_set
First set for this non-terminal.
Constructors Summary
public non_terminal(String nm, String tp)
Full constructor.

param
nm the name of the non terminal.
param
tp the type string for the non terminal.

      /* super class does most of the work */
      super(nm, tp);

      /* add to set of all non terminals and check for duplicates */
      Object conflict = _all.put(nm,this);
      if (conflict != null)
	// can't throw an exception here because these are used in static
	// initializers, so we crash instead
	// was: 
	// throw new internal_error("Duplicate non-terminal ("+nm+") created");
	(new internal_error("Duplicate non-terminal ("+nm+") created")).crash();

      /* assign a unique index */
      _index = next_index++;

      /* add to by_index set */
      _all_by_index.put(new Integer(_index), this);
    
public non_terminal(String nm)
Constructor with default type.

param
nm the name of the non terminal.

      this(nm, null);
    
Methods Summary
public voidadd_production(production prod)
Add a production to our set of productions.

      /* catch improper productions */
      if (prod == null || prod.lhs() == null || prod.lhs().the_symbol() != this)
	throw new internal_error(
	  "Attempt to add invalid production to non terminal production table");

      /* add it to the table, keyed with itself */
      _productions.put(prod,prod);
    
public static java.util.Enumerationall()
Access to all non-terminals.


       
      return _all.elements();
public static voidcompute_first_sets()
Compute first sets for all non-terminals. This assumes nullability has already computed.

      boolean      change = true;
      Enumeration  n;
      Enumeration  p;
      non_terminal nt;
      production   prod;
      terminal_set prod_first;

      /* repeat this process until we have no change */
      while (change)
	{
	  /* look for a new change */
	  change = false;

	  /* consider each non-terminal */
	  for (n = all(); n.hasMoreElements(); )
	    {
	      nt = (non_terminal)n.nextElement();

	      /* consider every production of that non terminal */
	      for (p = nt.productions(); p.hasMoreElements(); )
		{
		  prod = (production)p.nextElement();

		  /* get the updated first of that production */
		  prod_first = prod.check_first_set();

		  /* if this going to add anything, add it */
		  if (!prod_first.is_subset_of(nt._first_set))
		    {
		      change = true;
		      nt._first_set.add(prod_first);
		    }
		}
	    }
	}
    
public static voidcompute_nullability()
Compute nullability of all non-terminals.

      boolean      change = true;
      non_terminal nt;
      Enumeration  e;
      production   prod;

      /* repeat this process until there is no change */
      while (change)
	{
	  /* look for a new change */
	  change = false;

	  /* consider each non-terminal */
	  for (e=all(); e.hasMoreElements(); )
	    {
	      nt = (non_terminal)e.nextElement();

	      /* only look at things that aren't already marked nullable */
	      if (!nt.nullable())
		{
		  if (nt.looks_nullable())
		    {
		      nt._nullable = true;
		      change = true;
		    }
		}
	    }
	}
      
      /* do one last pass over the productions to finalize all of them */
      for (e=production.all(); e.hasMoreElements(); )
	{
	  prod = (production)e.nextElement();
	  prod.set_nullable(prod.check_nullable());
	}
    
static com.sun.java_cup.internal.non_terminalcreate_new(java.lang.String prefix)
Method for creating a new uniquely named hidden non-terminal using the given string as a base for the name (or "NT$" if null is passed).

param
prefix base name to construct unique name from.

 /* added 24-Mar-1998, CSA */

  /*-----------------------------------------------------------*/
  /*--- Static Methods ----------------------------------------*/
  /*-----------------------------------------------------------*/
	 
                                          
       
    
      if (prefix == null) prefix = "NT$";
      return new non_terminal(prefix + next_nt++);
    
static com.sun.java_cup.internal.non_terminalcreate_new()
static routine for creating a new uniquely named hidden non-terminal

 
      return create_new(null); 
    
public static com.sun.java_cup.internal.non_terminalfind(java.lang.String with_name)
lookup a non terminal by name string

      if (with_name == null)
        return null;
      else 
        return (non_terminal)_all.get(with_name);
    
public static com.sun.java_cup.internal.non_terminalfind(int indx)
Lookup a non terminal by index.


         
      
    
      Integer the_indx = new Integer(indx);

      return (non_terminal)_all_by_index.get(the_indx);
    
public terminal_setfirst_set()
First set for this non-terminal.


        
     return _first_set;
public booleanis_non_term()
Indicate that this symbol is a non-terminal.

      return true;
    
protected booleanlooks_nullable()
Test to see if this non terminal currently looks nullable.

      /* look and see if any of the productions now look nullable */
      for (Enumeration e = productions(); e.hasMoreElements(); )
	/* if the production can go to empty, we are nullable */
	if (((production)e.nextElement()).check_nullable())
	  return true;

      /* none of the productions can go to empty, so we are not nullable */
      return false;
    
public booleannullable()
Nullability of this non terminal.

return _nullable;
public intnum_productions()
Total number of productions with this non terminal on the LHS.

return _productions.size();
public static intnumber()
Total number of non-terminals.

return _all.size();
public java.util.Enumerationproductions()
Access to productions with this non terminal on the LHS.


             
     return _productions.elements();
public java.lang.StringtoString()
convert to string

      return super.toString() + "[" + index() + "]" + (nullable() ? "*" : "");