📄 production.java
字号:
* @param labelname the label name * @param stack_type the stack type of label? * @author frankf */ protected String make_declaration( String labelname, String stack_type, int offset) { String ret; /* Put in the left/right value labels */ if (emit.lr_values()) ret = "\t\tint " + labelname + "left = ((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + offset + ")).left;\n" + "\t\tint " + labelname + "right = ((java_cup.runtime.Symbol)" + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + offset + ")).right;\n"; else ret = ""; /* otherwise, just declare label. */ return ret + "\t\t" + stack_type + " " + labelname + " = (" + stack_type + ")((" + "java_cup.runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + offset + ")).value;\n"; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Declare label names as valid variables within the action string * @param rhs array of RHS parts. * @param rhs_len how much of rhs to consider valid. * @param final_action the final action string of the production. * @param lhs_type the object type associated with the LHS symbol. */ protected String declare_labels( production_part rhs[], int rhs_len, String final_action) { String declaration = ""; symbol_part part; action_part act_part; int pos; /* walk down the parts and extract the labels */ for (pos = 0; pos < rhs_len; pos++) { if (!rhs[pos].is_action()) { part = (symbol_part)rhs[pos]; /* if it has a label, make declaration! */ if (part.label() != null) { declaration = declaration + make_declaration(part.label(), part.the_symbol().stack_type(), rhs_len-pos-1); } } } return declaration; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Helper routine to merge adjacent actions in a set of RHS parts * @param rhs_parts array of RHS parts. * @param len amount of that array that is valid. * @return remaining valid length. */ protected int merge_adjacent_actions(production_part rhs_parts[], int len) { int from_loc, to_loc, merge_cnt; /* bail out early if we have no work to do */ if (rhs_parts == null || len == 0) return 0; merge_cnt = 0; to_loc = -1; for (from_loc=0; from_loc<len; from_loc++) { /* do we go in the current position or one further */ if (to_loc < 0 || !rhs_parts[to_loc].is_action() || !rhs_parts[from_loc].is_action()) { /* next one */ to_loc++; /* clear the way for it */ if (to_loc != from_loc) rhs_parts[to_loc] = null; } /* if this is not trivial? */ if (to_loc != from_loc) { /* do we merge or copy? */ if (rhs_parts[to_loc] != null && rhs_parts[to_loc].is_action() && rhs_parts[from_loc].is_action()) { /* merge */ rhs_parts[to_loc] = new action_part( ((action_part)rhs_parts[to_loc]).code_string() + ((action_part)rhs_parts[from_loc]).code_string()); merge_cnt++; } else { /* copy */ rhs_parts[to_loc] = rhs_parts[from_loc]; } } } /* return the used length */ return len - merge_cnt; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Helper routine to strip a trailing action off rhs and return it * @param rhs_parts array of RHS parts. * @param len how many of those are valid. * @return the removed action part. */ protected action_part strip_trailing_action( production_part rhs_parts[], int len) { action_part result; /* bail out early if we have nothing to do */ if (rhs_parts == null || len == 0) return null; /* see if we have a trailing action */ if (rhs_parts[len-1].is_action()) { /* snip it out and return it */ result = (action_part)rhs_parts[len-1]; rhs_parts[len-1] = null; return result; } else return null; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Remove all embedded actions from a production by factoring them * out into individual action production using new non terminals. * if the original production was: <pre> * A ::= B {action1} C {action2} D * </pre> * then it will be factored into: <pre> * A ::= B NT$1 C NT$2 D * NT$1 ::= {action1} * NT$2 ::= {action2} * </pre> * where NT$1 and NT$2 are new system created non terminals. */ /* the declarations added to the parent production are also passed along, as they should be perfectly valid in this code string, since it was originally a code string in the parent, not on its own. frank 6/20/96 */ protected void remove_embedded_actions( ) throws internal_error { non_terminal new_nt; production new_prod; String declare_str; /* walk over the production and process each action */ for (int act_loc = 0; act_loc < rhs_length(); act_loc++) if (rhs(act_loc).is_action()) { declare_str = declare_labels( _rhs, act_loc, ""); /* create a new non terminal for the action production */ new_nt = non_terminal.create_new(); new_nt.is_embedded_action = true; /* 24-Mar-1998, CSA */ /* create a new production with just the action */ new_prod = new action_production(this, new_nt, null, 0, declare_str + ((action_part)rhs(act_loc)).code_string()); /* replace the action with the generated non terminal */ _rhs[act_loc] = new symbol_part(new_nt); } } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Check to see if the production (now) appears to be nullable. * A production is nullable if its RHS could derive the empty string. * This results when the RHS is empty or contains only non terminals * which themselves are nullable. */ public boolean check_nullable() throws internal_error { production_part part; symbol sym; int pos; /* if we already know bail out early */ if (nullable_known()) return nullable(); /* if we have a zero size RHS we are directly nullable */ if (rhs_length() == 0) { /* stash and return the result */ return set_nullable(true); } /* otherwise we need to test all of our parts */ for (pos=0; pos<rhs_length(); pos++) { part = rhs(pos); /* only look at non-actions */ if (!part.is_action()) { sym = ((symbol_part)part).the_symbol(); /* if its a terminal we are definitely not nullable */ if (!sym.is_non_term()) return set_nullable(false); /* its a non-term, is it marked nullable */ else if (!((non_terminal)sym).nullable()) /* this one not (yet) nullable, so we aren't */ return false; } } /* if we make it here all parts are nullable */ return set_nullable(true); } /** set (and return) nullability */ boolean set_nullable(boolean v) { _nullable_known = true; _nullable = v; return v; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Update (and return) the first set based on current NT firsts. * This assumes that nullability has already been computed for all non * terminals and productions. */ public terminal_set check_first_set() throws internal_error { int part; symbol sym; /* walk down the right hand side till we get past all nullables */ for (part=0; part<rhs_length(); part++) { /* only look at non-actions */ if (!rhs(part).is_action()) { sym = ((symbol_part)rhs(part)).the_symbol(); /* is it a non-terminal?*/ if (sym.is_non_term()) { /* add in current firsts from that NT */ _first_set.add(((non_terminal)sym).first_set()); /* if its not nullable, we are done */ if (!((non_terminal)sym).nullable()) break; } else { /* its a terminal -- add that to the set */ _first_set.add((terminal)sym); /* we are done */ break; } } } /* return our updated first set */ return first_set(); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Equality comparison. */ public boolean equals(production other) { if (other == null) return false; return other._index == _index; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Generic equality comparison. */ public boolean equals(Object other) { if (!(other instanceof production)) return false; else return equals((production)other); } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Produce a hash code. */ public int hashCode() { /* just use a simple function of the index */ return _index*13; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Convert to a string. */ public String toString() { String result; /* catch any internal errors */ try { result = "production [" + index() + "]: "; result += ((lhs() != null) ? lhs().toString() : "$$NULL-LHS$$"); result += " :: = "; for (int i = 0; i<rhs_length(); i++) result += rhs(i) + " "; result += ";"; if (action() != null && action().code_string() != null) result += " {" + action().code_string() + "}"; if (nullable_known()) if (nullable()) result += "[NULLABLE]"; else result += "[NOT NULLABLE]"; } catch (internal_error e) { /* crash on internal error since we can't throw it from here (because superclass does not throw anything. */ e.crash(); result = null; } return result; } /*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Convert to a simpler string. */ public String to_simple_string() throws internal_error { String result; result = ((lhs() != null) ? lhs().the_symbol().name() : "NULL_LHS"); result += " ::= "; for (int i = 0; i < rhs_length(); i++) if (!rhs(i).is_action()) result += ((symbol_part)rhs(i)).the_symbol().name() + " "; return result; } /*-----------------------------------------------------------*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -