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

📄 parseengine.java

📁 java 编译器java复杂编译器,可以编译java文件的类库
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Copyright © 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, * California 95054, U.S.A. All rights reserved.  Sun Microsystems, Inc. has * intellectual property rights relating to technology embodied in the product * that is described in this document. In particular, and without limitation, * these intellectual property rights may include one or more of the U.S. * patents listed at http://www.sun.com/patents and one or more additional * patents or pending patent applications in the U.S. and in other countries. * U.S. Government Rights - Commercial software. Government users are subject * to the Sun Microsystems, Inc. standard license agreement and applicable * provisions of the FAR and its supplements.  Use is subject to license terms. * Sun,  Sun Microsystems,  the Sun logo and  Java are trademarks or registered * trademarks of Sun Microsystems, Inc. in the U.S. and other countries.  This * product is covered and controlled by U.S. Export Control laws and may be * subject to the export or import laws in other countries.  Nuclear, missile, * chemical biological weapons or nuclear maritime end uses or end users, * whether direct or indirect, are strictly prohibited.  Export or reexport * to countries subject to U.S. embargo or to entities identified on U.S. * export exclusion lists, including, but not limited to, the denied persons * and specially designated nationals lists is strictly prohibited. */package org.javacc.parser;import java.util.Hashtable;import java.util.*;public class ParseEngine extends JavaCCGlobals {  static private java.io.PrintWriter ostr;  static private int gensymindex = 0;  static private int indentamt;  static private boolean jj2LA;  /**   * These lists are used to maintain expansions for which code generation   * in phase 2 and phase 3 is required.  Whenever a call is generated to   * a phase 2 or phase 3 routine, a corresponding entry is added here if   * it has not already been added.   * The phase 3 routines have been optimized in version 0.7pre2.  Essentially   * only those methods (and only those portions of these methods) are   * generated that are required.  The lookahead amount is used to determine   * this.  This change requires the use of a hash table because it is now   * possible for the same phase 3 routine to be requested multiple times   * with different lookaheads.  The hash table provides a easily searchable   * capability to determine the previous requests.   * The phase 3 routines now are performed in a two step process - the first   * step gathers the requests (replacing requests with lower lookaheads with   * those requiring larger lookaheads).  The second step then generates these   * methods.   * This optimization and the hashtable makes it look like we do not need   * the flag "phase3done" any more.  But this has not been removed yet.   */  static private java.util.Vector phase2list = new java.util.Vector();  static private java.util.Vector phase3list = new java.util.Vector();  static private java.util.Hashtable phase3table = new java.util.Hashtable();  /**   * The phase 1 routines generates their output into String's and dumps   * these String's once for each method.  These String's contain the   * special characters '\u0001' to indicate a positive indent, and '\u0002'   * to indicate a negative indent.  '\n' is used to indicate a line terminator.   * The characters '\u0003' and '\u0004' are used to delineate portions of   * text where '\n's should not be followed by an indentation.   */  /**   * Returns true if there is a JAVACODE production that the argument expansion   * may directly expand to (without consuming tokens).   */  static private boolean javaCodeCheck(Expansion exp) {    if (exp instanceof RegularExpression) {      return false;    } else if (exp instanceof NonTerminal) {      NormalProduction prod = ((NonTerminal)exp).prod;      if (prod instanceof JavaCodeProduction) {        return true;      } else {        return javaCodeCheck(prod.expansion);      }    } else if (exp instanceof Choice) {      Choice ch = (Choice)exp;      for (int i = 0; i < ch.choices.size(); i++) {        if (javaCodeCheck((Expansion)(ch.choices.elementAt(i)))) {          return true;        }      }      return false;    } else if (exp instanceof Sequence) {      Sequence seq = (Sequence)exp;      for (int i = 0; i < seq.units.size(); i++) {        if (javaCodeCheck((Expansion)(seq.units.elementAt(i)))) {          return true;        } else if (!Semanticize.emptyExpansionExists((Expansion)(seq.units.elementAt(i)))) {          return false;        }      }      return false;    } else if (exp instanceof OneOrMore) {      OneOrMore om = (OneOrMore)exp;      return javaCodeCheck(om.expansion);    } else if (exp instanceof ZeroOrMore) {      ZeroOrMore zm = (ZeroOrMore)exp;      return javaCodeCheck(zm.expansion);    } else if (exp instanceof ZeroOrOne) {      ZeroOrOne zo = (ZeroOrOne)exp;      return javaCodeCheck(zo.expansion);    } else if (exp instanceof TryBlock) {      TryBlock tb = (TryBlock)exp;      return javaCodeCheck(tb.exp);    } else {      return false;    }  }  /**   * An array used to store the first sets generated by the following method.   * A true entry means that the corresponding token is in the first set.   */  static private boolean[] firstSet;  /**   * Sets up the array "firstSet" above based on the Expansion argument   * passed to it.  Since this is a recursive function, it assumes that   * "firstSet" has been reset before the first call.   */  static private void genFirstSet(Expansion exp) {    if (exp instanceof RegularExpression) {      firstSet[((RegularExpression)exp).ordinal] = true;    } else if (exp instanceof NonTerminal) {      genFirstSet(((BNFProduction)(((NonTerminal)exp).prod)).expansion);    } else if (exp instanceof Choice) {      Choice ch = (Choice)exp;      for (int i = 0; i < ch.choices.size(); i++) {        genFirstSet((Expansion)(ch.choices.elementAt(i)));      }    } else if (exp instanceof Sequence) {      Sequence seq = (Sequence)exp;      Object obj = seq.units.elementAt(0);      if ((obj instanceof Lookahead) && (((Lookahead)obj).action_tokens.size() != 0)) {        jj2LA = true;      }      for (int i = 0; i < seq.units.size(); i++) {        genFirstSet((Expansion)(seq.units.elementAt(i)));        if (!Semanticize.emptyExpansionExists((Expansion)(seq.units.elementAt(i)))) {          break;        }      }    } else if (exp instanceof OneOrMore) {      OneOrMore om = (OneOrMore)exp;      genFirstSet(om.expansion);    } else if (exp instanceof ZeroOrMore) {      ZeroOrMore zm = (ZeroOrMore)exp;      genFirstSet(zm.expansion);    } else if (exp instanceof ZeroOrOne) {      ZeroOrOne zo = (ZeroOrOne)exp;      genFirstSet(zo.expansion);    } else if (exp instanceof TryBlock) {      TryBlock tb = (TryBlock)exp;      genFirstSet(tb.exp);    }  }  /**   * Constants used in the following method "buildLookaheadChecker".   */  static final int NOOPENSTM = 0;  static final int OPENIF = 1;  static final int OPENSWITCH = 2;  /**   * This method takes two parameters - an array of Lookahead's   * "conds", and an array of String's "actions".  "actions" contains   * exactly one element more than "conds".  "actions" are Java source   * code, and "conds" translate to conditions - so lets say   * "f(conds[i])" is true if the lookahead required by "conds[i]" is   * indeed the case.  This method returns a string corresponding to   * the Java code for:   *   *   if (f(conds[0]) actions[0]   *   else if (f(conds[1]) actions[1]   *   . . .   *   else actions[action.length-1]   *   * A particular action entry ("actions[i]") can be null, in which   * case, a noop is generated for that action.   */  static String buildLookaheadChecker(Lookahead[] conds, String[] actions) {    // The state variables.    int state = NOOPENSTM;    int indentAmt = 0;    boolean[] casedValues = new boolean[tokenCount];    String retval = "";    Lookahead la;    Token t = null;    int tokenMaskSize = (tokenCount-1)/32 + 1;    int[] tokenMask = null;    // Iterate over all the conditions.    int index = 0;    while (index < conds.length) {      la = conds[index];      jj2LA = false;      if ((la.amount == 0) ||	  Semanticize.emptyExpansionExists(la.la_expansion) ||	  javaCodeCheck(la.la_expansion)	 ) {	// This handles the following cases:	// . If syntactic lookahead is not wanted (and hence explicitly specified	//   as 0).	// . If it is possible for the lookahead expansion to recognize the empty	//   string - in which case the lookahead trivially passes.	// . If the lookahead expansion has a JAVACODE production that it directly	//   expands to - in which case the lookahead trivially passes.	if (la.action_tokens.size() == 0) {	  // In addition, if there is no semantic lookahead, then the	  // lookahead trivially succeeds.  So break the main loop and	  // treat this case as the default last action.	  break;	} else {	  // This case is when there is only semantic lookahead	  // (without any preceding syntactic lookahead).  In this	  // case, an "if" statement is generated.	  switch (state) {	  case NOOPENSTM:	    retval += "\n" + "if (";	    indentAmt++;	    break;	  case OPENIF:	    retval += "\u0002\n" + "} else if (";	    break;	  case OPENSWITCH:	    retval += "\u0002\n" + "default:" + "\u0001";	    if (Options.B("ERROR_REPORTING")) {	      retval += "\njj_la1[" + maskindex + "] = jj_gen;";	      maskindex++;	    }	    maskVals.addElement(tokenMask);	    retval += "\n" + "if (";	    indentAmt++;	  }	  printTokenSetup((Token)(la.action_tokens.elementAt(0)));	  for (java.util.Enumeration enum = la.action_tokens.elements(); enum.hasMoreElements();) {	    t = (Token)enum.nextElement();	    retval += printToken(t);	  }	  retval += printTrailingComments(t);	  retval += ") {\u0001" + actions[index];	  state = OPENIF;	}      } else if (la.amount == 1 && la.action_tokens.size() == 0) {	// Special optimal processing when the lookahead is exactly 1, and there	// is no semantic lookahead.	if (firstSet == null) {	  firstSet = new boolean[tokenCount];	}	for (int i = 0; i < tokenCount; i++) {	  firstSet[i] = false;	}	// jj2LA is set to false at the beginning of the containing "if" statement.	// It is checked immediately after the end of the same statement to determine	// if lookaheads are to be performed using calls to the jj2 methods.	genFirstSet(la.la_expansion);	// genFirstSet may find that semantic attributes are appropriate for the next	// token.  In which case, it sets jj2LA to true.	if (!jj2LA) {	  // This case is if there is no applicable semantic lookahead and the lookahead	  // is one (excluding the earlier cases such as JAVACODE, etc.).	  switch (state) {	  case OPENIF:	    retval += "\u0002\n" + "} else {\u0001";	    // Control flows through to next case.	  case NOOPENSTM:	    retval += "\n" + "switch (";	    if (Options.B("CACHE_TOKENS")) {	      retval += "jj_nt.kind) {\u0001";	    } else {	      retval += "(jj_ntk==-1)?jj_ntk():jj_ntk) {\u0001";	    }	    for (int i = 0; i < tokenCount; i++) {	      casedValues[i] = false;	    }	    indentAmt++;	    tokenMask = new int[tokenMaskSize];	    for (int i = 0; i < tokenMaskSize; i++) {	      tokenMask[i] = 0;	    }          // Don't need to do anything if state is OPENSWITCH.	  }	  for (int i = 0; i < tokenCount; i++) {	    if (firstSet[i]) {	      if (!casedValues[i]) {		casedValues[i] = true;		retval += "\u0002\ncase ";		int j1 = i/32;		int j2 = i%32;		tokenMask[j1] |= 1 << j2;		String s = (String)(names_of_tokens.get(new Integer(i)));		if (s == null) {		  retval += i;		} else {		  retval += s;		}		retval += ":\u0001";	      }	    }	  }	  retval += actions[index];	  retval += "\nbreak;";	  state = OPENSWITCH;	}      } else {	// This is the case when lookahead is determined through calls to	// jj2 methods.  The other case is when lookahead is 1, but semantic	// attributes need to be evaluated.  Hence this crazy control structure.	jj2LA = true;      }      if (jj2LA) {	// In this case lookahead is determined by the jj2 methods.	switch (state) {	case NOOPENSTM:	  retval += "\n" + "if (";	  indentAmt++;	  break;	case OPENIF:	  retval += "\u0002\n" + "} else if (";	  break;	case OPENSWITCH:	  retval += "\u0002\n" + "default:" + "\u0001";	  if (Options.B("ERROR_REPORTING")) {	    retval += "\njj_la1[" + maskindex + "] = jj_gen;";	    maskindex++;	  }	  maskVals.addElement(tokenMask);	  retval += "\n" + "if (";	  indentAmt++;	}	jj2index++;	// At this point, la.la_expansion.internal_name must be "".	la.la_expansion.internal_name = "_" + jj2index;	phase2list.addElement(la);	retval += "jj_2" + la.la_expansion.internal_name + "(" + la.amount + ")";	if (la.action_tokens.size() != 0) {	  // In addition, there is also a semantic lookahead.  So concatenate	  // the semantic check with the syntactic one.	  retval += " && (";	  printTokenSetup((Token)(la.action_tokens.elementAt(0)));	  for (java.util.Enumeration enum = la.action_tokens.elements(); enum.hasMoreElements();) {	    t = (Token)enum.nextElement();	    retval += printToken(t);	  }	  retval += printTrailingComments(t);	  retval += ")";	}	retval += ") {\u0001" + actions[index];	state = OPENIF;      }      index++;    }    // Generate code for the default case.  Note this may not    // be the last entry of "actions" if any condition can be    // statically determined to be always "true".    switch (state) {    case NOOPENSTM:      retval += actions[index];      break;    case OPENIF:      retval += "\u0002\n" + "} else {\u0001" + actions[index];      break;    case OPENSWITCH:      retval += "\u0002\n" + "default:" + "\u0001";      if (Options.B("ERROR_REPORTING")) {	retval += "\njj_la1[" + maskindex + "] = jj_gen;";	maskVals.addElement(tokenMask);	maskindex++;      }      retval += actions[index];    }    for (int i = 0; i < indentAmt; i++) {      retval += "\u0002\n}";

⌨️ 快捷键说明

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