FileDocCategorySizeDatePackage
parser.javaAPI DocExample47539Sat Nov 25 11:54:30 GMT 2000None

parser.java

/*
 * Copyright (C) 1996,1997 Morgan Stanley & Co., Inc. 
 * Copyright (C) 1997 Ilya Tilevich
 *
 * This file is part of C2J++.
 * C2J++ is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the Free Software Foundation; 
 * either version 2, or (at your option) any later version.
 * C2J++ is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; 
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along with C2J; 
 * see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

import java.io.*;
import java.util.Vector;
import java.util.Enumeration;
import java.lang.Character;


class Buffer extends Vector
{
	Buffer(int iCapacity){
		super(iCapacity);
	}
	
	public void Add(int iByte){
		addElement(new Character((char)iByte));
	}

	public void Add(char c){
		addElement(new Character(c));
	}
	
	public char At(int iLoc){
		
				
		try{
		    			
			return ((Character) elementAt(iLoc)).charValue();
		 }
		 
		 catch (Throwable e) {System.out.println(e);}
		
			return '$';
	}	

	void Concatenate(Buffer bufOther){
		int iSize = bufOther.size();
		for(int i = 0; i < iSize; i ++)
			addElement(new Character(bufOther.At(i)) );

	}	

	void Concatenate(String strBuf){
		int iLen = strBuf.length();
		for(int i = 0; i < iLen; i++)
		    Add(strBuf.charAt(i));
	}

	boolean StartsWithComment(){
		int iSize = size(), i = 0;
		char ch;
		if(iSize == 0) return false;
		
		do{
			ch = At(i++);
		}while(i < iSize && Character.isSpace(ch));

		if(ch == '/'){
			for(int j = i; j < i+2; j++)
				if(At(j)!='*')
				  return false;
			return true;
		}

		else return false;
	}

	public 	synchronized void WriteOut(){  //to stdio
		
		Enumeration enum = elements();
		
		for(;enum.hasMoreElements();){
			 Character Char = (Character)(enum.nextElement());
			 System.out.print(Char.charValue());
        }
	 
	}

	/**
	 * Purpose: Writes this object to DataOutputStream
	 */
	public 	synchronized void WriteOut(DataOutputStream  dos){
		
		int iSize = size();
		
		
		try{
		
			for(int i = 0; i < iSize; i ++){
				
				char ch = At(i);
				dos.writeByte(At(i));
				
			}
			
		} catch(IOException e){System.out.println("IO error in Buffer WriteOut(dos)");}

	   	 
	}
	   	


}


/**
 * Class Scan
 * Purpose: Scans a source files ignoring white space characters
 * @version 1.1	 January 97
 * @author Ilya Tilevich
 * Note: This class is based on the original code written in C++ by Chris Laffra
 */
class Scanner
{
    private boolean  m_bPutBack = false;		// see getByte()
	private byte m_btPutbackByte = 0;		// see getByte()
	private int  m_iLineNo  = 0;		// the current line number
	protected TokenStack m_tkStack = null;
	 
	protected FileOutputStream m_fosFileOut = null; 
	protected DataOutputStream m_dosDataOut = null;	
	
	private Buffer m_Buffer;

	
	public Buffer GetBuffer() { return m_Buffer; }
	
	protected FileInputStream m_fisFileIn = null;  //source file
	protected BufferedInputStream m_bisBufferedInput = null;
	private DataInputStream m_disDataIn = null;

	/**
	 * m_bEOF indicates if the end of file is reached
	 */
	public boolean m_bEOF = false;

	/**
	 * Scan
	 * Purpose: Constructor
	 * @exception IOException if there are problems with opening a temp file   
	 */
	
	public Scanner(){
	
		m_bPutBack = false;		// see getByte()
	    m_btPutbackByte = 0;		// see getByte()
	    m_iLineNo  = 0;		// the current line number
	    m_tkStack = new TokenStack();
	 	
		try{
			m_fosFileOut = new  FileOutputStream("__temp__");
			m_dosDataOut = new DataOutputStream(m_fosFileOut);	
		}catch(IOException e){};

			
	}

	/**
	 * OpenInputFile
	 * Purpose: opens a source file for scanning and reinitializes member variables
	 * @param strInFile		the name for the source file
	 * @exception FileNotFoundException		if strInFile doesn't exist
	 * @exception Throwable		if there are problems with opening the file
	 */
	 	
	public void OpenInputFile(String strInFile){
	
	   try{
	       
		   m_fisFileIn = new FileInputStream(strInFile);
		   m_bisBufferedInput = new BufferedInputStream(m_fisFileIn);
		   m_disDataIn  = new DataInputStream(m_bisBufferedInput);

		   
				
	   }
		catch(FileNotFoundException e){
		    System.out.println("File Not Found");
		    return;
	    }
		catch(Throwable e) {
	        System.out.println("Error in opening file");
	        return;
	    }

		

		//When open a new file for reading, reset all member variables;
		m_tkStack = new TokenStack();
		m_Buffer = new Buffer(1024);

		m_bPutBack = false;		
	    m_btPutbackByte = 0;		
	    m_iLineNo  = 0;		
		m_bEOF = false;
		

	}

	public void CloseAllFiles(){
		   
		try{	
		   m_bisBufferedInput.close();   
		   m_disDataIn.close();   
		   m_fisFileIn.close();
		   
		   
	   
		   m_dosDataOut.close();
		   m_fosFileOut.close();
		}catch(IOException e){System.out.println(e);}
	}
	
	public void FlushBuffer(){
		m_Buffer.setSize(0);
	}
	
	
	public void WriteBuffer(){
		int iSize = m_Buffer.size();
		try{

		for(int i = 0; i < iSize; i ++){
			m_dosDataOut.writeByte(m_Buffer.At(i));
			///System.out.print(m_Buffer.At(i));
		}
		
		}catch(IOException e){System.out.println("Error in WriteBuffer()");}
		FlushBuffer();	
	}
	
	public boolean BufferStartsWithComment(){
		return m_Buffer.StartsWithComment();
	}

	/**
	 * getByte()
	 * Purpose: gets a byte from the input stream or a m_btPutbackByte
	 * Ignores '\r' 
	 * @return byte read
	 * @exception IOException if  there are problems with reading the file
	 * @exception Throwable		if there are problems writing to the temp file
	 */
	
	private byte getByte()
	{
	  if(m_bPutBack){
		  m_bPutBack = false;
		  return m_btPutbackByte;
	  }

	  int iCh = 0;
	  
	  try{
		  
		  if((iCh = m_disDataIn.read())!=-1){
			  //char ch = (char) iCh;
			  if(iCh == '\r'){ 
				  m_Buffer.Add(iCh);
				  return getByte();
			  }
			  if(iCh == '\n')  m_iLineNo++;

		  }

		  else
			  m_bEOF = true;
		  

		    //if(dosDataOut != null && iCh!= -1){
			//dosDataOut.writeByte(iCh);
			 
			// if(iCh == '\n') dosDataOut.writeBytes("  ");
		    //}

	  }
	  catch(IOException e) {
	          System.out.println("Error in reading file");
	  }


	  catch(Throwable e){
			System.out.println("Error in writing to file");
	  }
	
	    if(!m_bEOF)
			m_Buffer.Add(iCh);
	    return  (byte)iCh;
	  
	
	}

	/**
	 * ungetByte
	 * Purpose: put back a byte just read by getByte() method
	 * This method is used in this class and is called from Parse
	 * @param b the byte to put back	
	 */
	protected void ungetByte(byte b)
	{
		m_bPutBack = true;
		m_btPutbackByte = b;
	}
	
	/**
	 * isIdentifier
	 * Purpose: determines if the input param is a part of a legal C identifier
	 * @param b the byte to examine
	 * @return true if b can be a part of a C identifier, false otherwise
	 */
	
	public static boolean isIdentifier(byte b) { return Character.isLetterOrDigit((char)b) || b == '_'; }
	
	public  static  boolean isOperator(byte b){
		
		return (b == '!'||
				b == '^'||
				b == '&'||
				b == '*'||
				b == '-'||
				b == '+'||
				b == '='||
				b == '|'||
				b == '<'||
				b == '>'||
				b == '~');
	}
	
	
	/**
	 * skipSpaces
	 * Purpose: reads the source file until it encounters a byte other than space
	 */
	
	private void skipSpaces()
	{
		byte b;
		do{ 
			b = getByte(); 
			}while (b == ' '|| b == 10 || b == 9);
		ungetByte(b);
	}
	
	/**
	 * ByteArrayToString 
	 * Purpose: converts an array of bytes to a Java String
	 * @param	btArray[]	the array of bytes
	 * @param	iSize	the size of the btArray[]
	 */
	
	protected String ByteArrayToString(byte btArray[], int iSize)
	{
				String str = new String();
				for(int i = 0; i< iSize; ++i)
					str += (char)btArray[i];

		  		 return str;
	}

	/**
	 * getWord
	 * Purpose: Gets a word from the input stream and pushes it 
	 * into the ParseStack
	 * @param strBuf[]	a temporary array of bytes
	 * @param iBufSize	a maximum size of the word to be gotten
	 * @return the word read
	 */
	
	public String getWord(byte strBuf[], int iBufSize)
	{

	   skipSpaces();
	   int iN;
	   for(iN = 0; iN < iBufSize && !m_bEOF; ++iN){
		   if(iN < iBufSize)  strBuf[iN] = getByte();

		   if(strBuf[iN] == '/'){        //skip comments

			   if(iN < iBufSize-1) strBuf[++iN] = getByte();

			if(strBuf[iN] == '/') { 		  //the '//' form
				 do{
					 if(iN < iBufSize) strBuf[++iN] = getByte();
				 }while(iN < iBufSize && !m_bEOF && strBuf[iN]!='\n');

				 //try{
				//	WriteBuffer(); //don't throw away comments
				 //}catch(IOException e){}
				 
				 return getWord(strBuf, iBufSize);
			}
			  else if(strBuf[iN] == '*'){           //the '/*' form
				  boolean bWatchForSlash = false;
				  while(iN < iBufSize && !m_bEOF){
					 do{
						 if(iN < iBufSize) strBuf[iN] = getByte();
						 if(bWatchForSlash && strBuf[iN] == '/') break;
						 else bWatchForSlash = false;
					 }while(iN < iBufSize && !m_bEOF && strBuf[iN] != '*');
					 if(iN < iBufSize && strBuf[iN] != '/' && !m_bEOF) strBuf[iN] = getByte();
					 if(strBuf[iN] == '/'){
						 bWatchForSlash = false;
						 break;
					 }
					 else if(strBuf[iN] == '*') bWatchForSlash = true;					 
				  }
				 
				 //try{
				 //	WriteBuffer(); //don't throw away comments
				 //}catch (IOException e) {}
				 return getWord(strBuf, iBufSize);
			  }
			  else {
				  if(iN > 0) ungetByte(strBuf[iN--]);
			  }
		   }

			if(strBuf[iN] == '#'){           //skip preprocessor
			   byte b;
			   do{
				   b = getByte();
				   if(b == '\\') { b = getByte(); b = getByte(); }
			   }while(!m_bEOF && b != '\n');
			   //try{
			   //WriteBuffer(); //don't throw away preprocessor
			   //}catch (IOException e){}
			   return getWord(strBuf, iBufSize);
			}

			if(strBuf[iN] == '\'') {         //character constant
				do{
					if(iN < iBufSize) strBuf[++iN] = getByte();
					if(strBuf[iN] == '\\'){
						if(iN < iBufSize) strBuf[++iN] = getByte();
						if(iN < iBufSize) strBuf[++iN] = getByte();
					}
				}while(iN < iBufSize && m_bEOF && strBuf[iN]!='\'');

                return ByteArrayToString(strBuf, iN + 1);

	        }

	        if(strBuf[iN] == '"'){              //string constant
	            do{
	                if(iN < iBufSize-1) strBuf[++iN] = getByte();
	                if(strBuf[iN] == '\\'){
	                    if(iN < iBufSize-1) strBuf[++iN] = getByte();
	                    if(iN < iBufSize-1) strBuf[++iN] = getByte();
					}
				}while(iN < iBufSize && !m_bEOF &&  strBuf[iN] !='"');

	            return ByteArrayToString(strBuf, iN+1);
	        }

	        
							 
			if(!isIdentifier(strBuf[iN])) break;
	} //end of for


	if(iN > 0) ungetByte(strBuf[iN--]);

	String str = ByteArrayToString(strBuf, iN+1);
	m_tkStack.push(str);
	if(m_bEOF) return (str = "");
	return str;

}

public static void main(String[] args) throws IOException {
Scanner s = new Scanner();
s.OpenInputFile("t.1");

while(!s.m_bEOF)
    byte b = s.getByte();

   s.WriteBuffer();
}



}

/**
 * class Parser
 * Purpose: parse a C++ source file(s)
 * @version 1.0 December 96
 * @author Ilya Tilevich
 *  Note: This class is based on the original code written in C++ by Chris Laffra
 */
 
class Parser
{
    
		
	static final int m_iBufSize = 516;
	
	static final boolean  m_bDebug = false;

	static final String PUBLIC = "public ";
	static final String PRIVATE = "private ";
	static final String PROTECTED = "protected";
	String m_strAccessor = "protected";
	MembersArray m_membersArray; //array of all member functions
	Scanner m_scan;
	private boolean m_bParseMethods; //if true parse Cpp file, H file otherwise
	FileOutputStream m_fosFileOut; 

	static TextOutputStream m_tos; //the output file
	//protected StringArray m_linesGlobal;	//contains all global C functions
	protected Buffer m_linesGlobal;	//contains all global C functions
	
	boolean m_bDefnOnly; //don't write function bodies
	/**
	 * Parser
	 * Purpose: Constructor
	 * @param bCppFile	specifies which parsing method to choose
	 * @exception	if temp file cannot be open
	 */
	
	public Parser(boolean bCppFile){
		  
		 m_bParseMethods = bCppFile; //if true be ready to parse C++ file
		  
		  m_membersArray = new MembersArray();
	      
		  m_scan = new Scanner();
		  
		  m_linesGlobal = new Buffer(1024);
		  
		  m_bCommaSeen = false;
        
		  m_bInsideEnum = false;

	 }

	/**
	 * SetParserMethod
	 * Purpose: unstructs the parser to parse a header or an implementation file
	 * @param bCpp	If false - parser a header, it true parse a cpp file
	 */
	
	public void SetParseMethod(boolean bCpp){
		m_bParseMethods = bCpp;
			
	}
	
	/**
	 * OpenOutputFile
	 * Purpose: opens the output file for input and resets all parse member 
	 * variables
	 * @param	strInFile the source file name
	 */
	
	public void OpenInputFile(String strInFile){
		
		String m_strAccessor = "protected";

	    ClassRepresentation cpCache = null;		   
        
		strCacheClassName = new String();	
        
		class_info = null;
		
		m_strInitializer = null;
		
		m_bCommaSeen = false;
        
		m_bInsideEnum = false;
		
		strReadName = ""; 
        
		strReadType = ""; 
        
		paramList = null;
	 	
		m_strAccessor = new String();
		
		strCacheClassName = new String(); 
		
		class_info = null;
		
		m_bCommaSeen = false;
        
		m_bInsideEnum = false;


		m_scan.OpenInputFile(strInFile);
	
	}	
	
	public void CloseAllFiles(){
		m_scan.CloseAllFiles();
	}
	
	/**
	 * isCKeyword
	 * Purpose: checks out if the input parameter is a valid C keyword
	 * @param str  a word to check out
	 * @return true is str is a valid C keyword, false otherwise
	 */
	
