package graph; import java.io.IOException; import java.io.InputStream; import java.io.StreamTokenizer; /** * Parses an ADJ file and outputs an AdjacencyMatrix. * The format of the file is: * *
 *	# This is a comment
 *         Fa.Of   Sc.Of   Sem.R
 *	Fa.Of   2                      Faculty Offices
 *	Sc.Of   2       1              Faculty Secretary Offices
 *	Sem.R   1       1       0      Seminar Room
 *
 * 
* * The following parsing rules are used: * * * @see AdjacencyMatrix * @author Michael Shilman (michaels@eecs.berkeley.edu) * @version $Id$ */ public class AdjacencyParser { /** * Parse an ADJ file and output an AdjacencyMatrix * * @param s The Input stream of the file * @return The * @exception IOException * Thrown if there is any problem with the input stream * @exception FileFormatException * Thrown if there is a problem with the format * of contents of the file. */ public static AdjacencyMatrix parse(InputStream s) throws IOException, FileFormatException { StreamTokenizer st = new StreamTokenizer(s); st.commentChar('#'); st.parseNumbers(); st.eolIsSignificant(true); st.wordChars('(','('); st.wordChars(')',')'); st.wordChars('_','_'); st.wordChars('\'', '\''); int val; //Get the number of rows/columns from the first line int numCols = 0; while((val = st.nextToken()) != StreamTokenizer.TT_EOL) { if((val == StreamTokenizer.TT_WORD) || (val == StreamTokenizer.TT_NUMBER)) { String cname = ((val == StreamTokenizer.TT_WORD) ? st.sval : String.valueOf(st.nval)); //DBG System.out.println("Column = " + cname); numCols++; } else { String err = "Parse error, line " + st.lineno() + " : Expected string header for column " + numCols + "."; throw (new FileFormatException(err)); } } //DBG System.out.println("NumCols = " + numCols); AdjacencyMatrix mat = new AdjacencyMatrix(numCols); //Fill in the matrix line-by-line int y = 0; while(y < numCols) { val = st.nextToken(); if(val != StreamTokenizer.TT_WORD) { String err = "Parse error, line " + st.lineno() + " : Expected row header."; throw (new FileFormatException(err)); } //else ignore it //DBG System.out.println("Row header " + st.sval); //Traverse the row int x = 0; while(x <= y) { val = st.nextToken(); if(val != StreamTokenizer.TT_NUMBER) { String err = "Parse error, line " + st.lineno() + " : Expected integer edge weight, column " + x + "."; throw (new FileFormatException(err)); } else { mat.values[x][y] = mat.values[y][x] = (int)st.nval; x++; } } //Grab the title off the end of the row String label = new String(); while((val = st.nextToken()) != StreamTokenizer.TT_EOL) { if(val == StreamTokenizer.TT_WORD) { label = label + " " + st.sval; } else if(val == StreamTokenizer.TT_NUMBER) { label = label + " " + String.valueOf(st.nval); } else if(val == StreamTokenizer.TT_EOF) { //the end of the line was actually EOF if(y == (numCols-1)) { //we are on the last line anyway mat.names[y] = label; return mat; } else { String err = "Parse error, line " + st.lineno() + " : Premature EOF."; throw (new FileFormatException(err)); } } else { String err = "Parse error, line " + st.lineno() + " : Expected string label."; throw (new FileFormatException(err)); } } //DBG System.out.println("Label = " + label); mat.names[y] = label; y++; } //We are done with all the rows if((val = st.nextToken()) != StreamTokenizer.TT_EOF) { String warn = "Warning, line " + st.lineno() + " : Ignoring extra information at end of file"; System.out.println(warn); } return mat; } }