// Path: Mouse/source/utility/Convert.java
// public class Convert
// {
//   //-------------------------------------------------------------------
//   //  toCharLit
//   //-------------------------------------------------------------------
//   /**
//   *  Converts character to (unquoted) Java character literal
//   *  representing that character in ASCII encoding.
//   *  A character outside ASCII is converted to a Java escape.
//   *  In addition, a character literal must not be " or \.
//   *  These characters are also escaped.
//   *
//   *  @param  c the character.
//   *  @return literal representaton of c.
//   */
//   public static String toCharLit(char c)
//     {
//       switch(c)
//       {
//         case '\\': return("\\\\");
//         case '\'': return("\\\'");
//         default  : return(toRange(c,32,126));
//       }
//     }
// 
//   //-------------------------------------------------------------------
//   //  toStringLit
//   //-------------------------------------------------------------------
//   /**
//   *  Converts character string to (unquoted) Java string literal
//   *  representing that string in ASCII encoding.
//   *  Characters outside ASCII are converted to Java escapes.
//   *  In addition, a string literal must not contain " or \.
//   *  These characters are also escaped.
//   *
//   *  @param  s the string.
//   *  @return literal representaton of s.
//   */
//   public static String toStringLit(final String s)
//     {
//       StringBuilder sb = new StringBuilder();
//       for (int i=0;i<s.length();i++)
//       {
//         char c = s.charAt(i);
// 
//         switch(c)
//         {
//           case '"' : sb.append("\\\""); continue;
//           case '\\': sb.append("\\\\"); continue;
//           default  : sb.append(toRange(c,32,126)); continue;
//         }
//       }
//       return sb.toString();
//     }
// 
//   //-------------------------------------------------------------------
//   //  toPrint
//   //-------------------------------------------------------------------
//   public static String toPrint(final String s)
//   /**
//   *  Converts string to a printable / readable form.
//   *  Characters outside the range 32-255 are replaced by Java escapes.
//   *
//   *  @param  s the string.
//   *  @return printable representaton of s.
//   */
//     {
//       StringBuilder sb = new StringBuilder();
// 
//       for (int i=0;i<s.length();i++)
//         sb.append(toRange(s.charAt(i),32,255));
// 
//       return sb.toString();
//     }
// 
//   //-------------------------------------------------------------------
//   //  toComment
//   //-------------------------------------------------------------------
//   public static String toComment(final String s)
//   /**
//   *  Converts string to a form that can be generated as comment.
//   *  Java processes unicodes before recognizing comments.
//   *  A 'backslash u' in comment not followed by hex digits
//   *  is signaled as error. It is replaced by '\ u'
//   *  and then the result converted to printable.
//   *
//   *  @param  s the string.
//   *  @return comment representaton of s.
//   */
//     {
//       String temp = s;
//       return toPrint(temp.replace("\\u","\\ u"));
//     }
// 
//   //-------------------------------------------------------------------
//   //  toRange
//   //-------------------------------------------------------------------
//   private static String toRange(char c,int low,int high)
//   /**
//   *  If 'c' is outside the range 'low' through 'high' (inclusive),
//   *  return its representation as Java escape.
//   *  Otherwise return 'c' as a one-character string.
//   *
//   *  @param  c the character.
//   *  @return Representaton of c within the range.
//   */
//     {
//       switch(c)
//       {
//         case '\b': return("\\b");
//         case '\f': return("\\f");
//         case '\n': return("\\n");
//         case '\r': return("\\r");
//         case '\t': return("\\t");
//         default:
//           if (c<low || c>high)
//           {
//             String u = "000" + Integer.toHexString(c);
//             return("\\u" + u.substring(u.length()-4,u.length()));
//           }
//           else return Character.toString(c);
//       }
//     }
// 
//  }
// 
// Path: Mouse/source/runtime/Source.java
// public interface Source
// {
//   //-------------------------------------------------------------------
//   //  Is the wrapper correctly initialized?
//   //  The wrapper's constructor may encounter errors that result
//   //  in the object not being properly initialized.
//   //  The method returns 'false' if this is the case.
//   //-------------------------------------------------------------------
//   boolean created();
// 
//   //-------------------------------------------------------------------
//   //  Returns position of the last character plus 1
//   //  (= length of the sequence).
//   //-------------------------------------------------------------------
//   int end();
// 
//   //-------------------------------------------------------------------
//   //  Returns character at position p.
//   //-------------------------------------------------------------------
//   char at(int p);
// 
//   //-------------------------------------------------------------------
//   //  Returns characters at positions p through q-1.
//   //-------------------------------------------------------------------
//   String at(int p, int q);
// 
//   //-------------------------------------------------------------------
//   //  Describes position p in user's terms.
//   //-------------------------------------------------------------------
//   String where(int p);
// }


import java.util.Hashtable;
import java.util.HashSet;
import mouse.utility.Convert;
import mouse.runtime.Source;


  public void compact()
    {
      //---------------------------------------------------------------
      //  Use CompactVisitor to eliminate duplicate expressions
      //  from parse tree. (The result is no longer a tree.)
      //---------------------------------------------------------------
      CompactVisitor compactVisitor = new CompactVisitor();
      for (Expr r: rules)
        r.accept(compactVisitor);

      //---------------------------------------------------------------
      //  Build new expression lists.
      //---------------------------------------------------------------
      makeLists();
    }


  //=====================================================================
  //
  //  Show
  //
  //=====================================================================
  //-------------------------------------------------------------------
  //  showRules.
  //-------------------------------------------------------------------
  public void showRules()
    {
      System.out.println("\n" + rules.length + " rules");
      for (Expr.Rule r: rules)

// Path: Mouse/source/utility/Convert.java
// public class Convert
// {
//   //-------------------------------------------------------------------
//   //  toCharLit
//   //-------------------------------------------------------------------
//   /**
//   *  Converts character to (unquoted) Java character literal
//   *  representing that character in ASCII encoding.
//   *  A character outside ASCII is converted to a Java escape.
//   *  In addition, a character literal must not be " or \.
//   *  These characters are also escaped.
//   *
//   *  @param  c the character.
//   *  @return literal representaton of c.
//   */
//   public static String toCharLit(char c)
//     {
//       switch(c)
//       {
//         case '\\': return("\\\\");
//         case '\'': return("\\\'");
//         default  : return(toRange(c,32,126));
//       }
//     }
// 
//   //-------------------------------------------------------------------
//   //  toStringLit
//   //-------------------------------------------------------------------
//   /**
//   *  Converts character string to (unquoted) Java string literal
//   *  representing that string in ASCII encoding.
//   *  Characters outside ASCII are converted to Java escapes.
//   *  In addition, a string literal must not contain " or \.
//   *  These characters are also escaped.
//   *
//   *  @param  s the string.
//   *  @return literal representaton of s.
//   */
//   public static String toStringLit(final String s)
//     {
//       StringBuilder sb = new StringBuilder();
//       for (int i=0;i<s.length();i++)
//       {
//         char c = s.charAt(i);
// 
//         switch(c)
//         {
//           case '"' : sb.append("\\\""); continue;
//           case '\\': sb.append("\\\\"); continue;
//           default  : sb.append(toRange(c,32,126)); continue;
//         }
//       }
//       return sb.toString();
//     }
// 
//   //-------------------------------------------------------------------
//   //  toPrint
//   //-------------------------------------------------------------------
//   public static String toPrint(final String s)
//   /**
//   *  Converts string to a printable / readable form.
//   *  Characters outside the range 32-255 are replaced by Java escapes.
//   *
//   *  @param  s the string.
//   *  @return printable representaton of s.
//   */
//     {
//       StringBuilder sb = new StringBuilder();
// 
//       for (int i=0;i<s.length();i++)
//         sb.append(toRange(s.charAt(i),32,255));
// 
//       return sb.toString();
//     }
// 
//   //-------------------------------------------------------------------
//   //  toComment
//   //-------------------------------------------------------------------
//   public static String toComment(final String s)
//   /**
//   *  Converts string to a form that can be generated as comment.
//   *  Java processes unicodes before recognizing comments.
//   *  A 'backslash u' in comment not followed by hex digits
//   *  is signaled as error. It is replaced by '\ u'
//   *  and then the result converted to printable.
//   *
//   *  @param  s the string.
//   *  @return comment representaton of s.
//   */
//     {
//       String temp = s;
//       return toPrint(temp.replace("\\u","\\ u"));
//     }
// 
//   //-------------------------------------------------------------------
//   //  toRange
//   //-------------------------------------------------------------------
//   private static String toRange(char c,int low,int high)
//   /**
//   *  If 'c' is outside the range 'low' through 'high' (inclusive),
//   *  return its representation as Java escape.
//   *  Otherwise return 'c' as a one-character string.
//   *
//   *  @param  c the character.
//   *  @return Representaton of c within the range.
//   */
//     {
//       switch(c)
//       {
//         case '\b': return("\\b");
//         case '\f': return("\\f");
//         case '\n': return("\\n");
//         case '\r': return("\\r");
//         case '\t': return("\\t");
//         default:
//           if (c<low || c>high)
//           {
//             String u = "000" + Integer.toHexString(c);
//             return("\\u" + u.substring(u.length()-4,u.length()));
//           }
//           else return Character.toString(c);
//       }
//     }
// 
//  }
// 
// Path: Mouse/source/runtime/Source.java
// public interface Source
// {
//   //-------------------------------------------------------------------
//   //  Is the wrapper correctly initialized?
//   //  The wrapper's constructor may encounter errors that result
//   //  in the object not being properly initialized.
//   //  The method returns 'false' if this is the case.
//   //-------------------------------------------------------------------
//   boolean created();
// 
//   //-------------------------------------------------------------------
//   //  Returns position of the last character plus 1
//   //  (= length of the sequence).
//   //-------------------------------------------------------------------
//   int end();
// 
//   //-------------------------------------------------------------------
//   //  Returns character at position p.
//   //-------------------------------------------------------------------
//   char at(int p);
// 
//   //-------------------------------------------------------------------
//   //  Returns characters at positions p through q-1.
//   //-------------------------------------------------------------------
//   String at(int p, int q);
// 
//   //-------------------------------------------------------------------
//   //  Describes position p in user's terms.
//   //-------------------------------------------------------------------
//   String where(int p);
// }


// Path: Mouse/source/peg/PEG.java
import java.util.Hashtable;
import java.util.HashSet;
import mouse.utility.Convert;
import mouse.runtime.Source;


  public void compact()
    {
      //---------------------------------------------------------------
      //  Use CompactVisitor to eliminate duplicate expressions
      //  from parse tree. (The result is no longer a tree.)
      //---------------------------------------------------------------
      CompactVisitor compactVisitor = new CompactVisitor();
      for (Expr r: rules)
        r.accept(compactVisitor);

      //---------------------------------------------------------------
      //  Build new expression lists.
      //---------------------------------------------------------------
      makeLists();
    }


  //=====================================================================
  //
  //  Show
  //
  //=====================================================================
  //-------------------------------------------------------------------
  //  showRules.
  //-------------------------------------------------------------------
  public void showRules()
    {
      System.out.println("\n" + rules.length + " rules");
      for (Expr.Rule r: rules)

        System.out.println("  " + Convert.toPrint(r.asString()) + "   // " + attrs(r));
