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

📄 optimizing

📁 java 编译器java复杂编译器,可以编译java文件的类库
💻
字号:
/* * 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. */This file describes in a step by step manner how you can modify thelookaheads in your grammar to optimize for space in the generatedparser.  This is only necessary until JavaCC is improved to do thisoptimization automatically (at which time, we will delete this file).1. How much space optimization can one expect?The optimizations that we show here gets rid of all methods in thegenerated parser which start with "jj_2" and "jj_3" respectively.  Sotake a look at your generated parser and figure out how much space isoccupied by these methods.  When we performed this optimization on theJava grammar, we were able to decrease the size of the generatedparser by more than 50%.2. Why are "jj_2" and "jj_3" methods generated?These methods are generated to handle all lookaheads except thefollowing:a. A syntactic lookahead of 1 (the most common situation).b. For any amount of syntactic lookahead - when the target expansion can   match the empty string.c. When the syntactic lookahead is 0.  Typically there is only semantic   lookahead this situation.The "jj_2" and "jj_3" methods are also generated for lookaheads in the(a) and (b) categories above when hoisting of semantic predicates isrequired.3. Summary of how we achieve the optimization:Essentially, we go through the entire grammar looking for choicepoints that are not one of (a), (b), or (c) above.  We then replacethe lookaheads at these points with one of kind (c) above.When we do this, JavaCC generates a parser where all the new semanticlookaheads causes hoisting which affect other related choice pointsand cause the "jj_2" and "jj_3" methods to be generated there.So the final step is to locate these related choice points and insertexplicit lookahead specifications here to prevent hoisting from takingplace.4. When is a grammar amenable to such optimization?If the majority of the choice points in your grammar use lookaheadsthat fall into the categories (a), (b), or (c) above then go for it.Otherwise, you'll be spending too much work and essentially rewritingthe entire parser.  It took a few hours to optimize the Java grammar.But I would not recommend doing it for C++ (for C++, just wait forJavaCC to be upgraded to do it automatically).5. Step by step instructions:Suppose your grammar file is called Grammar.jj.  You are going to gothrough two steps - in the first step, you create Grammar1.jj, andin the second step you create the final grammar file - Grammar2.jj.Lets also assume that the parsers generated from these grammar filesare Grammar.java, Grammar1.java, and Grammar2.java respectively.STEP 1:For every lookahead in your grammar that does not fit into categories(a), (b), or (c) above, replace it with an equivalent semanticlookahead.  When you're done with all such replacements, the resultingfile is Grammar1.jj.Example:In the Java1.1.jj grammar, we have the following production for Name:void Name() :{}{  <IDENTIFIER>  ( LOOKAHEAD(2)    "." <IDENTIFIER>  )*}It uses a lookahead of 2 - obviously this means that the choiceselection succeeds only if the next two characters are a "." andan <IDENTIFIER>.  The following modification replaces the syntacticlookahead with a semantic lookahead:void Name() :{}{  <IDENTIFIER>  ( LOOKAHEAD( { getToken(1).kind == DOT && getToken(2).kind == IDENTIFIER } )    "." <IDENTIFIER>  )*}STEP 2:Run JavaCC on both Grammar.jj and Grammar1.jj to obtain Grammar.javaand Grammar1.java.  Remember, the goal is to get rid of "jj_2" and"jj_3" methods from the grammar.  Changes are you will see a bunch of"jj_2" and "jj_3" methods in Grammar1.java.  We need to focus onlyon the "jj_2" methods.  When these methods are removed, the "jj_3"methods automatically go away too.  In the Java grammar, we found 23"jj_2" methods to get rid of in this step.Search for calls to "jj_2" methods in Grammar1.java.  Locate thecorresponding portions in Grammar1.jj (the choice points in the grammarcorresponding to these calls).  These calls are there to performhoisting (which you don't want - you don't need to understand hoistingto perform this step).Now look for corresponding locations in Grammar.java.  You will seereferences to a token mask array instead of a "jj_2" call at theselocations.  Take a look at the value of the token mask array.  Usethese values to create a new lookahead for this choice point to getrid of the "jj_2" call.The resulting grammar (Grammar2.jj) is the grammar you want.Obviously, we need an example:The Java parser generated after performing step 1 has the followingmethod with a call to a "jj_2" method ("jj_2_3"):  static final public void UnmodifiedInterfaceDeclaration() throws ParseException {    jj_consume_token(INTERFACE);    jj_consume_token(IDENTIFIER);    if (jj_mask_29[getToken(1).kind]) {      jj_consume_token(EXTENDS);      NameList();    } else {      jj_expLA1[29] = jj_gen;      ;    }    jj_consume_token(LBRACE);    label_8:    while (true) {      if (jj_2_3(1)) {        ;      } else {        break label_8;      }      InterfaceMemberDeclaration();    }    jj_consume_token(RBRACE);  }The corresponding location in the Java grammar is:void UnmodifiedInterfaceDeclaration() :{}{  "interface" <IDENTIFIER> [ "extends" NameList() ]  "{"    ( // <-- the choice point      InterfaceMemberDeclaration()    )*  "}"}The choice point corresponding to the call to "jj_2_3" above ismarked by the arrow.Now lets take a look at the parser generated from the original Javagrammar.  The above method is shown below:  static final public void UnmodifiedInterfaceDeclaration() throws ParseException {    jj_consume_token(INTERFACE);    jj_consume_token(IDENTIFIER);    if (jj_mask_40[getToken(1).kind]) {      jj_consume_token(EXTENDS);      NameList();    } else {      jj_expLA1[40] = jj_gen;      ;    }    jj_consume_token(LBRACE);    label_9:    while (true) {      if (jj_mask_41[getToken(1).kind]) {        ;      } else {        jj_expLA1[41] = jj_gen;        break label_9;      }      InterfaceMemberDeclaration();    }    jj_consume_token(RBRACE);  }Instead of the call to "jj_2_3", there is a reference to the tokenmask array "jj_mask_41".  Now take a look at the initialization of"jj_mask_41" that occurs a few lines further on:  static boolean[] jj_mask_41 = new boolean[120];  static {    jj_mask_41[ABSTRACT] =    jj_mask_41[BOOLEAN] =    jj_mask_41[BYTE] =    jj_mask_41[CHAR] =    jj_mask_41[CLASS] =    jj_mask_41[DOUBLE] =    jj_mask_41[FINAL] =    jj_mask_41[FLOAT] =    jj_mask_41[INT] =    jj_mask_41[INTERFACE] =    jj_mask_41[LONG] =    jj_mask_41[NATIVE] =    jj_mask_41[PRIVATE] =    jj_mask_41[PROTECTED] =    jj_mask_41[PUBLIC] =    jj_mask_41[SHORT] =    jj_mask_41[STATIC] =    jj_mask_41[SYNCHRONIZED] =    jj_mask_41[TRANSIENT] =    jj_mask_41[VOID] =    jj_mask_41[VOLATILE] =    jj_mask_41[IDENTIFIER] = true;  }This defines the tokens that must be matched at the choice pointin order for that choice point to succeed.  Use this to explicitlyinsert a lookahead specification into the grammar to prevent thehoisting of semantic predicates.  Hence the resulting productionin the final grammar is:void UnmodifiedInterfaceDeclaration() :{}{  "interface" <IDENTIFIER> [ "extends" NameList() ]  "{"    (      LOOKAHEAD(1, <ABSTRACT> | <BOOLEAN> | <BYTE> | <CHAR> | <CLASS> | <DOUBLE> |                   <FINAL> | <FLOAT> | <INT> | <INTERFACE> | <LONG> | <NATIVE> |                   <PRIVATE> | <PROTECTED> | <PUBLIC> | <SHORT> | <STATIC> |                   <SYNCHRONIZED> | <TRANSIENT> | <VOID> | <VOLATILE> | <IDENTIFIER>)      InterfaceMemberDeclaration()    )*  "}"}

⌨️ 快捷键说明

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