parseTools.h

Go to the documentation of this file.
00001 
00002 #pragma once
00003 
00004 
00005 #include <string>
00006 #include <assert.h>
00007 #include <sstream>
00008 #include <vector>
00009 #include <iostream>
00010 #include <string.h>
00011 
00012 
00021 //--------------------------Parser Kram ----------------------------------------------
00022 
00026 inline void             eatWS(char* str, unsigned int & stelle);
00027 
00028 
00031 inline std::string      eatWS(const std::string &str);
00032 
00033 
00036 template <class _istream>
00037 char            extractChar(char schar, _istream& sstream);
00038 
00039 /*
00040 template <class _istream>
00041 char            extractChar(char schar, std::string  str)
00042 {
00043         //std::stringstream strstream(str);
00044         //extractChar(schar,strstream );
00045         //str=strstream.str();
00046         return schar;
00047 }
00048 */
00049 
00052 template <class _istream>
00053 char            extractChar(_istream& sstream, char schar);
00054 
00055 
00058 template <class _istream>
00059 int             getSign(_istream& sstream);
00060 
00061 
00066 template <class _istream>
00067 std::string     stripComment(_istream& data, bool & isComment);
00068 
00069 
00072 template <class _istream>
00073 void            stripComments(_istream& data);
00074 
00075 
00079 template <class _istream>
00080 std::string     readCurrentComment(_istream& data);
00081 
00082 
00085 template <class _istream>
00086 void            seekToBraceLevel(_istream & inputData, int &currentLevel, int braceLevel);
00087 
00088 
00091 inline std::string extractNextData(std::stringstream &Data);
00092 
00093 
00096 inline std::string extractNextBracedData(std::stringstream &Data);
00097 
00098 
00101 template <class _istream>
00102 std::string     readParamName(_istream & inputData);
00103 
00104 
00107 template <class _istream>
00108 std::string     readParamValue(_istream & inputData, std::string name);
00109 
00110 
00114 inline int      countSubGroups(std::stringstream &polynomStream);
00115 
00116 
00120 inline int      countGroups(std::stringstream &polynomStream);
00121 
00122 
00127 inline int      countElements(std::stringstream &str);
00128 
00129 //-------------------------------------------------------------------------------------------------------------
00130 
00140 template <class RingType>
00141 typename RingType::ElementType   parseNumber(RingType* ring1, std::string strNum, int _epsPrecision )
00142 {
00143         std::stringstream ssNum;
00144         ssNum << strNum;
00145 
00146         // erzeute ein Element mit vorgegebener epsPrecsion.
00147         typename RingType::ElementType erg(_epsPrecision, "dummy");
00148         //=createNum<TNum>(_epsPrecision);
00149         
00150         assert(erg.getEpsPrecision()>=_epsPrecision);
00151 
00152         
00153         //    Algoritmus: solange nicht ganzen string ausgelesen:
00154         //            solange weiterer Summand{
00155         //           -lese {Vorzeichen,SummandKoeff}
00156         //           -lese epspotenz(Summand)
00157         //           -addiere Summand zu erg, falls epspotenz<=_epsPrecision
00158         //      }
00159         //      -Wandle das Ganze in trage Ziffer in erg ein 
00160 
00161         while (!ssNum.fail() && !ssNum.eof())
00162         {
00163                 int number=1;
00164 
00165                 int sign=getSign(ssNum);
00166                 if (ssNum.peek()!='e')
00167                         ssNum >> number;
00168                 number=number*sign;
00169 
00172                 int precision=0;
00173 
00174                 // wenn es eine epsZahl ist, muss jetzt '*' folgen
00175                 if (!ssNum.eof() && ( ssNum.peek()=='*' || ssNum.peek()=='e')) // soll * weggelassen werden koennen???
00176                 {
00177                         // assert nicht gut... Programm sollte wenigstens zu Ende Laufen, wenn ein Polynom
00178                         // nicht eingelesen werden kann. Oder zu Beginn sollten testweise alle Polynome eingelesen werden.
00179                         if (ssNum.peek()=='*')
00180                                 extractChar('*',ssNum);
00181                         extractChar('e',ssNum);
00182                         if (ssNum.peek()=='p')
00183                         {
00184                                 extractChar('p',ssNum);
00185                                 extractChar('s',ssNum);
00186                         }
00187                         if ( !ssNum.eof() && ssNum.peek()=='^')
00188                         {
00189                                 extractChar('^',ssNum);
00190                                 ssNum >> precision;
00191                         }
00192                         else
00193                         {
00194                                 precision=1;  //epsExponent ist voraussichtlich 1
00195                         }
00196 
00197                 }
00198                 if (precision<=_epsPrecision)
00199                 {
00200                         //int number2=erg[precision];// get+set or addValue
00201                         erg.setValue(precision, ring1->getField()->ConvertScalar( number) );
00202                         //erg[precision]+=number;
00203                 
00204                 }
00205         }
00206         ssNum >> std::ws;
00207         if (ssNum.fail() || !ssNum.eof())
00208         {
00209                 std::cerr << "error during parseNumber, wrong format ?" << std::endl;
00210                 throw   "error during parseNumber, wrong format ?";
00211         }
00212         return erg;
00213 }
00214 
00215 
00217 inline int getMonomDegree(std::string monomGroup)
00218 {
00219         int monomDegree=0;
00220         for (size_t strPos=0;strPos<monomGroup.length();strPos++)
00221         {
00222                 if (monomGroup[strPos]==',')
00223                         monomDegree++;
00224         }
00225         return monomDegree;
00226 }
00227 
00228 inline int getMaxMonomDegree( std::string polynomString)
00229 {
00230         #ifdef DEBUG
00231         std::cerr << "getMaxMonomDegree" << std::endl;
00232         #endif
00233 
00234         int MaxMonomDegree=0;
00235 
00236         std::stringstream         polynomStream1;
00237         polynomStream1 << polynomString;
00238         polynomStream1 >> std::ws;
00239         extractChar('{',polynomStream1);
00240 
00241         #ifdef DEBUG
00242                 std::cerr << "polynomStream1" << polynomStream1.str() << std::endl;
00243         #endif
00244 
00245         while (!polynomStream1.eof() && polynomStream1.peek()=='{')
00246         {
00247                 std::string monomGroup1=extractNextBracedData(polynomStream1);
00248                 polynomStream1 >>std::ws;
00249                 if ( polynomStream1.peek()!='}' )               
00250                         extractChar(',',polynomStream1);
00251                 polynomStream1 >>std::ws;
00252                 // get degree of monoms in this grout : is equal to number of elements decreased by 1.
00253                 int currMonomDegree=getMonomDegree(monomGroup1);
00254                 if (currMonomDegree>MaxMonomDegree)
00255                         (MaxMonomDegree=currMonomDegree);
00256         }
00257         #ifdef DEBUG
00258         std::cerr << "getMaxMonomDegree : finished" << std::endl;
00259         #endif
00260         return MaxMonomDegree;
00261 }
00262 
00263 
00264 
00265 
00266 
00267 inline void eatWS(char* str,unsigned int & stelle)
00268 {
00269         while (isspace(str[stelle])&&(stelle<strlen(str))) 
00270         {
00271                 stelle++;
00272         }
00273 }
00274 
00275 
00276 inline std::string ltrim(const std::string &str)
00277 {
00278         std::string result="";
00279         size_t pos=0;
00280         for ( ; pos < str.length();pos++) 
00281         {
00282                 if (!isspace(str[pos]))
00283                         break;
00284         }
00285 
00286         for (; pos < str.length();pos++) 
00287         {
00288                 result=result+str[pos];
00289         }
00290         return result;
00291 }
00292 
00293 inline std::string rtrim(const std::string &str)
00294 {
00295         std::string result="";
00296         int pos=str.length()-1;
00297         for ( ; pos > 0 ; pos--) 
00298         {
00299                 if (!isspace(str[pos]))
00300                         break;
00301         }
00302 
00303         for (int pos2=0; pos2 <= pos ;pos2++) 
00304         {
00305                 result=result+str[pos2];
00306         }
00307         return result;
00308 }
00309 
00310 
00311 inline std::string trim(const std::string &str)
00312 {
00313         std::string res=ltrim(str);
00314         return rtrim(res);
00315 }
00316 
00317 inline std::string eatWS(const std::string &str)
00318 {
00319         std::string result="";
00320         for (size_t pos=0; pos < str.length();pos++) 
00321         {
00322                 if (!isspace(str[pos]))
00323                         result=result+str[pos];
00324         }
00325         return result;
00326 }
00327 
00328 //--------------------------Allgemeiner Parser Kram-----------------------------
00329 
00330 
00331 
00332 template <class _istream>
00333 char extractChar(char schar, _istream& sstream)
00334 {
00335         char a;
00336         sstream >> std::ws;
00337         //#ifdef DEBUG
00338                 std::string sschara;
00339                 sschara+=schar;
00340                 std::string sa;
00341                 
00342         //#endif
00343         
00344         if (sstream >> a)
00345         {
00346                 
00347                 #ifdef DEBUG
00348                         sa+=a;
00349                         std::cerr << "extract char: dest '" << sschara << "' ;real '" << sa << "'" << std::endl;
00350                 #endif
00351                 if ( a==schar)
00352                 {
00353                         return a;
00354                 }
00355                 else 
00356                 {
00357                         std::cerr <<"extract char: dest " << schar << " real "<< a << std::endl;
00358                 }
00359         }
00360         else 
00361         {
00362                 if (sstream.eof())
00363                         std::cerr << "sstream.eof" <<  std::endl;
00364                 std::cerr << "failed read '" << sschara << "' !!!" <<  std::endl;
00365         }
00366 
00367         #ifdef DEBUG
00368                 //std::cerr << "getChar " <<  std::endl;
00369                 //getchar();
00370         #endif
00371         std::string error=std::string("extract char ") + schar + std::string("failed");
00372         throw error;
00373 }
00374 
00375 template <class _istream>
00376 char extractChar(_istream& sstream,char schar)
00377 {
00378         return extractChar(schar,sstream);
00379 }
00380 
00381 
00382 template <class _istream>
00383 int getSign(_istream& sstream)
00384 {
00385         char a;
00386         sstream >> std::ws;
00387         if (!sstream.eof() )
00388         {
00389                 a=sstream.peek();
00390 
00391                 if (a=='-')
00392                 {
00393                         sstream >>a;
00394                         return -1;
00395                 }
00396                 if (a=='+')
00397                 {
00398                         sstream >>a;
00399                 }
00400         }
00401         return 1;
00402 }
00403 
00404 
00405 
00406 
00407 template <class _istream>
00408 std::string stripComment(_istream& data, bool & isComment)
00409 {
00410         char a;
00411         std::stringstream scomment;
00412         isComment=false;
00413 
00414         assert(! data.fail() );
00415         data >> std::ws;
00416         assert(! data.fail() );
00417 
00418         if ( !data.eof()  )
00419         {
00420                 data >> a;
00421                 assert(! data.fail() );
00422                 if ( data.eof() )
00423                 {
00424                         data.clear();
00425                         //cerr << "putback1 " << a << endl;
00426                         data.putback(a);
00427                         isComment=false;
00428                         assert(! data.fail() );
00429                 }
00430                 else
00431                 {
00432                         assert(! data.eof() );
00433                         char b = data.peek();
00434                         if ( data.eof() )
00435                         {
00436                                 data.clear();
00437                                 data.putback(a);
00438                                 isComment=false;
00439                         }
00440                         else
00441                         {
00442                         //      cerr << "peek b :" << b << endl;
00443                                 assert(! data.fail() );
00444                 
00445                                 if (a=='-' && !data.eof() && b=='-')
00446                                 {
00447                                         data >> a;
00448                                         isComment=true;
00449                                         assert(! data.fail() );
00450                                 }
00451                                 else
00452                                 {
00453                                         assert(! data.eof() );
00454                                         assert(! data.fail() );
00455                         //              cerr << "putback2 " << a << endl;
00456                                         data.putback(a);
00457                                         isComment=false;
00458                                         assert(! data.fail() );
00459                                 }
00460                         }
00461                 }
00462         }
00463         assert(! data.fail() );
00464         while (!data.eof() && isComment)
00465         {
00466                 data >> std::noskipws >> a;
00467         //      std::cerr <<  a;
00468                 if ( a=='\n' || a =='\r')
00469                 {
00470                         break;
00471                 }
00472                 scomment << a;
00473         //      cerr << "while scomment.str()" << scomment.str() << endl;
00474         }
00475         if ( data.fail() )
00476         {
00477                 std::cerr  << " Failed strip comment.";
00478                 throw "Failed strip comment.";
00479         }
00480         //cerr << "scomment.str()" << scomment.str() << endl;
00481         return scomment.str();
00482 }
00483 
00484 
00485 template <class _istream>
00486 void stripComments(_istream& data)
00487 {
00488         bool wasComment=true;
00489         while (wasComment)
00490         {
00491                 stripComment(data, wasComment);
00492         }
00493         return;
00494 }
00495 
00496 
00497 template <class _istream>
00498 std::string readCurrentComment(_istream& data)
00499 {       bool wasComment;
00500         return stripComment(data,wasComment);
00501 }
00502 
00503 
00504 template <class _istream>
00505 void seekToBraceLevel(_istream & inputData, int &currentLevel, int braceLevel)
00506 {
00507         char a;
00508         while (!inputData.eof() && currentLevel!=braceLevel)
00509         {
00510                 inputData >> a;
00511 
00512                 if (!inputData.eof() && a=='-'  && inputData.peek()=='-')
00513                 {
00514                         inputData.putback(a);
00515                         
00516                         readCurrentComment(inputData);
00517                 }
00518 
00519                 if (a=='{')     currentLevel++;
00520                 
00521                 if (a=='}')     currentLevel--;
00522 
00523                 if (a==';')     throw "seekToBraceLevel: Unexpected End of Value";
00524                 
00525                 if (a=='=')     throw "seekToBraceLevel: Unexpected Assignment";
00526 
00527                 if (currentLevel==braceLevel)
00528                         break;
00529         }
00530         if (currentLevel!=braceLevel)
00531                 throw "seekToBraceLevel:failed seek to brace level";
00532 }
00533 
00535 inline std::string extractNextData(std::stringstream &Data)
00536 {
00537         char a;
00538         std::stringstream result;
00539 
00540         int braceLevel=0;
00541 
00542         while (true )
00543         {
00544                 #ifdef DEBUG
00545                         std::cerr << "stripComments:  " <<  result.str() << std::endl;
00546                 #endif 
00547                 stripComments(Data);
00548                 #ifdef DEBUG
00549                         std::cerr << "stripComments finished" <<  result.str() << std::endl;
00550                 #endif 
00551 
00552                 if (Data.eof())
00553                         throw "Unexpected eof in data";
00554                 if (  Data.peek()=='}' )
00555                 {
00556                         if  (braceLevel==0)
00557                                 break;
00558                 }
00559                 if   ( Data.peek()==',' &&   braceLevel==0) 
00560                         break;
00561                 
00562                 Data   >> a;
00563                 result << a ;
00564                 if (a=='{')
00565                         braceLevel++;
00566                 if (a=='}')
00567                         braceLevel--;
00568                 
00569                 #ifdef DEBUG
00570                         std::cerr << "extractNextData: data.str()" <<  result.str() << std::endl;
00571                 #endif 
00572         }
00573         #ifdef DEBUG
00574                         std::cerr << "extractNextData finished!" <<  result.str() << std::endl;
00575                 #endif 
00576         return result.str();
00577 }
00578 
00579 
00580 
00581 
00582 inline std::string      extractNextBracedData(std::stringstream &Data)
00583 {
00584         char a;
00585         std::stringstream result;
00586 
00587         extractChar('{',Data);
00588         int braceLevel=1;
00589 
00590         result << '{';
00591         
00592         while (true )
00593         {
00594                 stripComments(Data);
00595                 if (Data.eof())
00596                         throw "Unexpected eof in curly braced data";
00597                 Data   >> a;
00598                 result << a ;
00599 
00600                 if (a=='}' && --braceLevel==0)
00601                         break;
00602 
00603                 if (a=='{')
00604                         braceLevel++;
00605         }
00606         return result.str();
00607 }
00608 
00609 
00610 
00611 
00622 template <class _istream>
00623 std::string     readParamName(_istream & inputData)
00624 {
00625         char a;
00626 
00627         std::stringstream parameterName;
00628         bool beginCommentPossible=false;
00629         bool containsWSPossible=false;
00630 
00631         while (!inputData.eof() && !inputData.fail() )
00632         {
00633                 a=inputData.peek();
00634                 if (a=='\n')
00635                 {
00636                         std::cerr << "ReadParamName: unexpected end of ParamName";
00637                         throw "ReadParamName: line break not allowed in parameter names";
00638                 }
00639                 if (a=='=')
00640                 {
00641                         break;
00642                 }
00643                 if (a==';')
00644                 {
00645                         std::cerr << "ReadParamName: unexpected End of ParamName";
00646                         throw "ReadParamName: unexpected End of ParamName";
00647                 }
00648 
00649                 if (isspace(a))
00650                 {
00651                         inputData >> std::ws;
00652                         if ( parameterName.str().length()>0)
00653                         {
00654                                 containsWSPossible=true;
00655                         }
00656                         continue;
00657                 }
00658                 if (a=='-')
00659                 {
00660                         if (!beginCommentPossible)
00661                                 beginCommentPossible=true;
00662                         else
00663                         {
00664                                 std::cerr << "ReadParamName: unexpected begin of a comment";
00665                                 throw "ReadParamName: unexpected begin of a comment";
00666                         }
00667                 }
00668                 else
00669                 {
00670                         beginCommentPossible=false;
00671                 }
00672         
00673                 if (containsWSPossible)
00674                 {
00675                         std::cerr << "ReadParamName: Parameter name contains white spaces";
00676                         throw "ReadParamName: Parameter name contains white spaces";
00677                 }
00678                 containsWSPossible = false;
00679                 inputData >> std::noskipws >> a;
00680                 parameterName << a;
00681                         
00682         }
00683         if (inputData.eof() || inputData.fail() )
00684         {
00685                 std::cerr << "ReadParamName: unexpected end of data";
00686                 throw "ReadParamName: unexpected end of data";
00687         }
00688         return parameterName.str();
00689 }
00690 
00692 template <class _istream>
00693 std::string readStringValue(_istream & inputData, std::string paramName)
00694 {
00695         std::stringstream       parameterValue;
00696         char a;
00697         
00698         a=inputData.peek();
00699         assert (a=='\"');
00700         
00701         inputData >> a;
00702         
00703         parameterValue  <<  a;
00704 
00705         while (!inputData.eof() && !inputData.fail() )
00706         {
00707                 a=inputData.peek();
00708                 if (a=='\"')
00709                 {
00710                         inputData >> a;
00711                         parameterValue  <<  a;
00712                         return parameterValue.str();
00713                 }
00714                 inputData >> std::noskipws >> a;
00715                 parameterValue  <<  a;
00716         }
00717         throw "readStringValue: unexpected end of data";
00718 }
00719 
00730 template <class _istream>
00731 std::string readParamValue(_istream & inputData, std::string paramName)
00732 {
00733         char a;
00734 
00735         std::stringstream       parameterValue;
00736         bool                    beginCommentPossible = false;
00737 
00738         std::string wsCache="";
00739         
00740         inputData >> std::ws;
00741 //      cerr << "readParamValue of " << paramName << endl;
00742         while (!inputData.eof() && !inputData.fail() )
00743         {
00744 
00745                 //cerr << "parameterValue.str() " <<  parameterValue.str() << endl;
00746                 a=inputData.peek();
00747                 if (a=='\"')
00748                 {
00749                         return readStringValue( inputData, paramName);
00750                 }
00751                 if (a=='\n')
00752                 {
00753                         beginCommentPossible=false;
00754                         inputData >> std::noskipws >> a;
00755                         if (isspace(a))
00756                         {
00757                                 wsCache+= a;
00758                         }
00759                         else
00760                         {
00761                                 parameterValue  << wsCache; wsCache="";
00762                                 parameterValue  <<  a;
00763                         }
00764                         continue;
00765                 }
00766                 if (a=='=')
00767                 {
00768                         std::string rest;
00769                         inputData >> rest;
00770                         //cerr << "current: " << parameterValue.str() ;
00771                         
00772                 //      cerr << "rest: " << rest ;
00773                         throw "ReadParamValue: unexpected assignment in parameter value";
00774                 }
00775                 if (a==';')
00776                         break;
00777                 if (a=='-')
00778                 {
00779                                 bool wasComment=false;
00780                                 stripComment(inputData,wasComment);
00781                                 if (wasComment)
00782                                         continue;
00783                 }
00784                 inputData >> std::noskipws >> a;
00785                 if (isspace(a))
00786                 {
00787                         wsCache+= a;
00788                 }
00789                 else
00790                 {
00791                         parameterValue  << wsCache; wsCache="";
00792                         parameterValue  <<  a;
00793                 }
00794 //              std::cerr << "parameterValue" << parameterValue.str() << endl;
00795         }
00796         if (inputData.eof() || inputData.fail() )
00797                 throw "readParamValue: unexpected end of data";
00798         return parameterValue.str();
00799 }
00800 
00801 
00802 
00803 inline int countSubGroups(std::stringstream &polynomStream)
00804 {
00805         std::string strCopy = polynomStream.str();
00806 
00807         int braceLevel=0;
00808         int subGroupCount=0;
00809 
00810         for (size_t strPos=0;strPos<strCopy.length();strPos++)
00811         {
00812                 if (strCopy[strPos]=='{')
00813                 {
00814                         if (braceLevel==1)
00815                                 subGroupCount++;
00816                         braceLevel++;
00817                         
00818                 }
00819                 if (strCopy[strPos]=='}')
00820                 {
00821                         braceLevel--;
00822                         
00823                 }
00824                 if (braceLevel<0)
00825                         throw "countSubGroups: too much closing braces!";
00826         }
00827         if (braceLevel!=0)
00828                         throw "countSubGroups: Error in curly brace nesting";
00829         return subGroupCount;
00830 }
00831 
00832 
00833 inline int countGroups(std::stringstream &polynomStream)
00834 {
00835         std::string strCopy = polynomStream.str();
00836 
00837         int braceLevel=0;
00838         int groupCount=0;
00839 
00840         for (size_t strPos=0; strPos<strCopy.length(); strPos++)
00841         {
00842                 if (strCopy[strPos]=='{')
00843                 {
00844                         if (braceLevel==0)
00845                                 groupCount++;
00846                         braceLevel++;
00847                         
00848                 }
00849                 if (strCopy[strPos]=='}')
00850                 {
00851                         braceLevel--;
00852                         
00853                 }
00854                 if (braceLevel<0)
00855                         throw "countSubGroups: too much closing braces!";
00856         }
00857         if (braceLevel!=0)
00858                         throw "groupCount: Error in curly brace nesting";
00859         return groupCount;
00860 }
00861 
00862 
00863 inline int countElements(std::stringstream &str)
00864 {
00865         std::string strCopy = str.str();
00866 
00867         int braceLevel=0;
00868         int elementCount=0;
00869 
00870         for (size_t strPos=0;strPos<strCopy.length();strPos++)
00871         {
00872                 if (strCopy[strPos]=='{')
00873                 {
00874                         braceLevel++;
00875                 }
00876                 if (strCopy[strPos]==',')
00877                 {
00878                         if (braceLevel==1)
00879                                 elementCount++;
00880                 }
00881                 if (strCopy[strPos]=='}')
00882                 {
00883                         if (braceLevel==1)
00884                                 elementCount++;
00885                         braceLevel--;
00886                 }
00887                 if (braceLevel<0)
00888                         throw "countSubGroups: too much closing braces!";
00889         }
00890         if (braceLevel!=0)
00891                         throw "countElements: Error in curly brace nesting";
00892         return elementCount;
00893 }
00894 
00895 
00896 
00897 
Generated on Tue Nov 23 13:10:52 2010 for centerfocus by  doxygen 1.6.3