Logo Search packages:      
Sourcecode: jasmin-sable version File versions  Download package

static void java_cup::emit::emit_action_code ( PrintWriter  out,
production  start_prod 
) throws internal_error [inline, static, protected]

Emit code for the non-public class holding the actual action code.

Parameters:
out stream to produce output on.
start_prod the start production of the grammar.

Definition at line 312 of file emit.java.

References java_cup::production::action(), action_code, action_code_time, java_cup::action_part::code_string(), java_cup::action_part::equals(), java_cup::symbol::index(), java_cup::production::index(), java_cup::production::lhs(), java_cup::symbol::name(), parser_class_name, pre(), java_cup::production::rhs(), java_cup::production::rhs_length(), java_cup::symbol::stack_type(), java_cup::symbol_part::the_symbol(), and java_cup::production::to_simple_string().

Referenced by parser().

    {
      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;
    }


Generated by  Doxygen 1.6.0   Back to index