/*-----------------------------------------------------------*/ /*--- General Methods ---------------------------------------*/ /*-----------------------------------------------------------*/ /** Add a transition out of this state to another. * @param on_sym the symbol the transition is under. * @param to_st the state the transition goes to. */ public void add_transition(symbol on_sym, lalr_state to_st) { lalr_transition trans; /* create a new transition object and put it in our list */ trans = new lalr_transition(on_sym, to_st, _transitions); _transitions = trans; }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Add a single symbol to the Set. * @param sym the symbol we are adding. * @return true if this changes the Set. */ public bool add(symbol sym) { // object previous; not_null(sym); /* put the object in */ try { _all.Add(sym.name(), sym); } catch { return(false); } /* if we had a previous, this is no change */ //return previous == null; return(true); }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Add a single symbol to the Set. * @param sym the symbol we are adding. * @return true if this changes the Set. */ public bool add(symbol sym) { // object previous; not_null(sym); /* put the object in */ try { _all.Add(sym.name(),sym); } catch { return false; } /* if we had a previous, this is no change */ //return previous == null; return true; }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** 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(TextWriter cout, production start_prod) { production prod; long start_time = DateTime.Now.Ticks; /* class header */ cout.WriteLine(); cout.WriteLine( "/** Cup generated class to encapsulate user supplied action code.*/" ); cout.WriteLine("public class " + pre("actions") + " {"); /* user supplied code */ if (action_code != null) { cout.WriteLine(); cout.WriteLine(action_code); } /* field for parser object */ cout.WriteLine(" private " + parser_class_name + " my_parser;"); /* constructor */ cout.WriteLine(); cout.WriteLine(" /** Constructor */"); cout.WriteLine(" public " + pre("actions") + "(" + parser_class_name + " t_parser) {"); cout.WriteLine(" this.my_parser = t_parser;"); cout.WriteLine(" }"); /* action method head */ cout.WriteLine(); cout.WriteLine(" /** Method with the actual generated action code. */"); cout.WriteLine(" public TUVienna.CS_CUP.Runtime.Symbol " + pre("do_action") + "("); cout.WriteLine(" int " + pre("act_num,")); cout.WriteLine(" TUVienna.CS_CUP.Runtime.lr_parser " + pre("parser,")); cout.WriteLine(" System.Collections.Stack xstack1,"); cout.WriteLine(" int " + pre("top)")); // cout.WriteLine(" throws java.lang.Exception"); cout.WriteLine(" {"); /* declaration of result symbol */ /* New declaration!! now return Symbol * 6/13/96 frankf */ cout.WriteLine(" /* Symbol object for return from actions */"); cout.WriteLine(" mStack " + pre("stack") + " =new mStack(xstack1);"); cout.WriteLine(" TUVienna.CS_CUP.Runtime.Symbol " + pre("result") + ";"); cout.WriteLine(); /* switch top */ cout.WriteLine(" /* select the action based on the action number */"); cout.WriteLine(" switch (" + pre("act_num") + ")"); cout.WriteLine(" {"); /* emit action code for each production as a separate case */ IEnumerator p = production.all(); while (p.MoveNext()) { prod = (production)p.Current; /* case label */ cout.WriteLine(" /*. . . . . . . . . . . . . . . . . . . .*/"); cout.WriteLine(" case " + prod.index() + ": // " + prod.to_simple_string()); /* give them their own block to work in */ cout.WriteLine(" {"); /* 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 */ cout.WriteLine(" " + 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).GetType() != typeof(symbol_part)) { continue; } symbol s = ((symbol_part)prod.rhs(i)).the_symbol(); if (s.GetType() != typeof(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. cout.WriteLine(" " + "// propagate RESULT from " + s.name()); cout.WriteLine(" " + "if ( " + "((TUVienna.CS_CUP.Runtime.Symbol) " + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + index + ")).value != null )"); cout.WriteLine(" " + "RESULT = " + "(" + prod.lhs().the_symbol().stack_type() + ") " + "((TUVienna.CS_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("")) { cout.WriteLine(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 = "((TUVienna.CS_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 = "((TUVienna.CS_CUP.Runtime.Symbol)" + emit.pre("stack") + ".elementAt(" + emit.pre("top") + "-" + loffset + ")).left"; } cout.WriteLine(" " + pre("result") + " = new TUVienna.CS_CUP.Runtime.Symbol(" + prod.lhs().the_symbol().index() + "/*" + prod.lhs().the_symbol().name() + "*/" + ", " + leftstring + ", " + rightstring + ", RESULT);"); } else { cout.WriteLine(" " + pre("result") + " = new TUVienna.CS_CUP.Runtime.Symbol(" + prod.lhs().the_symbol().index() + "/*" + prod.lhs().the_symbol().name() + "*/" + ", RESULT);"); } /* end of their block */ cout.WriteLine(" }"); /* if this was the start production, do action for accept */ if (prod == start_prod) { cout.WriteLine(" /* ACCEPT */"); cout.WriteLine(" " + pre("parser") + ".done_parsing();"); } /* code to return lhs symbol */ cout.WriteLine(" return " + pre("result") + ";"); cout.WriteLine(); } /* end of switch */ cout.WriteLine(" /* . . . . . .*/"); cout.WriteLine(" default:"); cout.WriteLine(" throw new System.Exception("); cout.WriteLine(" \"Invalid action number found in " + "internal parse table\");"); cout.WriteLine(); cout.WriteLine(" }"); /* end of method */ cout.WriteLine(" }"); /* end of class */ cout.WriteLine("}"); cout.WriteLine(); action_code_time = DateTime.Now.Ticks - start_time; }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Determine if the Set contains a particular symbol. * @param sym the symbol we are looking for. */ public bool contains(symbol sym) {return _all.ContainsKey(sym.name());}
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Remove a single symbol if it is in the Set. * @param sym the symbol we are removing. */ public void remove(symbol sym) { not_null(sym); _all.Remove(sym.name()); }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Determine if the Set contains a particular symbol. * @param sym the symbol we are looking for. */ public bool contains(symbol sym) { return(_all.ContainsKey(sym.name())); }
/*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .*/ /** Remove a single symbol if it is in the Set. * @param sym the symbol we are removing. */ public void remove(symbol sym) { not_null(sym); _all.Remove(sym.name()); }
/*-----------------------------------------------------------*/ /*--- General Methods ---------------------------------------*/ /*-----------------------------------------------------------*/ /** Add a transition out of this state to another. * @param on_sym the symbol the transition is under. * @param to_st the state the transition goes to. */ public void add_transition(symbol on_sym, lalr_state to_st) { lalr_transition trans; /* create a new transition object and put it in our list */ trans = new lalr_transition(on_sym, to_st, _transitions); _transitions = trans; }