/** * parser for resistor structure strings * * @author Peter Schüller <mailto:e0125596@student.tuwien.ac.at> */ public class WiderstParser extends Object { //static member to record number of resistors // (unlimited resistors _could_ be calculated) public static int iEprogLimit = 0; /** * generic exception for this parser */ public static class WiderstParserException extends Exception { } /** * structure which can record * *) a single resistor * *) a parallel resistor-circuit * *) a serial resistor-circuit */ public static class Structure extends Object { /** * generic exception for structure operations */ public static class StructureException extends Exception { } //"no structure" public static final int ERROR = 0; //parallel circuit public static final int PARALLEL = 1; //serial circuit public static final int SERIAL = 2; //simple resistor public static final int RESISTOR = 3; //one of the above defined types public int iType; //array of structures below this one public Structure[] acSubStructures; //value if this is a simple resistor public double dResistorValue; /** * constructor * error is standard, so we know if we forgot to initialize */ Structure() { iType = ERROR; acSubStructures = null; } /** * add a (parsed) substructure into this * this function manages the array magic in this object */ public void addSubStructure( Structure s ) { Structure[] acNew; if( acSubStructures == null ) { acNew = new Structure[1]; } else { acNew = new Structure[1 + acSubStructures.length]; int i; for( i = 0; i < acSubStructures.length; i++ ) { acNew[i] = acSubStructures[i]; } } acNew[ acNew.length - 1 ] = s; acSubStructures = acNew; } /** * calculate the resistance of this structure * *) resistor: return value * *) parallel: return 1/( sum( 1/substructure_values ) ) * *) serial: return sum( substructure_values ) */ public double calculateResistance() throws StructureException { double d; int i; switch( iType ) { case ERROR: throw new StructureException(); case PARALLEL: d = 0.0; for( i = 0; i < acSubStructures.length; i++ ) { d += 1.0 / acSubStructures[i].calculateResistance(); } d = 1.0 / d; break; case SERIAL: d = 0.0; for( i = 0; i < acSubStructures.length; i++ ) { d += acSubStructures[i].calculateResistance(); } break; case RESISTOR: d = dResistorValue; break; default: throw new StructureException(); } return d; } } //end of structure class definition /** * parses a whole resistor structure from a string into the Structure */ public static Structure parseString( String s ) throws WiderstParserException { Structure sReturn = new Structure(); //this is a structure specification if( s.charAt(0) == '(' && s.charAt(s.length()-1) == ')' ) { //remove brackets s = s.substring( 1, s.length() - 1 ); //get type from last character switch( s.charAt( s.length() - 1 ) ) { case 'P': sReturn.iType = Structure.PARALLEL; break; case 'S': sReturn.iType = Structure.SERIAL; break; default: throw new WiderstParserException(); } //remove last character and ',' before if( s.charAt( s.length() - 2 ) == ',' ) s = s.substring( 0, s.length() - 2 ); else throw new WiderstParserException(); //find end of first substructure int iEnd = -1; //-1 = to allow the first substring operation to work do { s = s.substring( iEnd + 1, s.length() ); iEnd = findEndOfNextStructureSpecification( s ); sReturn.addSubStructure( parseString( s.substring( 0, iEnd ) ) ); } while( iEnd != s.length() ); } //this is a resistor specification else { iEprogLimit++; sReturn.iType = Structure.RESISTOR; try { sReturn.dResistorValue = ResistorCodes.decodeString( s ); } catch( ResistorCodes.ResistorCodesException e ) { throw new WiderstParserException(); } } return sReturn; } /** * this function finds the end of the first structure specification in the string s */ protected static int findEndOfNextStructureSpecification( String s ) throws WiderstParserException { int i; int iDepth = 0; for( i = 0; i < s.length(); i++ ) { switch( s.charAt( i ) ) { case '(': iDepth ++; break; case ')': iDepth --; //not allowed here if( iDepth == -1 ) throw new WiderstParserException(); break; case ',': if( iDepth == 0 ) { return i; } break; } } if( iDepth != 0 ) throw new WiderstParserException(); else return s.length(); } }