using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace ParseMod { class Program { static void Main( string[] lasArgs ) { if( lasArgs.Length == 0 ) { Console.WriteLine( "Please specify an input file on the command line." ); return; } Console.WriteLine( "\nPlease note:\n\t1) This only works on model files containing no time indices.\n\t2) It requires that scientific notation is not used for numeric constants.\n\t3) It requires that integers are expressed as decimals e.g. 1.0.\n" ); Console.WriteLine( "Variable\t\tIndex" ); string lasFileName = lasArgs[0]; StreamReader lInputFile = new StreamReader( lasFileName ); StreamWriter lOutputFile = new StreamWriter( lasFileName + ".c", false ); Dictionary< string, uint > ldsnVariables = new Dictionary< string, uint >( ); uint lunNumVariables = 0; string lsLine = ""; string lsNewLine; bool lbInModelBlock = false; char[] lacSeperators = "+-*/()<>=,{}[];:\"'`~!&|\\%?".ToCharArray( ); while( ( lsNewLine = lInputFile.ReadLine( ) ) != null ) { lsNewLine = lsNewLine.Replace( '\t', ' ' ).Replace( '\r', ' ' ).Replace( '\n', ' ' ); if( lsNewLine.Contains( "//" ) ) { lsNewLine = lsNewLine.Substring( 0, lsNewLine.IndexOf( "//" ) ); } lsNewLine = lsNewLine.Trim( ); if( lsNewLine.Length == 0 ) continue; if( lsNewLine[0] != '@' ) { if( lsLine.Length == 0 ) lsLine = lsNewLine; else lsLine += " " + lsNewLine; if( lsNewLine[ lsNewLine.Length - 1 ] == ';' ) { // process the line // pad all operators with spaces { int lnSeperatorIndex, lnNewSeperatorIndex; lnSeperatorIndex = lsLine.IndexOfAny( lacSeperators ); while( lnSeperatorIndex >= 0 ) { lsLine = lsLine.Insert( lnSeperatorIndex, " " ); while( ( lnNewSeperatorIndex = lsLine.IndexOfAny( lacSeperators, lnSeperatorIndex + 2 ) ) == lnSeperatorIndex + 2 ) ++lnSeperatorIndex; lsLine = lsLine.Insert( lnSeperatorIndex + 2, " " ); if( lnNewSeperatorIndex >= 0 ) lnSeperatorIndex = lnNewSeperatorIndex + 1; else lnSeperatorIndex = -1; } } lsLine = lsLine.Trim( ); while( lsLine.Contains( " ^" ) ) lsLine = lsLine.Replace( " ^", "^" ); while( lsLine.Contains( "^ " ) ) lsLine = lsLine.Replace( "^ ", "^" ); while( lsLine.Contains( '^' ) ) { int lnPowIndex = lsLine.IndexOf( '^' ); int lnStartIndex = lnPowIndex - 1, lnEndIndex = lnPowIndex + 1; if( lsLine[lnStartIndex] == ')' ) { int lnBracketDepth = 1; while( lnBracketDepth > 0 ) { --lnStartIndex; if( lsLine[ lnStartIndex ] == ')' ) ++lnBracketDepth; else if( lsLine[ lnStartIndex ] == '(' ) --lnBracketDepth; } } else { do lnStartIndex--; while( lsLine[ lnStartIndex ] != ' ' ); lnStartIndex++; } if( lsLine[lnEndIndex] == '(' ) { int lnBracketDepth = 1; while( lnBracketDepth > 0 ) { ++lnEndIndex; if( lsLine[ lnEndIndex ] == ')' ) --lnBracketDepth; else if( lsLine[ lnEndIndex ] == '(' ) ++lnBracketDepth; } } else { do ++lnEndIndex; while( lsLine[ lnEndIndex ] != ' ' ); --lnEndIndex; } lsLine = lsLine.Substring( 0, lnStartIndex ) + " pow( " + lsLine.Substring( lnStartIndex, lnPowIndex - lnStartIndex ) + ", " + lsLine.Substring( lnPowIndex + 1, lnEndIndex - lnPowIndex ) + " ) " + lsLine.Substring( lnEndIndex + 1 ); } while( lsLine.Contains( " " ) ) lsLine = lsLine.Replace( " ", " " ); if( lsLine.StartsWith( "var " ) ) { string[] lasNewVariables = lsLine.Substring( 4, lsLine.Length - 5 ).Split( new char[]{ ' ' }, StringSplitOptions.RemoveEmptyEntries ); foreach( string lsNewVariable in lasNewVariables ) { ldsnVariables.Add( lsNewVariable, lunNumVariables ); Console.WriteLine( lsNewVariable + "\t\t" + lunNumVariables.ToString( ) ); ++lunNumVariables; } } else if( lsLine.StartsWith( "parameters " ) ) { lOutputFile.WriteLine( "static double " + lsLine.Substring( 11 ).Replace( ' ', ',' ).Replace( ",;", " ;" ) ); } else if( lsLine.StartsWith( "model " ) || lsLine.StartsWith( "model(" ) || lsLine.StartsWith( "model;" ) ) { lbInModelBlock = true; } else if( lsLine.Contains( '=' ) ) { if( lbInModelBlock ) { lsLine = " " + lsLine; foreach( KeyValuePair< string, uint > lKVP in ldsnVariables ) lsLine = lsLine.Replace( " " + lKVP.Key + " ", "ladInput[ " + lKVP.Value + " ]" ); lsLine = lsLine.Trim( ); if( lsLine[0] == '#' ) lOutputFile.WriteLine( "double " + lsLine.Substring( 1 ) ); else { int lnEqualsIndex = lsLine.IndexOf( '=' ); lOutputFile.WriteLine( "ldLHS =" + lsLine.Substring( 0, lnEqualsIndex ) + ";" ); lOutputFile.WriteLine( "ldRHS =" + lsLine.Substring( lnEqualsIndex + 1 ) ); lOutputFile.WriteLine( "ldDeviation = ldLHS - ldRHS;" ); lOutputFile.WriteLine( "ldDeviation *= ldDeviation;" ); lOutputFile.WriteLine( "ldResidual += isnormal( ldDeviation ) ? ldDeviation : skdNonNormalPunish;" ); } } else { lOutputFile.WriteLine( lsLine ); } } lsLine = ""; } } } lInputFile.Close( ); lOutputFile.Close( ); } } }