	public static boolean isCKeyword(String str){
		if(str.compareTo("break") == 0 || 
		   str.compareTo("case") == 0 || 
		   str.compareTo("char") == 0 || 
		   str.compareTo("const") == 0 || 
		   str.compareTo("continue") == 0 || 
		   str.compareTo("default") == 0 || 
		   str.compareTo("delete") == 0 ||
		   str.compareTo("do") == 0 || 
		   str.compareTo("double") == 0 || 
		   str.compareTo("else") == 0 || 
		   str.compareTo("enum") == 0 || 
		   str.compareTo("extern") == 0 || 
		   str.compareTo("float") == 0 || 
		   str.compareTo("for") == 0 || 
		   str.compareTo("goto") == 0 || 
		   str.compareTo("if") == 0 || 
		   str.compareTo("int") == 0 || 
		   str.compareTo("long") == 0 || 
		   str.compareTo("new") == 0 ||
		   str.compareTo("register") == 0 || 
		   str.compareTo("return") == 0 || 
		   str.compareTo("short") == 0 || 
		   str.compareTo("signed") == 0 || 
		   str.compareTo("sizeof") == 0 || 
		   str.compareTo("static") == 0 || 
		   str.compareTo("struct") == 0 || 
		   str.compareTo("switch") == 0 || 
		   str.compareTo("typedef") == 0 || 
		   str.compareTo("union") == 0 || 
		   str.compareTo("unsigned") == 0 || 
		   str.compareTo("void") == 0 || 
		   str.compareTo("volatile") == 0 || 
		   str.compareTo("while") == 0)
		   		   return true;
		return false;
	}
		   

/**
 * isConstCharOrString
 * Purpose: finds out if the input parameter is a constant char of form 'x' or
 * a quoted string
 * @param str a word to check out
 * @return true if str is a const char or str, false otherwise
 */

protected boolean isConstCharOrString(String str){
	int iSize = str.length();
	return ((str.charAt(0) == '"'	&& str.charAt(iSize-1) == '"') || 
		    (str.charAt(0) == '\'' &&  str.charAt(iSize-1) ==  '\''));
}


/**
 * skipWord
 * Purpose: reads a word from the input stream
 * @return the word read right after the skipped one
 */

private String skipWord()
{
	byte btArray[] = new byte[m_iBufSize];
	return m_scan.getWord(btArray, m_iBufSize);
}

/**
 * findWord
 * Purpose: fins a word in the source file
 * @param strToFind		word to look for
 * @return true if the word was found, false if the end of file was reached
 */

private boolean findWord(String strToFind)
{
	String str;
	if(m_bDebug) System.out.println("strToFind is " + strToFind);
	byte btArray[] = new byte[m_iBufSize];
	do{
		str = m_scan.getWord(btArray, m_iBufSize);
		if(str.compareTo("") == 0) return false;
	}while(str.compareTo(strToFind) != 0);

	return true;
}

/**
 * findAndDoNotSkipWord
 * Purpose: searches for a word in the  source file until either 
 * the word to search is found or strDontSkip is encountered
 * @param	strWordToFind	the search word
 * @param	strDontSkip		the word not to be skipped
 * @return	true if the word was found, false if the strDontSkip
 * was encountered or end of file was reached
 */

boolean findAndDoNotSkipWord(String strWordToFind, String strDontSkip)
{
	if(m_bDebug) System.out.println("findAndDontSkipWord " + strWordToFind + " ," +
		strDontSkip);
	byte btArray[] = new byte[m_iBufSize];
	String str;
	do{
		
		str = m_scan.getWord(btArray, m_iBufSize);
		if(str.compareTo("") == 0) return false;
		if(m_bDebug) System.out.println("m_scan.getWord() -> \"" + str);
		if(str.compareTo(strDontSkip) == 0) return false;
	
	}while(str.compareTo(strWordToFind) != 0);

	return true;
}

/**
 * skipMatching
 * Purpose: read the function body between strWordToSkip and strWordtoFind
 * putting the words read into strArray.
 * ; character serves as a signal to start entering a new element into strArray
 * @param strWordToSkip		the word to be skipped
 * @param strWordToFind		the word to find
 * @param strArray	array  to hold the function's body
 * @return false if the end of the file was reached, true otherwise
 */


boolean skipMatching(String strWordToSkip, String strWordToFind, StringArray strArray)
{
  
	
	if(m_bDebug) System.out.println("skipMatching( " + strWordToSkip + " , "
	                   + strWordToFind);
   byte btArray[] = new byte[m_iBufSize];
   String str;
   boolean bNewLine = true;
   do{
	   str = m_scan.getWord(btArray, m_iBufSize);
	   if(str.compareTo("") == 0) return false;
	   if(str.compareTo("for") == 0){ //take care of for loop
	      
		  strArray.addElement(str);
		  str = m_scan.getWord(btArray, m_iBufSize);
	   	  if(str.compareTo("") == 0) return false;
		  else if(str.compareTo("(") == 0){
			  strArray.appendToLastString(str);
			  while(str.compareTo(")")!= 0 && str.compareTo("") !=0){
	   			 str = m_scan.getWord(btArray, m_iBufSize);
		      	 if(isCKeyword(str))
		             str += " ";
	   	  		 strArray.appendToLastString(str);
			  }	//while
	   	  bNewLine = true;
		  }//else if
	   	  continue;
	   }
		if(str.compareTo("}") == 0 || str.compareTo("{") == 0)
		   bNewLine = true;
	   else if(isCKeyword(str))
		   str += " ";
	   if(str.compareTo(";") == 0 || str.compareTo("';") == 0){
		   bNewLine = true;
	   	   strArray.appendToLastString(str);
	   }
	   if(!bNewLine)
		   strArray.appendToLastString(str);
	   else if(bNewLine && str.compareTo(";")!=0 && str.compareTo("';")!=0  ){
	       if(str.compareTo("{") != 0  &&  str.compareTo("}") != 0)
				strArray.addElement(" " + str);
	   	   else 
			   strArray.addElement(str);
		   bNewLine = false;
	   }
	   
	   if(str.endsWith("}") || str.endsWith("{"))
		   bNewLine = true;
	   if(m_bDebug) System.out.println("    " + str);
	   if(str.compareTo(strWordToSkip) == 0)
		   skipMatching(strWordToSkip, strWordToFind, strArray);
   }while(str.compareTo(strWordToFind) !=0 );

   return true;
}

boolean skipMatching(String strWordToSkip, String strWordToFind)
{
   	
   if(m_bDebug) System.out.println("skipMatching( " + strWordToSkip + " , "
	                   + strWordToFind);
   byte btArray[] = new byte[m_iBufSize];
   
   boolean bNewLine = true;
   
   String str;
   do{
	   str = m_scan.getWord(btArray, m_iBufSize);
	   if( str.compareTo("")==0 ) 
		   return false;
	   else if(str.compareTo(strWordToSkip) == 0)
		   skipMatching(strWordToSkip, strWordToFind);
   
   }while(str.compareTo(strWordToFind) !=0 );

   
   return true;
}




private ClassRepresentation cpCache = null;		   
private String strCacheClassName;	
protected ClassRepresentation class_info = null;

/**
 * findClass
 * Purpose: determines if class with a given name already has a ClassRepresentation
 * uses strCacheClassName to hold a name of the last found class
 * @param strClassName  the class name to find
 * @param bIsSuper	specifies if the class to find is a super class
 * @return	ClassRepresentation of the found class
 *
 */
 

ClassRepresentation findClass(String strClassName, boolean bIsSuper)
{
	
	ClassRepresentation c, d;
	if(cpCache!=null && strClassName.compareTo(strCacheClassName) == 0) return cpCache;
	for(c = class_info; c!=null;c = c.GetNext())
		if(c.GetName().compareTo(strClassName) == 0){
			cpCache = c;
			strCacheClassName = strClassName;
			return c;
		}
		/*c = new ClassRepresentation(strClassName, class_info, bIsSuper);
		class_info = c;
		*/
	c = new ClassRepresentation(strClassName, null, bIsSuper);
	
	if(class_info == null) 
			class_info = c;
	else {
		for(d = class_info; d.GetNext() != null; d = d.GetNext());
		d.SetNext(c); //add to the head of the list
	}		
	
	return c;
}


/**
 * setSuperClass
 * Purpose: sets a super class for a class named strClassName
 * @param	strClass the class name to have a super class set for
 * @param	strSuperClass	the name of the super class
 *
 */
 

void setSuperClass(String strClassName, String strSuperClassName)
{
	if(strSuperClassName.compareTo(",") == 0) return;
	if(m_bDebug) System.out.println("setSuperClass( " + strClassName + " , " +
									strSuperClassName);
	ClassRepresentation c1 = findClass(strClassName, false);
	ClassRepresentation c2 = findClass(strSuperClassName, true);
	c1.addSuperClass(c2);
}

/**
 * readSuperClasses
 * Purpose: determines if the class named strClassName is a child class
 * @param	strClassName	the class to be investigated
 * @return true if class is followed by a valid class definition,
 * false otherwise
 *
 */

boolean readSuperClasses(String strClassName)
{
	if(m_bDebug) System.out.println("readSuperClasses( " + strClassName);
	byte btArray[] = new byte[m_iBufSize];
	String str;
	while(true){
		str = m_scan.getWord(btArray, m_iBufSize);
		if(str.compareTo("") == 0) return false;
		if(m_bDebug) System.out.println("m_scan.getWord() -> " + str);
		if(str.compareTo(":") == 0) continue;
		if(str.compareTo("public") == 0) continue;
		if(str.compareTo("private") == 0) continue;
		if(str.compareTo("protected") == 0) continue;
		if(str.compareTo("{") == 0) break;
		if(str.compareTo(";") == 0) return false;
		else setSuperClass(strClassName, str);
	}

	return true;

}  

/**
 * readGlobalBody
 * Purpose: read a global function and store it's body in m_linesGlobal array
 * @param strMemberName		the function name
 * @param str	the function return type
 * @param parameters	the function's parameters list
 *
 */
void readGlobalBody(String strMemberName, String strType,  ParmList parameters){
						
 	m_linesGlobal.Concatenate("\r\n/**\r\n");

	if(parameters != null)
		parameters.printAsParms(m_linesGlobal);

	if(strType.compareTo("void") != 0 &&
		strType.compareTo(":") != 0 &&
	   strType.compareTo(";") != 0 &&
	   strType.compareTo("}") != 0)
	       m_linesGlobal .Concatenate("* @return " + strType + "\r\n");
	m_linesGlobal.Concatenate("*/\r\n");
	
	
	
	if(strType.compareTo(":") !=0 && strType.compareTo(";") != 0 && strType.compareTo("}") !=0 ){
		  
		m_linesGlobal.Concatenate("static " + strType + " ");
	}
		
		
	if(parameters != null){ 
			m_linesGlobal.Concatenate(strMemberName + "(");
			parameters.printNames(m_linesGlobal);
			m_linesGlobal.Concatenate(")\r\n{");
	}
		
	else
		   m_linesGlobal.Concatenate(strMemberName + "()\r\n{");
			
		
	
	//m_strInitializer = "";
	
	
	m_scan.FlushBuffer(); //clear the buffer 
	skipMatching("{", "}");
	
	if(!m_bDefnOnly)
		m_linesGlobal.Concatenate(m_scan.GetBuffer());
    else
		m_linesGlobal.Concatenate("\n}");
	
	
}	
/**
 * addGlobals
 * Purpose: adds the array of global functions and variables to the m_membersArray
 * Note: this function should be called when the parsing if over
 *
 */


public void addGlobals(){

	MemberBody memBodies = new MemberBody("__globals",  m_linesGlobal); //the actual body
	m_membersArray.addElement(memBodies); 
}	
//////////////
private String m_strInitializer; //constructor initialize list
/**
 * readMemberBody
 * Purpose: reads the class method's body; generates comments and adds both
 * the comments and the body to m_membersArray 
 * @param strClassName		the function's class name
 * @param strMemberName		the function's name
 * @strType		the function's return type
 * @parameters	the function's parameters list
 */

void readMemberBody(String strClassName, String strMemberName, String strType,
					ParmList parameters){
						
 	Buffer lines1 = new Buffer(1024);
	Buffer lines2;

	MemberBody memBody1, memBody2;
	String strMemName = new String(); //a unique name which represents a functions
	//in m_membersArray;
	strMemName = strClassName;
	strMemName += "__";
	strMemName += strMemberName;
	if(parameters != null)
		strMemName = parameters.printTypes(strMemName);

	if(parameters != null)
		parameters.printAsParms(lines1);

	if(strType.compareTo("void") != 0 &&
		strType.compareTo(":") != 0 &&
	   strType.compareTo(";") != 0 &&
	   strType.compareTo("}") != 0 &&
	   strClassName.compareTo(strMemberName) != 0)
	   	    lines1.Concatenate("* @return " + strType + "\r\n");
	lines1.Concatenate("*/");
	memBody1 = new MemberBody(strMemName, lines1); //contains only comments
	
	
	lines2 = new Buffer(1024);

	strMemName += "__body";

	if(strType.compareTo(":") !=0 && strType.compareTo(";") != 0 && strType.compareTo("}") !=0 ){
		if(strClassName.compareTo(strMemberName) != 0)
		    lines2.Concatenate(strType + " ");
	 	else  
			lines2.Concatenate(strType);
	}
		
	if(strMemberName.charAt(0) == '~')  //destructor
		lines2.Concatenate("void finalize() {");
		
	else{
		
		if(parameters != null){ 
			lines2.Concatenate(strMemberName + "(");
			parameters.printNames(lines2);
			lines2.Concatenate(")\r\n{");
		}
		
		else
			lines2.Concatenate(strMemberName + "()\r\n{");
			
		
		
	}
	
	if(m_strInitializer != null)
		lines2.Concatenate(m_strInitializer);
	m_strInitializer = "";
	
	m_scan.FlushBuffer(); //clear the buffer 
	skipMatching("{", "}");
	
	if(!m_bDefnOnly)
		lines2.Concatenate(m_scan.GetBuffer());
    else
		lines2.Concatenate("\n}");
	///concat to lines2
	memBody2 = new MemberBody(strMemName, lines2); //the actual body
	

	m_membersArray.addElement(memBody1); 
	m_membersArray.addElement(memBody2);

}	
 
private boolean m_bCommaSeen = false;
private boolean m_bInsideEnum = false;
private int		m_iEnumValue = 0;
/**
 * readMember
 * Purpose: reads a class member either a variable or a method
 * @param strClassName  the class name
 * @param type	type of a member (constructor, variable ...)
 * @return false if the end of class defintio of the end of file was reached
 * true otherwise
 *
 */


boolean readMember(String strClassName, Type type) {
	
	byte btArray[] = new byte[m_iBufSize];
	
	if(m_bDebug) System.out.println(" readMember(" + strClassName + " " + strReadName + " " + strReadType);
	
	String strSeparator = new String();
	
	boolean bIsStatic = false;
	
	strReadName = "";
	
	if(m_bCommaSeen){
		if(m_bDebug) System.out.println("comma seen, continue with type " + strReadType);
	}
	else{
		if((strReadType = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
		if(m_bDebug) System.out.println("first word " + strReadType);
	}

	if(strReadType.compareTo("public") == 0){
		m_strAccessor = "public";
		skipWord(); return true;
    }
	else if(strReadType.compareTo("private") == 0){
		m_strAccessor = "private";
		skipWord(); return true;
	}
	else if(strReadType.compareTo("protected") == 0){
		m_strAccessor = "protected";
	    skipWord(); return true;
	}
	else if(strReadType.compareTo("enum") == 0){
		if(m_bDebug) System.out.println("enum " + strReadType);
		if(!findAndDoNotSkipWord("{", ";"))
			return false;
		if((strReadType = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
		m_bInsideEnum = true;
	}
	if(m_bInsideEnum){
		if(strReadType.compareTo("}") == 0){      //matching {
			m_bInsideEnum = false;
			return true;
		}
		strReadName = strReadType;
		if((strSeparator = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
		if(strSeparator.compareTo("=") == 0) {
			if((strSeparator = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
			strReadName += " = ";
			m_iEnumValue = new Integer(strSeparator).intValue() + 1;
			strReadName += strSeparator;
			if((strSeparator = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
		}
		
		else if(!strSeparator.equals("=")){
			strReadName += " = ";
			strReadName += String.valueOf(m_iEnumValue++);
		}
		if(strSeparator.compareTo("}") == 0) { //matching {
			m_iEnumValue = 0;
			m_bInsideEnum = false;
		}
		
		
		strReadType = "static final int";
		if(m_bDebug) System.out.println("enum " +  strReadName);
		type.SetType(Type.Variable);
		return true;
	    }

	
	StringArray lines = new StringArray();
	if(strReadType.compareTo("{") == 0) {
		lines = new StringArray();
		skipMatching(strReadType, "}"); 
		return true;
	}

	if(strReadType.compareTo("}") == 0) {
		m_scan.ungetByte((byte)strReadType.charAt(0));
		m_bCommaSeen = false;
		return false;
	}
	if(strReadType.compareTo(";") == 0) return true;
	if(strReadType.compareTo("class") == 0 ||
		strReadType.compareTo("struct") == 0){
		String strName = new String();
		String strNestedClassName;
		if((strNestedClassName = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0)
			return true;
		if(m_bDebug) System.out.println("nested_class_name " + strNestedClassName);
		if(readSuperClasses(strName)){
			strName = strClassName;
			strName += strNestedClassName;
			readClassBody(strName);
			findClass(strName, false).SetNested(true);
			skipMatching("{", "}");
			if((strSeparator = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0)
				return false;
			return true;
		}
	}

	if((strReadName = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0)
		return false;
	if(m_bDebug) System.out.println("name = " + strReadName);

	if(strReadName.compareTo("(") == 0){
		strReadName = strReadType;
		if(m_bDebug) System.out.println("Before Constuructor");
		paramList = readParmList();

		if(findAndDoNotSkipWord("{", ";")){
			if(strReadName.compareTo(strClassName) == 0){
				type.SetType(Type.InlinedConstructor);
				readMemberBody(strReadName, strReadName, "", paramList);
			} 
			else{
				readMemberBody(strReadName, strReadName, "", paramList);
				return true;
			}
		}
		else
			type.SetType(Type.Constructor);
		if(m_bDebug)System.out.println("found constructor");
		return true;
	}
	

	if(strReadType.compareTo("~") == 0){
		strReadType += strReadName;
		strReadName = strReadType;
		strReadType = "";
		paramList = readParmList();
		if(findAndDoNotSkipWord("{", ";")){
			type.SetType(Type.InlinedDestructor);
			readMemberBody(strReadName.substring(1),strReadName, "", paramList);
		}
		else
			type.SetType(Type.Destructor);
			 if(m_bDebug) System.out.println("found destructor");
			 return true;
	}
	if(strReadName.compareTo("{") == 0) {skipMatching("{", "}"); return true;}
	if(strReadName.compareTo("}") == 0) {m_scan.ungetByte((byte)'}'); m_bCommaSeen = false; return false;}
	if(strReadName.compareTo(";") == 0) {m_scan.ungetByte((byte)';'); return true;}

	type.SetType(Type.Variable);

	for(;;){
		if(strReadType.compareTo("static") == 0) bIsStatic = true;
		if((strSeparator=m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
		if(m_bDebug) System.out.println("separator= " + strSeparator);

		if(strSeparator.compareTo("}") == 0) { m_scan.ungetByte((byte)'}'); m_bCommaSeen = false; return false;}
		if(strSeparator.compareTo("{") == 0){
			skipMatching("{", "}");
		}
		if(strSeparator.compareTo("[") == 0){
			skipMatching("[", "]");
			type.SetType(Type.Array);
			break;
		}
		if(strSeparator.compareTo("(") == 0){          //read member parameters
			if(m_bDebug){ System.out.println("Seen start of function");
			              System.out.println("before readParmList"); }
			paramList  = readParmList();
			if(m_bDebug)
			System.out.println("after read parmList found a method "); 

			if(findAndDoNotSkipWord("{", ";")) { //}
				if(strReadName.compareTo("=") == 0 ||
				   strReadName.compareTo("!=") == 0 || 
				   strReadName.compareTo("==") == 0 ||
				   strReadName.compareTo("new") == 0 ||
				   strReadName.compareTo("delete") == 0)
						bIsStatic = true;
				readMemberBody(strClassName, strReadName, strReadType, paramList);
				if(bIsStatic)type.SetType(Type.StaticInlinedMethod);
				else type.SetType(Type.InlinedMethod);
			}
			else{
				if(bIsStatic)
					type.SetType(Type.StaticMethod);
				else type.SetType(Type.Method);
			}

			if(m_bDebug)System.out.println("end of function");
			break;
		}

		if(strSeparator.compareTo(";") == 0){
			m_bCommaSeen = false;
			break;
		}
		if(strSeparator.compareTo(",") == 0){
			m_bCommaSeen = true;
			return true;
		}

		else if(strReadName.compareTo("*") == 0)  //Replacer will take care of it
			strReadType += " " + strReadName;
		else if(strReadName.compareTo("&") == 0) 
			strReadType += " " + strReadName;
		else  strReadType = strReadName;        //.substring(0, m_iBufSize -1);
		
		strReadName = strSeparator;  //strType.substring(0, m_iBufSize -1);
	
	} 

	if(strReadType.compareTo(":") == 0) strReadType = "";
	return true;


}	

/**
 * findMember
 * Purpose: finds a class member which was previously read
 * @param strClassName	the class name
 * @param strMethodName	the name of the member to be found
 * @return ClassMemberRepresentation of the found member, or null if 
 * the member was not found
 *
 */

ClassMemberRepresentation findMember(String strClassName, String strMethodName)
{

   ClassRepresentation c = findClass(strClassName, false);
   if(c!=null)
	  for(ClassMemberRepresentation m = c.GetMembers(); m!=null; m = m.GetNext())
	      if(m.GetName().compareTo(strMethodName) == 0) return m;
   return null;


}	

/**
 * isStaticMethod
 * not being used
 *
 */
boolean isStaticMethod(String strClassName, String strMethodName)
{
	if(strMethodName.compareTo("=") == 0 ||
	   strMethodName.compareTo("!=") == 0 ||
	   strMethodName.compareTo("==") == 0 ||
	   strMethodName.compareTo("new") == 0 ||
	   strMethodName.compareTo("delete") == 0)
	    return true;
	ClassMemberRepresentation m = findMember(strClassName, strMethodName);
    if(m == null)
		return true;

	return (m.GetMemberType().GetType() == Type.StaticMethod || 
		m.GetMemberType().GetType() == Type.StaticInlinedMethod);

}

/**
 * isAValidName
 * Purpose: determines if the strName is a valid token
 * @param strName the word to be checked
 * @return boolean
 *
 */

boolean isAValidName(String strName)
{

   return(strName!=null && strName.length() > 0 && strName.charAt(0)!=';');
}


String strReadName; //Since it is not possible to  pass Strings by reference for modifications
String strReadType; 
ParmList paramList;
/**
 * readClassBody
 * Purpose: parse the class definition
 * @param strClassName	the class name
 */

void readClassBody(String strClassName) 
{
	if(m_bDebug) System.out.println("readClassBody " + strClassName);
	ClassRepresentation c = findClass(strClassName, false);
	strReadName = new String();
	strReadType = new String();
	Type type = new Type();
	ClassMemberRepresentation mdouble = null;
	ClassMemberRepresentation m = null;
	paramList = new ParmList("", "" ,null);  //?????????? check it out
	while(readMember(strClassName, type))
		if(isAValidName(strReadName)){
			m = new ClassMemberRepresentation(strReadType, strReadName, type, m, paramList, m_strAccessor); 
			c.SetMembers(m);
			if(m.GetMemberType().GetType() == Type.Method)
				for(mdouble = c.GetMembers(); mdouble!=null; mdouble = mdouble.GetNext())
					if((m.GetMemberType().GetType() == Type.StaticMethod || 
					   m.GetMemberType().GetType()  == Type.Method) &&
					   m.GetName().compareTo(mdouble.GetName()) == 0 &&
					   m.GetMemberType().GetType() == mdouble.GetMemberType().GetType()){
					//cannot cope with overloaded functions yet.
					m.SetMemberType(new Type(Type.StaticMethod));
				}

	    }
}

   /**
    * readParmList
	* Purpose: read a list of function parameters and put them into ParmList
	* @return ParmList
	*
	*/

 
   ParmList readParmList()
   {
   
		if(m_bDebug)System.out.println("enter readParmList()");

		byte []btArray = new byte[m_iBufSize];
		String strToken;
		ParmList list = new ParmList("", "", null);
		String strType = new String();
		String strName = new String();
		do{
		   if((strToken = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return null;

		   if(strToken.compareTo(",") == 0 || strToken.compareTo(")") == 0){
				strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-3);
				strName = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2);
				if(strType.compareTo(",") == 0 || strType.compareTo("(") == 0 || strType.compareTo(":") == 0){
					strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2);
					strName = "";
				}

				if(strType.compareTo("*") == 0 || strType.compareTo("&") == 0){
					for(int i = 0; i < 30 ; i++){
						String str = new String(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-(4 +i)));
						strType = str + strType;
						if(str.compareTo("*") !=0 && str.compareTo("&") !=0)
							   break;
						
					}
					//strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-4) + strType;
					strName = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2);
				}

				if(strType.compareTo("=") == 0){
					strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-5);
					strName = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-4);
				}

				if(strName.compareTo("&") == 0){
					strName = "dummy_";
					strType += "&";
				}
				if(strName.compareTo("*") == 0){
					strName = "dummy_";
					strType += "*";
				}
				if( ((m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-4)).compareTo("unsigned") == 0) &&
					(strType.compareTo("long") == 0 || strType.compareTo("short") == 0 || strType.compareTo("int") == 0 ||
					strType.compareTo("char") == 0)){

					strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-4);
					strType += "_";
					strType += m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-3);
				}


				if( (strType.compareTo("unsigned") == 0) &&
					(strName.compareTo("long") == 0 || strName.compareTo("short") == 0 || strName.compareTo("int") == 0 ||
					strName.compareTo("char") == 0)){
					strType+="_";
					strType+=strName;
					strName = "";
					list = new ParmList(strType, "", list);
				}
				else if(strName.compareTo("void") == 0)
					list = new ParmList(strName, "", list);
				else if(strName.length() > 0 && Scanner.isIdentifier( (byte)(strName.charAt(0)) ) )
					list = new ParmList(strType, strName, list);
				else if(strName.length() > 0 && strName.charAt(0) == '(')
					list = new ParmList("", "", list);
				else
					list = new ParmList(strType, "0", list);
		   }
		}while(strToken.compareTo("{") != 0 && strToken.compareTo(";") != 0 && strToken.compareTo(")") != 0);
   
		if(m_bDebug){
			System.out.println("strType is " + strType);
			System.out.println("strName is " + strName);
		}

		if(strToken.compareTo(")") == 0){
			if((strToken = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return null;
			if(strToken.compareTo("const") == 0)
				if((strToken = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return null;
		}

		//read initializer list
		if(strToken.compareTo(":") == 0){
			if((strToken = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return null;
			  m_strInitializer = "\n ";
			  boolean bSuperConstructorCall = false;
			  while(strToken.compareTo("{") != 0 && strToken.compareTo(";") !=0){
				  if(strToken.charAt(0) >='A' && strToken.charAt(0) <= 'Z'){ //traditionally class names 
					   m_strInitializer += "super";		   //are capitalized
					   bSuperConstructorCall = true;
				  }
				  else if(bSuperConstructorCall){
					  if(strToken.compareTo("(") == 0)	 m_strInitializer += "(";
					  else if(strToken.compareTo(")") == 0){
						  m_strInitializer+=");\n\t";
						  bSuperConstructorCall = false;
					  }
					  else if(strToken.compareTo(",") == 0) m_strInitializer += ",";
					  else m_strInitializer+=strToken;
				  }
					  
				  else{ 
					   if(strToken.compareTo("(") == 0) m_strInitializer += " = ";
					   else if(strToken.compareTo(")") == 0) m_strInitializer += ";\n\t";
					   else if(strToken.compareTo("')") == 0)m_strInitializer += "';\n\t";  
					   else if(strToken.compareTo(",") == 0) m_strInitializer += "";
					   else m_strInitializer += strToken;
				  }

				  if((strToken = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return null;
			  }	//while

		}  //if

		 m_scan.ungetByte((byte)(strToken.charAt(0)));
		 if(m_bDebug) System.out.println("leave readParmList()");
		 return list;	 
}
   
/**
 * readClass
 * Purpose: read a class or not a class
 * @return boolean false if the end of file has been reached
 * true otherwise
 *
 */


boolean readClass(boolean bDefnOnly)	throws IOException
{
    m_bDefnOnly = bDefnOnly;
	if(m_bDebug)System.out.println("readClass() {");
	byte [] btArray = new byte[m_iBufSize];
	StringArray lines = new StringArray();
	String strToken = new String();
	String strClassName = new String();
	int iWordsRead = 0;
	String strConst = new String();

	for(;;){
		
		if((strToken=m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
		if(isConstCharOrString(strToken))
			strConst = new String(strToken);
		iWordsRead++;
		//boolean bTest = (strToken.compareTo("class") == 0);
		if(strToken.compareTo("class") == 0 ||
			strToken.compareTo("struct") == 0){	//start of class definition
			if((strClassName=m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
			if(readSuperClasses(strClassName)){
				readClassBody(strClassName); //will read unto }
				if(m_bDebug) System.out.println("}");
				m_scan.ungetByte((byte)' '); //clear scan buffer
				iWordsRead = 0;
				return true;
			}

			continue;
		}

		String strType = new String();
		strClassName = "";
	 	String strMethodName = new String();
		if(strToken.compareTo("(") == 0){   //beginning of formal parameter list?
			if(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-3).compareTo(":") == 0 &&
				m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-4).compareTo(":") == 0) {
				
				iWordsRead = 0;
				strClassName = m_scan.m_tkStack.getClassNameFromStack(5);
				strMethodName = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2);
				strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-6);
				if(strType.compareTo("*") == 0 || strType.compareTo("&") == 0){
					for(int i = 0; i < 32; i++){
						String str = new String(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-(7 + i))); 
						strType = str + strType;
						if(str.compareTo("*") !=0  &&  str.compareTo("&") != 0)
				    		  break;
							//strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-7);
					}
				}
			}

			else if(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-3).compareTo("~") == 0 &&
				m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-4).compareTo(":") == 0 &&
				m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-5).compareTo(":") == 0){
				strClassName = m_scan.m_tkStack.getClassNameFromStack(6);
				strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-7);
				if(strType.compareTo("*") == 0 || strType.compareTo("&") == 0)
					   strType = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-8);
				strMethodName = "~";
				strMethodName+=m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2);
			}

			if(strClassName.compareTo("") != 0) { //start of class method
				
				iWordsRead = 0;
				if(m_bDebug)System.out.println("start of class method");
				ParmList p = readParmList();
				//String strToken;
				if((strToken = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
				    iWordsRead ++;
				if(p!=null && strToken.compareTo("{") == 0){ //found a body
					if(m_bParseMethods){
						readMemberBody(strClassName, strMethodName, strType, p);
						if((strToken=m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
					}

					else{
						iWordsRead = 0;
						skipMatching("{", "}");
					}
				}
				if(m_bDebug)System.out.println("end of class method");
			}	
					
				else{ //start of global function
					if(m_bDebug)System.out.println("start of global function");
					strMethodName = m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2);
					for(int i = 0; i< 30; i++){
						  String str = new String(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize() - (3+i) ) );
						  strType = str+strType;
						  if(str.compareTo("*") !=0 && str.compareTo("&") != 0)
							 break;
					}
					    
					ParmList p = readParmList();
					//String strToken;
					if((strToken = m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
					    iWordsRead ++;
					if(strToken.compareTo("{") == 0){
						if(m_bDebug)
						 if(p!=null){
							p.printNames();
						 }
					
						if(m_bDebug){
							System.out.println("Before calling readGlobalBody, type is " + strType);
							m_scan.m_tkStack.printStack(7);
						}
						readGlobalBody(strMethodName, strType, p);
						iWordsRead = 0; 
						if((strToken=m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
				
					
					}

					else if(strToken.compareTo(";") == 0){
						iWordsRead = 0;   
						continue;
					}
					else if((strToken=m_scan.getWord(btArray, m_iBufSize)).compareTo("") == 0) return false;
				}	     iWordsRead++;
			}

			
			if(/*m_bParseMethods && */m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2).compareTo("}") !=0 &&
				strToken.compareTo(";") == 0){	 //end of declaration
				if(m_bDebug)System.out.println("start of static declaration");
				if(m_bDebug)m_scan.m_tkStack.printStack(10);
				m_linesGlobal.Concatenate("\n");
				m_linesGlobal.Concatenate("/*@c2j++ The following variable used to be declared global */");
				m_linesGlobal.Concatenate("\n");
				for(int i = m_scan.m_tkStack.GetSize() - iWordsRead; i < m_scan.m_tkStack.GetSize(); i++){
					if(m_scan.m_tkStack.TokenAt(i).compareTo("static") == 0)
						m_linesGlobal.Concatenate("final "); //?????
					else if(m_scan.m_tkStack.TokenAt(i).compareTo("const") == 0){
						m_linesGlobal.Concatenate("static final ");
					   continue;
					}
					
					if(i == m_scan.m_tkStack.GetSize() -1){
					  if(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-2).compareTo("=") == 0) 
						 m_linesGlobal.Concatenate(strConst);
					}
					if(i!= m_scan.m_tkStack.GetSize() - iWordsRead || m_scan.m_tkStack.TokenAt(i).compareTo(";") != 0)    
					   m_linesGlobal.Concatenate(m_scan.m_tkStack.TokenAt(i) + " ");
					/*
						   for(int j = i; j >=0; j--){
							m_tos.writeBytes(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-j));
							if(m_bDebug)System.out.println(m_scan.m_tkStack.TokenAt(m_scan.m_tkStack.GetSize()-j));
						} */
				}
				
				m_linesGlobal.Concatenate("\n");
				iWordsRead = 0;	
				
				if(m_bDebug)System.out.println("end of declaration");
			}  //end of declaration

		} //end of for
			
		 
 }
 
}