📄 emit.java
字号:
out.println(); symbols_time = System.currentTimeMillis() - start_time; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Emit code for the non-public class holding the actual action code. * @param out stream to produce output on. * @param start_prod the start production of the grammar. */ protected static void emit_action_code(PrintWriter out, production start_prod) throws internal_error { production prod; long start_time = System.currentTimeMillis(); /* class header */ out.println(); out.println( "/** Cup generated class to encapsulate user supplied action code.*/" ); out.println("class " + pre("actions") + " {"); /* user supplied code */ if (action_code != null) { out.println(); out.println(action_code); } /* field for parser object */ out.println(" private final "+parser_class_name+" parser;"); /* constructor */ out.println(); out.println(" /** Constructor */"); out.println(" " + pre("actions") + "("+parser_class_name+" parser) {"); out.println(" this.parser = parser;"); out.println(" }"); /* action method head */ out.println(); out.println(" /** Method with the actual generated action code. */"); out.println(" public final java_cup.runtime.Symbol " + pre("do_action") + "("); out.println(" int " + pre("act_num,")); out.println(" java_cup.runtime.lr_parser " + pre("parser,")); out.println(" java.util.Stack " + pre("stack,")); out.println(" int " + pre("top)")); out.println(" throws java.lang.Exception"); out.println(" {"); /* declaration of result symbol */ /* New declaration!! now return Symbol 6/13/96 frankf */ out.println(" /* Symbol object for return from actions */"); out.println(" java_cup.runtime.Symbol " + pre("result") + ";"); out.println(); /* switch top */ out.println(" /* select the action based on the action number */"); out.println(" switch (" + pre("act_num") + ")"); out.println(" {"); /* emit action code for each production as a separate case */ for (Enumeration p = production.all(); p.hasMoreElements(); ) { prod = (production)p.nextElement(); /* case label */ out.println(" /*. . . . . . . . . . . . . . . . . . . .*/"); out.println(" case " + prod.index() + ": // " + prod.to_simple_string()); /* give them their own block to work in */ out.println(" {"); /* create the result symbol */ /*make the variable RESULT which will point to the new Symbol (see below) and be changed by action code 6/13/96 frankf */ out.println(" " + prod.lhs().the_symbol().stack_type() + " RESULT = null;"); /* Add code to propagate RESULT assignments that occur in * action code embedded in a production (ie, non-rightmost * action code). 24-Mar-1998 CSA */ for (int i=0; i<prod.rhs_length(); i++) { // only interested in non-terminal symbols. if (!(prod.rhs(i) instanceof symbol_part)) continue; symbol s = ((symbol_part)prod.rhs(i)).the_symbol(); if (!(s instanceof non_terminal)) continue; // skip this non-terminal unless it corresponds to // an embedded action production. if (((non_terminal)s).is_embedded_action == false) continue; // OK, it fits. Make a conditional assignment to RESULT. int index = prod.rhs_length() - i - 1; // last rhs is on top. out.println(" " + "// propagate RESULT from " + s.name()); out.println(" " + "if ( " + "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + index + ")).value != null )"); out.println(" " + "RESULT = " + "(" + prod.lhs().the_symbol().stack_type() + ") " + "((java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + index + ")).value;"); } /* if there is an action string, emit it */ if (prod.action() != null && prod.action().code_string() != null && !prod.action().equals("")) out.println(prod.action().code_string()); /* here we have the left and right values being propagated. must make this a command line option. frankf 6/18/96 */ /* Create the code that assigns the left and right values of the new Symbol that the production is reducing to */ if (emit.lr_values()) { int loffset; String leftstring, rightstring; int roffset = 0; rightstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + roffset + ")).right"; if (prod.rhs_length() == 0) leftstring = rightstring; else { loffset = prod.rhs_length() - 1; leftstring = "((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + loffset + ")).left"; } out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" + prod.lhs().the_symbol().index() + "/*" + prod.lhs().the_symbol().name() + "*/" + ", " + leftstring + ", " + rightstring + ", RESULT);"); } else { out.println(" " + pre("result") + " = new java_cup.runtime.Symbol(" + prod.lhs().the_symbol().index() + "/*" + prod.lhs().the_symbol().name() + "*/" + ", RESULT);"); } /* end of their block */ out.println(" }"); /* if this was the start production, do action for accept */ if (prod == start_prod) { out.println(" /* ACCEPT */"); out.println(" " + pre("parser") + ".done_parsing();"); } /* code to return lhs symbol */ out.println(" return " + pre("result") + ";"); out.println(); } /* end of switch */ out.println(" /* . . . . . .*/"); out.println(" default:"); out.println(" throw new Exception("); out.println(" \"Invalid action number found in " + "internal parse table\");"); out.println(); out.println(" }"); /* end of method */ out.println(" }"); /* end of class */ out.println("}"); out.println(); action_code_time = System.currentTimeMillis() - start_time; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Emit the production table. * @param out stream to produce output on. */ protected static void emit_production_table(PrintWriter out) { production all_prods[]; production prod; long start_time = System.currentTimeMillis(); /* collect up the productions in order */ all_prods = new production[production.number()]; for (Enumeration p = production.all(); p.hasMoreElements(); ) { prod = (production)p.nextElement(); all_prods[prod.index()] = prod; } // make short[][] short[][] prod_table = new short[production.number()][2]; for (int i = 0; i<production.number(); i++) { prod = all_prods[i]; // { lhs symbol , rhs size } prod_table[i][0] = (short) prod.lhs().the_symbol().index(); prod_table[i][1] = (short) prod.rhs_length(); } /* do the top of the table */ out.println(); out.println(" /** Production table. */"); out.println(" protected static final short _production_table[][] = "); out.print (" unpackFromStrings("); do_table_as_string(out, prod_table); out.println(");"); /* do the public accessor method */ out.println(); out.println(" /** Access to production table. */"); out.println(" public short[][] production_table() " + "{return _production_table;}"); production_table_time = System.currentTimeMillis() - start_time; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Emit the action table. * @param out stream to produce output on. * @param act_tab the internal representation of the action table. * @param compact_reduces do we use the most frequent reduce as default? */ protected static void do_action_table( PrintWriter out, parse_action_table act_tab, boolean compact_reduces) throws internal_error { parse_action_row row; parse_action act; int red; long start_time = System.currentTimeMillis(); /* collect values for the action table */ short[][] action_table = new short[act_tab.num_states()][]; /* do each state (row) of the action table */ for (int i = 0; i < act_tab.num_states(); i++) { /* get the row */ row = act_tab.under_state[i]; /* determine the default for the row */ if (compact_reduces) row.compute_default(); else row.default_reduce = -1; /* make temporary table for the row. */ short[] temp_table = new short[2*row.size()]; int nentries = 0; /* do each column */ for (int j = 0; j < row.size(); j++) { /* extract the action from the table */ act = row.under_term[j]; /* skip error entries these are all defaulted out */ if (act.kind() != parse_action.ERROR) { /* first put in the symbol index, then the actual entry */ /* shifts get positive entries of state number + 1 */ if (act.kind() == parse_action.SHIFT) { /* make entry */ temp_table[nentries++] = (short) j; temp_table[nentries++] = (short) (((shift_action)act).shift_to().index() + 1); } /* reduce actions get negated entries of production# + 1 */ else if (act.kind() == parse_action.REDUCE) { /* if its the default entry let it get defaulted out */ red = ((reduce_action)act).reduce_with().index(); if (red != row.default_reduce) { /* make entry */ temp_table[nentries++] = (short) j; temp_table[nentries++] = (short) (-(red+1)); } } else if (act.kind() == parse_action.NONASSOC) { /* do nothing, since we just want a syntax error */ } /* shouldn't be anything else */ else throw new internal_error("Unrecognized action code " +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -