⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 non_terminal.java

📁 我开发的一个用java语言实现的编译器,内含词法分析器,语法分析器,而且可以实现中间代码生成.用到了SLR算法和LR(1)算法
💻 JAVA
字号:
package java_cup;import java.util.Hashtable;import java.util.Enumeration;/** 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 */public class non_terminal extends symbol {  /*-----------------------------------------------------------*/  /*--- Constructor(s) ----------------------------------------*/  /*-----------------------------------------------------------*/  /** Full constructor.   * @param nm  the name of the non terminal.   * @param tp  the type string for the non terminal.   */  public non_terminal(String nm, String tp)     {      /* 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);    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Constructor with default type.    * @param nm  the name of the non terminal.   */  public non_terminal(String nm)     {      this(nm, null);    }  /*-----------------------------------------------------------*/  /*--- (Access to) Static (Class) Variables ------------------*/  /*-----------------------------------------------------------*/  /** Table of all non-terminals -- elements are stored using name strings    *  as the key    */  protected static Hashtable _all = new Hashtable();  /** Access to all non-terminals. */  public static Enumeration all() {return _all.elements();}  /** lookup a non terminal by name string */   public static non_terminal find(String with_name)    {      if (with_name == null)        return null;      else         return (non_terminal)_all.get(with_name);    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Table of all non terminals indexed by their index number. */  protected static Hashtable _all_by_index = new Hashtable();  /** Lookup a non terminal by index. */  public static non_terminal find(int indx)    {      Integer the_indx = new Integer(indx);      return (non_terminal)_all_by_index.get(the_indx);    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Total number of non-terminals. */  public static int number() {return _all.size();}  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Static counter to assign unique indexes. */  protected static int next_index = 0;  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Static counter for creating unique non-terminal names */  static protected int next_nt = 0;  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** special non-terminal for start symbol */  public static final non_terminal START_nt = new non_terminal("$START");  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** flag non-terminals created to embed action productions */  public boolean is_embedded_action = false; /* added 24-Mar-1998, CSA */  /*-----------------------------------------------------------*/  /*--- Static Methods ----------------------------------------*/  /*-----------------------------------------------------------*/	   /** 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.    */  static non_terminal create_new(String prefix) throws internal_error    {      if (prefix == null) prefix = "NT$";      return new non_terminal(prefix + next_nt++);    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** static routine for creating a new uniquely named hidden non-terminal */  static non_terminal create_new() throws internal_error    {       return create_new(null);     }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Compute nullability of all non-terminals. */  public static void compute_nullability() throws internal_error    {      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());	}    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Compute first sets for all non-terminals.  This assumes nullability has   *  already computed.   */  public static void compute_first_sets() throws internal_error    {      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);		    }		}	    }	}    }  /*-----------------------------------------------------------*/  /*--- (Access to) Instance Variables ------------------------*/  /*-----------------------------------------------------------*/  /** Table of all productions with this non terminal on the LHS. */  protected Hashtable _productions = new Hashtable(11);  /** Access to productions with this non terminal on the LHS. */  public Enumeration productions() {return _productions.elements();}  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Total number of productions with this non terminal on the LHS. */  public int num_productions() {return _productions.size();}  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Add a production to our set of productions. */  public void add_production(production prod) throws internal_error    {      /* 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);    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Nullability of this non terminal. */  protected boolean _nullable;  /** Nullability of this non terminal. */  public boolean nullable() {return _nullable;}  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** First set for this non-terminal. */  protected terminal_set _first_set = new terminal_set();  /** First set for this non-terminal. */  public terminal_set first_set() {return _first_set;}  /*-----------------------------------------------------------*/  /*--- General Methods ---------------------------------------*/  /*-----------------------------------------------------------*/  /** Indicate that this symbol is a non-terminal. */  public boolean is_non_term()     {      return true;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** Test to see if this non terminal currently looks nullable. */  protected boolean looks_nullable() throws internal_error    {      /* 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;    }  /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/  /** convert to string */  public String toString()    {      return super.toString() + "[" + index() + "]" + (nullable() ? "*" : "");    }  /*-----------------------------------------------------------*/}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -