import java.io.*;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.util.StringTokenizer;

/** class GrammarConverter
 *
 *  Construct a file containing a Java class definition that instantiates a
 *  Diagram for each diagram definition encountered in the input file.
 */
public class GrammarConverter {

    public static final int BEGIN_DIAGRAM = '(';
    public static final int END_DIAGRAM   = ')';

    private static final String DIAGRAM_KEY = "diagram";
    private static final String REG_KEY = "regularexp";
    private static int     _lineNumber = 1;
    private static int     _index = 6;
    private static boolean _errorFlag = false;

    private static int       _indent = 0;
    private static Hashtable _vectors = new Hashtable();
    private static Vector  _nonTerminalNames = new Vector();
    private static Vector  _nonTerminalDefined = new Vector();
    private static int       _vectorCnt = 0;
    private static int       _maxVectorCnt = 0;

    
    public String []  lowerCase ;
    public String []  upperCase;
    private String [] tokenString;
    public String [] slashChars;
    public String [] digits;
    public String [] singleChars;

    private static FileOutputStream _oStream;

    public GrammarConverter() {
    }

    // Create a file whose name is specified on the command line with the
    // <classname> argument. Add to the output file
    //     1) a Java class header
    //     2) the Java code necessary to construct the diagrams defined in the
    //        input file specified on the command line with the <filename>
    //        arguement
    //     3) a Java class ending
    public static void main(String[] args) {
        if (args.length < 2) {
            System.out.println(
                "Syntax: java GrammarConverter <filename> <classname>\n");
            System.out.println(
                "     <filename>   full path name of the file to be parsed");
            System.out.println(
                "     <classname>  name of the class file to be created");
        }
        else {
            try {
                _oStream = new FileOutputStream(args[1] + ".java");
            }
            catch (IOException e) {
                System.out.println("Error opening output file");
                e.printStackTrace();
                return;
            }

            output(
                "// This file was created by the GrammarConverter from the " +
                "definitions \n//contained in " + args[0] + ".\n" +
                "// The " + args[1] + " class just creates the Diagrams "+
                "in it's initialization \n" + "// routine and adds the" +
                " diagrams created, to the vector 'diagramList'.\n" +
                "// The CurryDiagram class accesses the Diagrams by " +
                "creating an instance \n// of class Grammar " +
                "and accessing the vector diagramList.\n\n\n" +
                "import java.util.Vector;\n\n" +
                "public class " + args[1] + " {\n\n" +
                "public " + args[1] + "() {\n\n");

            (new GrammarConverter()).parseFile(args[0]);

            output("\n} // End of class " + args[1] + "\n");
        }
    }


  public void InitialiseArrays()
  {

     slashChars[0] = "\\n"; slashChars[1] = "\\r";
     slashChars[2] = "\\t"; slashChars[3] = "\\"; 
     lowerCase[0] = "a";   upperCase[0] = "A";
     lowerCase[1] = "b";   upperCase[1] = "B";
     lowerCase[2] = "c";   upperCase[2] = "C";
     lowerCase[3] = "d";   upperCase[3] = "D"; 
      lowerCase[4] = "e";   upperCase[4] = "E";
 lowerCase[5] = "f";   upperCase[5] = "F";
 lowerCase[6] = "r";   upperCase[6] = "A";
 lowerCase[7] = "n";   upperCase[7] = "A";
 lowerCase[8] = "t";   upperCase[8] = "A";
 lowerCase[9] = "a";   upperCase[9] = "A";
 lowerCase[10] = "`";   upperCase[10] = "Z";
 lowerCase[11] = "/";   upperCase[11] = "Z";
 lowerCase[12] = "'";   upperCase[12] = "Z";
 lowerCase[13] = "z";   upperCase[13] = "Z";
 lowerCase[14] = "z";   upperCase[14] = "Z";
 lowerCase[15] = "z";   upperCase[15] = "Z";
 lowerCase[16] = "z";   upperCase[16] = "Z";
 lowerCase[17] = "z";   upperCase[17] = "Z";
 lowerCase[18] = "z";   upperCase[18] = "Z";
 lowerCase[19] = "z";   upperCase[19] = "Z";
 lowerCase[20] = "z";   upperCase[20] = "Z";
 lowerCase[21] = "z";   upperCase[21] = "Z";
 lowerCase[22] = "z";   upperCase[22] = "Z";
 lowerCase[23] = "x";   upperCase[23] = "X";
 lowerCase[24] = "z";   upperCase[24] = "Z";
 lowerCase[25] = "z";   upperCase[25] = "Z";
 digits[0] ="0"; digits[1] = "9";
 digits[2] = "7"; digits[3] = "3";
 digits[4] = "1";
 singleChars[0] = "~";singleChars[1] = "!";
 singleChars[2] ="@"; singleChars[3] = "#";
 singleChars[4] = "$" ; singleChars[5] = "%";
 singleChars[6] ="^" ; singleChars[7] = "&";
 singleChars[8] = ":"; singleChars[9] = "=";
 singleChars[10] = "<"; singleChars[11] = ">";
 singleChars[12] = "?"; singleChars[13] = ".";
 singleChars[14] = "|";  singleChars[15] = "+";
 singleChars[16] = ")"; singleChars[17] = "(";
  singleChars[18] = "]";  singleChars[19] = "[";
  singleChars[20] = "*";   
 singleChars[21] = "_";
 singleChars[22] = " ";
 singleChars[23] = "-";

  }


  public String transformString(String s){

    // StringTokenizer st;

   String dummy = "";
   String tmp;
   String d = "";
   char a = '"';
   String bslash  = "\\";
   boolean firstToken = false;
   int ctr   = -1;
   String cmt = "\\\\"; 

    lowerCase = new String[26];
    upperCase = new String[26];
    slashChars = new String[4];
    tokenString = new String[100];
    digits      = new String[5];
    singleChars = new String[24];
   InitialiseArrays();
   //for (int i=0 ; i <=25; i++)
   //       System.out.println("char " + lowerCase[i] + upperCase[i]);


   d += a;
   StringTokenizer  st = new StringTokenizer(s,d);

    while (st.hasMoreTokens() )
      {
         ctr++;         
         tokenString[ctr] = st.nextToken();
         System.out.println(tokenString[ctr]);
      }

        System.out.println("counter is " + ctr);
    dummy += tokenString[0];
    dummy += a ;

     for (int i=0 ; i <= ctr; i++)
     {
       System.out.println("All the strings\n");


       System.out.println(tokenString[i]);
     }
     System.out.println(dummy + "  " + tokenString[0]);

    System.out.println("doing scannig\n");

    for ( int i =1; i <= ctr-1 ; i++)
      {
             System.out.println( tokenString[i]);

         if ( (IsChar(tokenString[i])) || (IsDigit(tokenString[i])) )
           {
           
             dummy += bslash + a + tokenString[i] + bslash + a;
                 System.out.println(" after IsChar  true " + dummy);
           }

         else  if (IsItthese(tokenString[i]))
           {
            dummy += bslash + a + bslash + tokenString[i] + bslash + a;
                 System.out.println(" after IsItthese  true " + dummy);
           }
         else if (IsComment(tokenString[i]))
           {
            
              dummy += bslash + a + bslash + bslash + bslash + bslash
                       + bslash  + a;
                 System.out.println(" after IsComment  true " + dummy);

           }
         else if (IsSingle(tokenString[i]))
           {
           
             dummy += bslash + a + tokenString[i] + bslash + a;
                 System.out.println(" after IsSingle  true " + dummy);
           }  
         else if (IsUnderscore(tokenString[i]))
           {
          
                  dummy += bslash +a + tokenString[i] + bslash + a;
          System.out.println(" after isunderscore is true " + dummy);

           }
         else
           {

           dummy += tokenString[i];
          System.out.println(" after ischar is false " + dummy);

           }

       }
 
       dummy += a + tokenString[ctr] ;
       System.out.println(" Final value of dummy is " + dummy);
         System.out.println(" 8 % 5  8 /5is" + 8%5 + 8 / 5);

    return dummy;
  }// End of transformString


  public boolean IsComment(String s)
  {
     boolean flag = false;
    String cmt = "\\\\";

   
    if (s.equals(cmt))
    {
      flag = true;
      
    }
   return flag;
   
 }


  public boolean IsUnderscore(String s)
  {
     boolean flag = false;
    String cmt = "_";

   
    if (s.equals(cmt))
    {
      flag = true;
      
    }
   return flag;
   
 }

  public boolean IsSingle(String s)
  {
     boolean flag = false;
    String cmt = "\\\\";
    for (int i=0; i<=23; i++)
        {
        if ( s.equals(singleChars[i]) )
          {
                     flag = true;
                     break;
          }
        }
   return flag;
   
 }

  public boolean IsItthese(String s){

   boolean flag = false;
      for (int i=0; i<=3; i++)
        {
        if ( s.equals(slashChars[i]) )
          {
                     flag = true;
                     break;
          }
        }
    return flag;

  }


  public boolean IsDigit(String s){

   boolean flag = false;
      for (int i=0; i<=4; i++)
        {
        if ( s.equals(digits[i]) )
          {
                     flag = true;
                     break;
          }
        }
    return flag;

  }

  public boolean IsChar(String s){
  
    boolean flag = false;
    for (int i = 0 ; i <= 25 ; i++)
      {
        if ( (s.equals(lowerCase[i]) ) || (s.equals(upperCase[i])) )
          {
           flag = true;
            break;
          }
      }
  
      return flag;

  }


    // Parse the specified input file.
    //
    // For every syntax diagram keyword encountered, attempt to interpret the
    // diagram specification that follows. If successful, add to the output
    // file the code necessary to construct the diagram specified. If an error
    // is found in the file, report the error on standard output.
    public void parseFile(String filename) {

        StreamTokenizer tokens = null;
        try {
            tokens = new StreamTokenizer(new FileInputStream(filename));
            tokens.ordinaryChar('/');
            tokens.slashSlashComments(true);
            tokens.eolIsSignificant(true);
        }
        catch (FileNotFoundException e) {
            System.out.println(
                "Input file \"" + filename +  "\" not found.");
            return;
        }

        Vector diagNames = new Vector();        // Diagram names encountered
        String sequenceDecl = "";               // Latest diagram declaration
        String latestName = "";                 // Latest diagram's name
        int c;
        boolean expecting_name = false;
        boolean expecting_key = false;
        boolean expecting_begin = true;
        boolean expecting_end = false;
        
        boolean expecting_reg_name = false;

        Enumeration enum;
        String currentElement = "";
        String tempString = "";
        String finalStr = "";

      out:
        while (true) {
            try {
                c = tokens.nextToken();
            }
            catch (IOException e) {
                e.printStackTrace();
                return;
            }
            switch (c) {
            case StreamTokenizer.TT_EOF:
                break out;
            case StreamTokenizer.TT_EOL:
                 _lineNumber++;
                break;
            case BEGIN_DIAGRAM:
                if (expecting_begin) {
                    output("//*******************************\n");
                    expecting_begin = false;
                    expecting_key = true;
                }
                else {
                    printError((char)BEGIN_DIAGRAM);
                    break out;
                }
                break;
            case END_DIAGRAM:
                if (expecting_end) {
                    outputVectors();
                    output(sequenceDecl + ";\n\n");
                    resetVectors();
                    expecting_end = false;
                    expecting_begin = true;
                }
                else {
                    printError((char)END_DIAGRAM);
                    break out;
                }
                break;
            case StreamTokenizer.TT_NUMBER:
                System.out.println("Error in input file on line " +
                                   _lineNumber);
                System.out.println("    Unexpected number " + tokens.nval);
                break out;
            case StreamTokenizer.TT_WORD:
                if (expecting_key) {
                    if (tokens.sval.equals(DIAGRAM_KEY)) {
                        expecting_key = false;
                        expecting_name = true;
                    }
                     else if (tokens.sval.equals(REG_KEY)) {
                       System.out.println("Recg reg");
                      expecting_key = false;
                      expecting_name = false;
                      expecting_reg_name = true;
                    }  
                   
                    else {
                        printError(tokens.sval);
                        break out;
                    }
                }
                else if (expecting_name) {
                    latestName = tokens.sval;
                    diagNames.addElement(latestName);
                    DiagramParser parser = new DiagramParser();
                     if (latestName.equals("Identifier") ||
                         latestName.equals("Unit") ||
                           latestName.equals("Anonymous") ||
                          latestName.equals("Symbol") ||
                           latestName.equals("Space") ||
                            latestName.equals("Nil") ||
                         latestName.equals("Exponent") ||
                          latestName.equals("StringLiteral") ||
                           latestName.equals("CharLiteral") ||
                           latestName.equals("Decimal") ||
                           latestName.equals("Octal") ||
                           latestName.equals("Hexadecimal"))

                       { System.out.println("Tdentifer" + "  ");
                       }
                     else
                    _nonTerminalDefined.addElement(latestName);
                    sequenceDecl = latestName + " = " +
                                   parser.parseDiagram(tokens);
                    expecting_name = false;
                    expecting_end = true;
                }
                 else if (expecting_reg_name) {
                       latestName = tokens.sval;
                    System.out.println("Recg regular name" + latestName);
                    diagNames.addElement(latestName);
                    DiagramParser parser = new DiagramParser();
                 
                    tempString = parser.parseReg(tokens);
                    System.out.println("tempString is "+ tempString);
 
                    finalStr = transformString(tempString);
                   System.out.println("finalStr is "+ finalStr); 
                    sequenceDecl = latestName + " = " +
                                   finalStr;
                     System.out.println("Finished reg");
                    expecting_name = false;
                    expecting_reg_name = false;
                    expecting_end = true;
                }
               
                else {
                    printError(tokens.sval);
                    break out;
                }
                break;
            default:
                printError((char)c);
                break out;
            }
        }
        enum = diagNames.elements();
        while(enum.hasMoreElements()) {
            currentElement = (String)enum.nextElement();
            output("diagramList.addElement(" + currentElement + ");\n");
            output("diagramNames.addElement(\"" + currentElement + "\"); \n");
        }
        output("\n} // End of constructor\n\n");
        checkNonTerminalDefinitions();//checks if all non terminals have
        // been defined.
        outputDiagNames(diagNames);
    }

    //----------------------------------------------------------
    // Following method checks if all non terminals appearing in the
    // input file have been defined.
    //----------------------------------------------------------
    
    public void checkNonTerminalDefinitions(){
        while(!(_nonTerminalDefined.isEmpty()))
        {
           _nonTerminalNames.removeElement(_nonTerminalDefined.firstElement());
           _nonTerminalDefined.removeElementAt(0);
        }
        if(!(_nonTerminalNames.isEmpty()))
           System.out.println("Error in input file: The following nonterminals have not been defined" + _nonTerminalNames.toString()+"\n" );
    }
                
    //----------------------------------------------------------
    // Following method adds an element to the list _nonTerminalNames.
    //----------------------------------------------------------
    
    public static void addNonTerminal(String Name){
        if(!(_nonTerminalNames.contains(Name))){
                _nonTerminalNames.addElement(Name);
        }
    }
                

    //----------------------------------------------------------
    // Method for putting information into the output file.
    //----------------------------------------------------------

    static void output(String str) {
        if (str == null) return;
        if (str.equals("")) return;

        try {
            byte[] buf = new byte[str.length()];
            str.getBytes(0, str.length(), buf, 0);
            _oStream.write(buf);
        }
        catch (IOException e) {
            System.out.println("Error writing to output file");
            e.printStackTrace();
        }
    }

    //----------------------------------------------------------
    // Methods for managing indentation in the output file.
    //----------------------------------------------------------

    static String getIndent() {
        String s = "";

        for (int i = 0; i < _indent; i++)
            s += "    ";

        return s;
    }

    static void incIndent() {
        _indent++;
    }

    static void decIndent() {
        _indent--;
    }

    //----------------------------------------------------------
    // Methods for managing Vector definitions used in the specification of
    // the diagram definitions encountered in the input file.
    //----------------------------------------------------------

    static void addVector(String name, String value) {
        _vectors.put(new Integer(name.substring(_index)),value);
    }

    static String removeVector(String name) {
        return (String)_vectors.remove(new Integer(name.substring(_index)));
    }

    static void resetVectors() {
        _vectors.clear();
        resetVectorCnt();
    }

    static void outputVectors() {
        Enumeration e = _vectors.elements();
        while(e.hasMoreElements()) {
            output(e.nextElement().toString());
        }
        output("\n");
    }

    static int getVectorCnt() {
        return _vectorCnt;
    }

    static void resetVectorCnt() {
        _vectorCnt = 0;
    }

    static void incVectorCnt() {
        _vectorCnt++;
        _maxVectorCnt = Math.max(_maxVectorCnt, _vectorCnt);
    }

    //----------------------------------------------------------
    // Methods for managing parsing errors.
    //----------------------------------------------------------

    static int getLineNumber() {
        return _lineNumber;
    }

    static void incLineNumber() {
        _lineNumber++;
    }

    static boolean getErrorFlag() {
        return _errorFlag;
    }

    static void printError(char token) {
        System.out.println("Error in input file on line " + _lineNumber);
        System.out.println("    Unexpected token '" + token + "'");
        _errorFlag = true;
    }

    static void printError(String string) {
        System.out.println("Error in input file on line " + _lineNumber);
        System.out.println("    Unexpected string \"" + string + "\"");
        _errorFlag = true;
    }

    //----------------------------------------------------------
    // Method for outputting a Diagram declaration for every diagram
    // definition encountered in the input file.
    //----------------------------------------------------------

    private void outputDiagNames(Vector names) {
        String prefix = "public Diagram ";
        int i, cnt = 0;
        boolean firstLine = true;
        String currentElement = "";
        Enumeration e = names.elements();
        while(e.hasMoreElements()) {
            currentElement = (String)e.nextElement();
            if (firstLine) {
                cnt = prefix.length() + currentElement.length();
                output("//====================================\n\n");
                output("public Vector diagramList = new Vector(); \n");
                output("public Vector diagramNames = new Vector(); \n");
                output(prefix + currentElement);
                firstLine = false;
            } else {
                cnt += (currentElement.length() + 2);
                if (cnt < 75) {
                    output(", " + currentElement);
                } else {
                    output(",\n");
                    for (i = 0; i < prefix.length(); i++)
                        output(" ");
                    output(currentElement);
                    cnt = prefix.length() + currentElement.length() + 2;
                }
            }
        }
        output(";\n\n");
    }
}

/** class VectorBuilder
 *
 *  Add to the output file a Vector definition for each diagram definition
 *  encountered in the input stream intended as part of the diagram currently
 *  being constructed.
 */
class VectorBuilder {

    private static Vector _names = new Vector();

    VectorBuilder() {
    }

    // Create a Vector containing a Diagram corresponding to each of
    // the diagram definitions encountered in the input stream prior to
    // encountering two END_DIAGRAM tokens together.
    //
    // Returns the name of the Vector created.
    //
    public String createVector(StreamTokenizer tokens) {
        String str = "";
        DiagramParser parser = new DiagramParser();

        GrammarConverter.incVectorCnt();
        String vectorName = "vector" + GrammarConverter.getVectorCnt();
        if (_names.contains(vectorName)) {
            str += ("\n" + vectorName + ".removeAllElements();\n");
        } else {
            _names.addElement(vectorName);
            str += ("\nVector " + vectorName + " = new Vector();\n");
        }

        String diag = "";
        while ((diag = parser.parseDiagram(tokens)) != null) {
            str += (vectorName + ".addElement(" + diag + ");\n");
        }
        GrammarConverter.addVector(vectorName, str);

        return vectorName;
    }

}

/** class DiagramParser
 *
 *  Construct Diagram instantiation code according to the next diagram
 *  definition encountered in the input stream.
 */
class DiagramParser {

    private static final int BEGIN_DIAGRAM = GrammarConverter.BEGIN_DIAGRAM;
    private static final int END_DIAGRAM   = GrammarConverter.END_DIAGRAM;

    private static final String SEQUENCE_KEY      = "sequence";
    private static final String CHOICE_KEY        = "choice";
    private static final String OPTIONAL_KEY      = "optional";
    private static final String LOOP_KEY          = "loop";
    private static final String SEQUENCE_LOOP_KEY = "sequence-loop";
    private static final String ZERO_OR_MORE_KEY  = "zero-or-more";
    private static final String ONE_OR_MORE_KEY   = "one-or-more";
    private static final String TERMINAL_KEY      = "terminal";
    private static final String NONTERMINAL_KEY   = "nonterminal";
    private static final String REGEXP_KEY        = "regular";

    public DiagramParser() {
    }

    // Parse the specified StreamTokenizer.
    //
    // For every syntax diagram keyword encountered, attempt to interpret the
    // diagram specification that follows and construct the code required to
    // instantiate the specified diagram. If successful, return the
    // instantiation code in String form. If not, return null instead.
    public String parseDiagram(StreamTokenizer tokens) {

        String diag = null;                     // Latest diagram declaration
        String latestName = "";                 // Latest diagram's name
        String key = "";
        int c;
        boolean expecting_name = false;
        boolean expecting_key = false;
        boolean expecting_begin = true;
        boolean expecting_end = false;

      out:
        while (true) {
            try {
                c = tokens.nextToken();
            }
            catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            switch (c) {
            case StreamTokenizer.TT_EOF:
                break out;
            case StreamTokenizer.TT_EOL:
                GrammarConverter.incLineNumber();
                break;
            case StreamTokenizer.TT_NUMBER:
                System.out.println("Error in input file on line " +
                                   GrammarConverter.getLineNumber());
                System.out.println("    Unexpected number " + tokens.nval);
                break out;
            case BEGIN_DIAGRAM:
                if (expecting_begin) {
                    expecting_begin = false;
                    expecting_key = true;
                }
                else {
                    GrammarConverter.printError((char)BEGIN_DIAGRAM);
                    break out;
                }
                break;
            case END_DIAGRAM:
                if (expecting_end) {
                    break out;
                }
                else if (expecting_begin) {
                    tokens.pushBack();
                    break out;
                }
                else {
                    GrammarConverter.printError((char)END_DIAGRAM);
                    break out;
                }
            case '"':
            case StreamTokenizer.TT_WORD:
                if (expecting_key) {
                    key = tokens.sval;
                    expecting_key = false;
                    if (key.equals(TERMINAL_KEY) || key.equals(REGEXP_KEY) ||
                        key.equals(NONTERMINAL_KEY)) {
                        expecting_name = true;
                    }
                    else if (key.equals(CHOICE_KEY)) {
                        VectorBuilder dvb = new VectorBuilder();
                        diag = (GrammarConverter.getIndent() +
                                "new DecisionDiagram(" +
                                dvb.createVector(tokens) + ")");
                        expecting_end = true;
                    }
                    else if (key.equals(OPTIONAL_KEY)) {
                        VectorBuilder dvb = new VectorBuilder();
                        String vectorName = dvb.createVector(tokens);
                        String temp = GrammarConverter.removeVector(vectorName);
                        GrammarConverter.addVector(
                            vectorName, (temp + vectorName +
                                         ".addElement(new EmptyDiagram());\n"));
                        diag = (GrammarConverter.getIndent() +
                                "new DecisionDiagram(" +
                                vectorName + ")");
                        expecting_end = true;
                    }
                    else if (key.equals(SEQUENCE_KEY)) {
                        VectorBuilder svb = new VectorBuilder();
                        diag = (GrammarConverter.getIndent() +
                                "new SequenceDiagram(" +
                                svb.createVector(tokens) + ")");
                        expecting_end = true;
                    }
                    else if (key.equals(SEQUENCE_LOOP_KEY)) {
                        VectorBuilder svb = new VectorBuilder();
                        diag = (GrammarConverter.getIndent() +
                                "new SequenceDiagram(true, " +
                                svb.createVector(tokens) + ")");
                        expecting_end = true;
                    }
                    else if (key.equals(LOOP_KEY)) {
                        diag = (GrammarConverter.getIndent() +
                                "new LoopDiagram(\n");
                        GrammarConverter.incIndent();
                        DiagramParser parser = new DiagramParser();
                        diag += (GrammarConverter.getIndent() +
                                 parser.parseDiagram(tokens) + ",\n" +
                                 GrammarConverter.getIndent() +
                                 parser.parseDiagram(tokens) + ")");
                        GrammarConverter.decIndent();
                        expecting_end = true;
                    }
                    else if (key.equals(ZERO_OR_MORE_KEY)) {
                        diag = (GrammarConverter.getIndent() +
                                "new LoopDiagram(\n");
                        GrammarConverter.incIndent();
                        DiagramParser parser = new DiagramParser();
                        diag += (GrammarConverter.getIndent() +
                                 "new EmptyDiagram(),\n" +
                                 GrammarConverter.getIndent() +
                                 parser.parseDiagram(tokens) + ")");
                        GrammarConverter.decIndent();
                        expecting_end = true;
                    }
                    else if (key.equals(ONE_OR_MORE_KEY)) {
                        diag = (GrammarConverter.getIndent() +
                                "new LoopDiagram(\n");
                        GrammarConverter.incIndent();
                        DiagramParser parser = new DiagramParser();
                        diag += (GrammarConverter.getIndent() +
                                 parser.parseDiagram(tokens) + ",\n" +
                                 GrammarConverter.getIndent() +
                                 "new EmptyDiagram())");
                        GrammarConverter.decIndent();
                        expecting_end = true;
                    }
                    else {
                        GrammarConverter.printError(tokens.sval);
                        break out;
                    }
                }
                else if (expecting_name) {
                    latestName = tokens.sval;
                    if (key.equals(TERMINAL_KEY)) {
                        diag = "new TerminalDiagram(\"" + latestName + "\")";
                    }
                    else if (key.equals(NONTERMINAL_KEY)) {
                        diag = "new NonTerminalDiagram(\"" + latestName + "\")";

                         if  (latestName.equals("Identifier") ||
                              latestName.equals("Unit")
                           ||  latestName.equals("Nil")
                           ||  latestName.equals("Symbol")
                           ||  latestName.equals("Octal")
                           ||   latestName.equals("Decimal")
                           ||   latestName.equals("Hexadecimal")
                           ||   latestName.equals("StringLiteral")
                           ||   latestName.equals("CharLiteral")
                           ||  latestName.equals("Space")
                           ||  latestName.equals("Anonymous")
                           ||  latestName.equals("Exponent") )
                           {
                             System.out.println(" WWWWWWWWW");
                           }
                          else
                           {
                         GrammarConverter.addNonTerminal(latestName);
                           }
                    }
                     else if (key.equals(REGEXP_KEY)) {
                        diag = "new NonTerminalDiagram(\"" + latestName + "\")";
                        //  GrammarConverter.addNonTerminal(latestName);
                    }

                    else {
                        GrammarConverter.printError(tokens.sval);
                        break out;
                    }
                    expecting_name = false;
                    expecting_end = true;
                }
                else {
                    GrammarConverter.printError(tokens.sval);
                    break out;
                }
                break;
            default:
                GrammarConverter.printError((char)c);
                break out;
            } // switch
        } // while
        if (GrammarConverter.getErrorFlag()) {
            return null;
        } else {
            return diag;
        }
 
    }

 public String parseReg(StreamTokenizer tokens) {

        String diag = null;                     // Latest diagram declaration
        String latestName = "";                 // Latest diagram's name
        String key = "";
        int c;
        boolean expecting_name = false;
        boolean expecting_key = false;
        boolean expecting_begin = true;
        boolean expecting_end = false;

        boolean expecting_reg_name = false;

      out:
        while (true) {
            try {
                c = tokens.nextToken();
            }
            catch (IOException e) {
                e.printStackTrace();
                return null;
            }
            switch (c) {
            case StreamTokenizer.TT_EOF:
                break out;
            case StreamTokenizer.TT_EOL:
                GrammarConverter.incLineNumber();
                break;
            
            case StreamTokenizer.TT_NUMBER:
                System.out.println("DP &&& Error in input file on line " +
                                   GrammarConverter.getLineNumber());
                System.out.println("DP &&&    Unexpected number " + tokens.nval);
                break out;
            case BEGIN_DIAGRAM:
                if (expecting_begin) {
                    System.out.println("&&& Saw Begin " + key);                  
                    expecting_begin = false;
                    expecting_key = true;
                }
                else {
                    GrammarConverter.printError((char)BEGIN_DIAGRAM);
                    break out;
                }
                break;
            case END_DIAGRAM:
                if (expecting_end) {
                    System.out.println("&&& Saw End " + key);                  
                    break out;
                }
                else if (expecting_begin) {
                    tokens.pushBack();
                    break out;
                }
                else {
                    GrammarConverter.printError((char)END_DIAGRAM);
                    break out;
                }
            case '"':
              //case StreamTokenizer.TT_WORD:          
                    latestName = tokens.sval;
                    expecting_key = false;
                     System.out.println("****  got the string " + latestName);    
                    diag = "new Regular(\"" + latestName + "\")";              
                     expecting_name = false;     
                     expecting_end = true;

                     /* if (key.equals(FIXED_KEY)) {
                      //GrammarConverter.incIndent();
                      // DiagramParser parser = new DiagramParser();
                         diag = (GrammarConverter.getIndent() +
                                   "1");
                         //  GrammarConverter.decIndent();
                         expecting_name = true;
                        expecting_reg_name = true;
                        expecting_end = true;
                    }
                    
                    else if (key.equals(SEQUENCE_KEY)) {
                        
                        DiagramParser parser = new DiagramParser();
                        diag = (GrammarConverter.getIndent() +
                                "new Regular("+ parser.parseReg(tokens) + 
                                      parser.parseReg(tokens) + ")" );
                        expecting_end = true;
                    }
         
                    else if (key.equals(CLOSURE_KEY)) {
                      // VectorBuilder svb = new VectorBuilder();
                         diag = (GrammarConverter.getIndent() + ",2");
                          expecting_name = true;
                        expecting_reg_name = true;
                        expecting_end = true;
                
        
                    }
                    else if (key.equals(LOOP_KEY)) {
                        diag = (GrammarConverter.getIndent() +
                                "new LoopDiagram(\n");
                        GrammarConverter.incIndent();
                         DiagramParser parser = new DiagramParser();
                        diag += (GrammarConverter.getIndent() +
                                 parser.parseReg(tokens) + ",\n" +
                                 GrammarConverter.getIndent() +
                                 parser.parseReg(tokens) + ")");
                        GrammarConverter.decIndent();
                        expecting_end = true;
                    }
                    else if (key.equals(ZERO_OR_MORE_KEY)) {
                        diag = (GrammarConverter.getIndent() +
                                "new LoopDiagram(\n");
                        GrammarConverter.incIndent();
                        DiagramParser parser = new DiagramParser();
                        diag += (GrammarConverter.getIndent() +
                                 "new EmptyDiagram(),\n" +
                                 GrammarConverter.getIndent() +
                                 parser.parseReg(tokens) + ")");
                        GrammarConverter.decIndent();
                        expecting_end = true;
                    }
                    else if (key.equals(ONE_OR_MORE_KEY)) {
                        diag = (GrammarConverter.getIndent() +
                                "new LoopDiagram(\n");
                        GrammarConverter.incIndent();
                        DiagramParser parser = new DiagramParser();
                        diag += (GrammarConverter.getIndent() +
                                 parser.parseReg(tokens) + ",\n" +
                                 GrammarConverter.getIndent() +
                                 "new EmptyDiagram())");
                        GrammarConverter.decIndent();
                        expecting_end = true;
                    }
                    else {
                        GrammarConverter.printError(tokens.sval);
                        break out;
                    }
                }
                else if (expecting_reg_name)  {
                    latestName = tokens.sval;
                    // DiagramParser parser = new DiagramParser();
                        diag += ",\"" + latestName + "\"" ;
          
                    expecting_reg_name = false;
                    //expecting_begin = true;
                    expecting_end = true;
                    
                } */
             // expecting_name 
                
            // GrammarConverter.printError(tokens.sval);
                    break ;
                
                
            default:
                GrammarConverter.printError((char)c);
                break out;
            }// switch(c)
        } // while
        if (GrammarConverter.getErrorFlag()) {
            return null;
        } else {
            return diag;
        }
    } // End of parseReg



}




