in util/src/main/java/java_cup/production.java [71:176]
public production(
non_terminal lhs_sym,
production_part rhs_parts[],
int rhs_l,
String action_str)
throws internal_error
{
int i;
action_part tail_action;
String declare_str;
int rightlen = rhs_l;
/* remember the length */
if (rhs_l >= 0)
_rhs_length = rhs_l;
else if (rhs_parts != null)
_rhs_length = rhs_parts.length;
else
_rhs_length = 0;
/* make sure we have a valid left-hand-side */
if (lhs_sym == null)
throw new internal_error(
"Attempt to construct a production with a null LHS");
/* I'm not translating labels anymore, I'm adding code to declare
labels as valid variables. This way, the users code string is
untouched
6/96 frankf */
/* check if the last part of the right hand side is an action. If
it is, it won't be on the stack, so we don't want to count it
in the rightlen. Then when we search down the stack for a
Symbol, we don't try to search past action */
if (rhs_l > 0) {
if (rhs_parts[rhs_l - 1].is_action()) {
rightlen = rhs_l - 1;
} else {
rightlen = rhs_l;
}
}
/* get the generated declaration code for the necessary labels. */
declare_str = declare_labels(
rhs_parts, rightlen, action_str);
if (action_str == null)
action_str = declare_str;
else
action_str = declare_str + action_str;
/* count use of lhs */
lhs_sym.note_use();
/* create the part for left-hand-side */
_lhs = new symbol_part(lhs_sym);
/* merge adjacent actions (if any) */
_rhs_length = merge_adjacent_actions(rhs_parts, _rhs_length);
/* strip off any trailing action */
tail_action = strip_trailing_action(rhs_parts, _rhs_length);
if (tail_action != null) _rhs_length--;
/* Why does this run through the right hand side happen
over and over? here a quick combination of two
prior runs plus one I wanted of my own
frankf 6/25/96 */
/* allocate and copy over the right-hand-side */
/* count use of each rhs symbol */
_rhs = new production_part[_rhs_length];
for (i=0; i<_rhs_length; i++) {
_rhs[i] = rhs_parts[i];
if (!_rhs[i].is_action()) {
((symbol_part)_rhs[i]).the_symbol().note_use();
if (((symbol_part)_rhs[i]).the_symbol() instanceof terminal) {
_rhs_prec =
((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_num();
_rhs_assoc =
((terminal)((symbol_part)_rhs[i]).the_symbol()).precedence_side();
}
}
}
/*now action string is really declaration string, so put it in front!
6/14/96 frankf */
if (action_str == null) action_str = "";
if (tail_action != null && tail_action.code_string() != null)
action_str = action_str + "\t\t" + tail_action.code_string();
/* stash the action */
_action = new action_part(action_str);
/* rewrite production to remove any embedded actions */
remove_embedded_actions();
/* assign an index */
_index = next_index++;
/* put us in the global collection of productions */
_all.put(new Integer(_index),this);
/* put us in the production list of the lhs non terminal */
lhs_sym.add_production(this);
}