GSP.cpp
gehe zur Dokumentation dieser Datei
00001 
00023 // ##################################################################
00024 // main file of gsp (GMN Soft Parser)
00025 // ##################################################################
00026 
00027 #include "GSP.h"
00028 #include "GSP_File.h"
00029 #ifdef WX
00030 #include "wx/wxchar.h"
00031 #else
00032 #include <string.h>
00033 #endif
00034 
00035 // global data
00036 
00037 int GspCurrentLineNr;    // curent line parser deals with
00038 int GspErrorLineNr;      // line of occured error
00039 int GspErrorPos;         // column of occured error in line
00040 mutString GspErrorLine;      // text of error line
00041 int GspError;            // error id
00042 
00043 // last saved position (before an error occurs)
00044 int PossibleErrorLineNr;
00045 int PossibleErrorPos;
00046 mutString PossibleErrorLine; //[GSP_MAX_LINE];
00047 
00048 #ifdef WX
00049 mutString Sep = mutEmptyString;
00050 inline size_t SepPos()
00051 {
00052         size_t a =  (Sep.Len());
00053         return a;
00054 }
00055 
00056 #define SepPos SepPos()
00057 #else
00058 char Sep[GSP_MAX_SEP];
00059 int  SepPos;
00060 #endif
00061 
00062 // local data
00063 char ParaMode;
00064 char Komma;
00065 int  NumberLength;
00066 #ifdef WX
00067 mutString Brackets = mutEmptyString;
00068 #define BracketDeep \
00069   (Brackets.Len())
00070 #else
00071 int  BracketDeep;
00072 char Brackets[200];
00073 #endif
00074 char LastTag;
00075 // last note
00076 
00077 static int octave;
00078 
00079 static mutString accedentials /*[GSP_MAX_LINE]*/;
00080 
00081 static frac duration;
00082 
00083 #define NEW_LINE mutT("\n")
00084 mutChar SepChars[] = mutT(" \t\r\n");
00085 
00086 mutChar DelimitChars[] = mutT("{}[]()");
00087 
00088 #define uchar unsigned char
00089 
00090 // ##################################################################
00091 // Work with strings
00092 
00093 #ifdef WX
00094 inline void AddStr(mutString & Target, int Pos, const mutString& Source)
00095 {
00096         DEBUGLOG2(other,_T("%s + %s"), Target.c_str(), Source.c_str());
00097         Target += Source;
00098         DEBUGLOG2(other,_T("=%s"), Target.c_str());
00099 }
00100 
00101 inline int CharIn(mutChar c, const mutChar * s)
00102 
00103 {
00104         DEBUGLOG2(other,_T("'%c' is in '%s' at position %d, returning %d"),
00105                   c, s, mutStrChr(s, c), mutStrChr(s, c) != NULL);
00106         return mutStrChr(s, c) != NULL;
00107 }
00108 
00109 inline int IsLetter(mutChar c)
00110 
00111 {
00112         return ((mutT('a') <= c) && (c <= mutT('z'))) ||
00113                ((mutT('A') <= c) && (c <= mutT('Z'))) ||
00114                ( c == mutT('_') );
00115 }
00116 
00117 /*
00118 inline int IsNumber(mutChar c)
00119 {
00120   return (mutIsDigit(c));
00121 }
00122 */
00123 #else
00124 void AddStr(char *Target, int &Pos, char *Source)
00125 {
00126         for (int i = 0; Source[i]; i++) {
00127                 Target[Pos++] = Source[i];
00128         }
00129 
00130         Target[Pos] = 0;
00131 }
00132 
00133 int CharIn(mutChar c, const mutString s)
00134 {
00135         return mutStrChr(s, c) != 0;
00136 }
00137 
00138 int IsLetter(mutChar c)
00139 
00140 {
00141         return ((mutT('a') <= c) && (c <= mutT('z'))) ||
00142                ((mutT('A') <= c) && (c <= mutT('Z'))) ||
00143                ( c == mutT('_') );
00144 }
00145 
00146 int IsNumber(mutChar c)
00147 {
00148         return (mutT('0') <= c) && (c <= mutT('9'));
00149 }
00150 
00151 #endif
00152 // ##################################################################
00153 // dealing with errors
00154 
00155 // produces an error at CurrentPos
00156 int DoError(int nr, int pos = -1)
00157 {
00158         if ( GspError ) return GspError;
00159 
00160         GspError = nr;
00161 
00162         GspErrorLineNr = GspCurrentLineNr;
00163 
00164         if ( pos == -1 )
00165                 GspErrorPos = CurrentPos;
00166         else
00167                 GspErrorPos = pos;
00168 
00169         GspErrorLine = CurrentLine;
00170 
00171         return nr;
00172 }
00173 
00174 // produces an error at the last saved position
00175 int CheckError(int nr)
00176 {
00177         if ( !nr ) return 0; // no error
00178 
00179         if ( GspError ) return GspError;
00180 
00181         GspError = nr;
00182 
00183         GspErrorLineNr = PossibleErrorLineNr;
00184 
00185         GspErrorPos = PossibleErrorPos;
00186 
00187         GspErrorLine = PossibleErrorLine;
00188 
00189         return nr;
00190 }
00191 
00192 // save current position (for CheckError)
00193 void SavePos()
00194 {
00195         PossibleErrorLineNr = GspCurrentLineNr;
00196         PossibleErrorPos = CurrentPos;
00197         mutCopyIntoString(PossibleErrorLine, CurrentLine);
00198 }
00199 
00200 // ##################################################################
00201 // reading separator chars
00202 
00203 #define CHAR0 CurrentLine[CurrentPos]
00204 #define CHAR1 CurrentLine[CurrentPos+1]
00205 inline wxString & takesep()
00206 {
00207         Sep += CurrentLine[CurrentPos++];
00208         DEBUGLOG2(other,_T("New Sep: %s"), Sep.c_str());
00209         return Sep;
00210 }
00211 
00212 #define TAKESEP takesep()
00213 
00214 
00215 // reading separator string
00216 int GetSep()
00217 {
00218 #ifdef WX
00219         Sep = mutEmptyString;
00220 #else
00221         SepPos = 0;
00222 #endif
00223         Komma = 0;
00224         int RemDeep = 0;
00225         int RemLine = 0;
00226 
00227         while ( !Eof && !GspError ) {
00228 #ifdef WX
00229                 DEBUGLOG2(other,_T("%d >= %d? Sep.Len=%d"),CurrentPos,CurrentLine.Len(),Sep.Len());
00230                 DEBUGLOG2(other,_T("%s"),CurrentLine.c_str());
00231 
00232                 if (CurrentPos >= CurrentLine.Len())
00233 #else
00234                 mutChar c = CHAR0;
00235 
00236                 if ( !c ) // new Line
00237 #endif
00238                 {
00239 
00240                         if ( ReadNewLine() )
00241                         {
00242                                 DoError(32);
00243 #ifdef WX
00244                                 Sep = Sep.Left(1);
00245                                 DEBUGLOG2(other,_T("Returning 1 at with (%d) '%s'"),
00246                                           SepPos, Sep.c_str());
00247                                 return SepPos;
00248 #else
00249                                 return ( SepPos = 1 );
00250 #endif
00251                         }
00252 
00253                         RemLine = 0;
00254 
00255                         if ( GspCurrentLineNr != 1 )
00256                                 AddStr(Sep, SepPos, NEW_LINE);
00257 
00258                         continue;
00259                 }
00260 
00261 #ifdef WX
00262                 mutChar c = CHAR0;
00263 
00264 #endif
00265 
00266                 if ( c == mutT('(') && CHAR1 == mutT('*') )  // comment start
00267                 {
00268                         TAKESEP;
00269                         TAKESEP;
00270                         RemDeep++;
00271                         continue;
00272                 }
00273 
00274                 if ( RemDeep ) // during a comment
00275                 {
00276 
00277                         if ( c == mutT('*') && CHAR1 == mutT(')') )
00278                         {
00279                                 TAKESEP;
00280                                 TAKESEP;
00281                                 RemDeep--;
00282                         } else
00283                                 TAKESEP;
00284 
00285                         continue;
00286                 }
00287 
00288                 if ( RemLine ) {
00289                         TAKESEP;
00290                         continue;
00291                 }
00292 
00293                 if ( c == mutT('%') ) // line comment
00294                 {
00295                         RemLine = 1;
00296                         continue;
00297                 }
00298 
00299                 if ( CharIn(c, SepChars) ) // separating chars
00300                 {
00301                         TAKESEP;
00302                         continue;
00303                 }
00304 
00305                 if ( c == mutT(',') && ParaMode ) // sequenz separator
00306                 {
00307                         TAKESEP;
00308                         Komma = 1;
00309                         continue;
00310                 }
00311 
00312                 break;
00313         }
00314 
00315         DEBUGLOG2(other,_T("Returning with (%d) '%s'"),SepPos,Sep.c_str());
00316 
00317 #ifndef WX
00318         Sep[SepPos] = 0;
00319 #endif
00320         return SepPos;
00321 }
00322 
00323 // ##################################################################
00324 // subfunctions of parsing process
00325 
00326 bool minus;
00327 
00328 // reads an integer
00329 long ReadLong(int SignAllowed)
00330 {
00331         long a = 0;
00332         NumberLength = 0;
00333         minus = false;
00334 
00335         if ( SignAllowed ) {
00336                 DEBUGLOG2(other,_T("Sign char %c?"), CHAR0);
00337 
00338                 if ( CHAR0 == mutT('+') ) CurrentPos++;
00339                 else if ( CHAR0 == mutT('-') ) {
00340                         CurrentPos++;
00341                         minus = true;
00342                 }
00343         }
00344 
00345         GetSep();
00346 
00347         while ( mutIsdigit(CHAR0) && !SepPos ) {
00348                 DEBUGLOG2(other,_T("Number char %c? (a=%d)"), CHAR0, a);
00349                 a = a*10 + (CurrentLine[CurrentPos++]-mutT('0'));
00350                 NumberLength++;
00351                 GetSep();
00352         }
00353 
00354         if ( minus ) return -a;
00355 
00356         return a;
00357 }
00358 
00359 // reads a number parameter (int or real)
00360 int ReadParaNumber()
00361 {
00362         long a = ReadLong(1);
00363 
00364         if ( SepPos || CHAR0 != mutT('.') ) // integer
00365                 return CheckError(TagParaInt(a));
00366 
00367         // real
00368         CurrentPos++; // comma position
00369 
00370         GetSep();
00371 
00372         mutChar minus1 = minus;
00373 
00374         double r = (double)a;
00375 
00376         if ( SepPos ) // real without fraction part
00377                 return CheckError(TagParaReal(r));
00378 
00379         float b = (double) ReadLong(0);
00380 
00381         for (int i = 1; i <= NumberLength; i++)
00382                 b = b / 10;
00383 
00384         if ( minus1 ) b = -b;
00385 
00386         return CheckError(TagParaReal(r+b));
00387 }
00388 
00389 // reads a parameter string
00390 int ReadParaStr()
00391 {
00392 #ifdef WX
00393         mutString s /*[GSP_MAX_LINE]*/ = mutT("");
00394 #else
00395         mutChar s[GSP_MAX_LINE] = "";
00396 #endif
00397         int i = 0;
00398         CurrentPos++;
00399 
00400         while ( (CHAR0 != mutT('"') || CHAR1 == mutT('"')) && !Eof ) {
00401                 if ( !CHAR0 ) // new Line
00402                 {
00403                         ReadNewLine();
00404                         AddStr(s, i, NEW_LINE);
00405                         continue;
00406                 }
00407                 if ( CHAR0 == mutT('"') ) CurrentPos++;
00408 
00409 #ifdef WX
00410                 s += CurrentLine[CurrentPos++];
00411 
00412 #else
00413                 s[i++] = CurrentLine[CurrentPos++];
00414 
00415 #endif
00416         }
00417 
00418         if ( CHAR0 == mutT('"') ) CurrentPos++;
00419 
00420 #ifndef WX
00421         s[i] = 0;
00422 
00423 #endif
00424         GetSep();
00425 
00426         return CheckError(TagParaStr(s));
00427 }
00428 
00429 // reads a tag
00430 int ReadTag()
00431 {
00432         mutString Name/* [GSP_MAX_LINE] */ = mutT("");
00433         mutChar i = 0;
00434         LastTag = 2; // to have an indicator, wether the last token was a tag
00435         CurrentPos++;
00436         GetSep();
00437 #ifdef WX
00438         i = CurrentPos;
00439 #endif
00440 
00441         while ( IsLetter(CHAR0) && !SepPos ) {
00442 #ifdef WX
00443                 CurrentPos++;
00444 #else
00445                 Name[i++] = CurrentLine[CurrentPos++];
00446 #endif
00447                 GetSep();
00448         }
00449 
00450 #ifdef WX
00451         Name = CurrentLine (i,CurrentPos-i);
00452 
00453 #else
00454         Name[i] = 0;
00455 
00456 #endif
00457         if ( !GspError ) CheckError(Tag(Name));
00458 
00459         if ( CHAR0 == mutT('<') ) {
00460                 CurrentPos++;
00461                 GetSep();
00462 
00463                 if ( !GspError ) CheckError(BeginParameter());
00464 
00465                 ParaMode = 1;
00466         }
00467 
00468         if ( CHAR0 == mutT('>') ) {
00469                 CurrentPos++;
00470                 GetSep();
00471 
00472                 if ( !GspError ) CheckError(EndParameter());
00473 
00474                 ParaMode = 0;
00475         }
00476 
00477         return GspError;
00478 }
00479 
00480 // reads a note
00481 int ReadNote()
00482 {
00483         mutChar i = 0;
00484 #ifdef WX
00485         mutString Name /* [GSP_MAX_LINE]*/ = wxEmptyString;
00486         accedentials = wxEmptyString;
00487 #else
00488         mutChar Name[GSP_MAX_LINE] = mutT("");
00489         accedentials[0] = 0;
00490 #endif
00491 
00492         GetSep();
00493 
00494 #ifdef WX
00495 
00496         for (i = CurrentPos; IsLetter(CHAR0) && !SepPos; CurrentPos++)
00497                 GetSep();
00498 
00499         Name = CurrentLine(i,CurrentPos-i);
00500 
00501         GetSep();
00502 
00503 #else
00504         while ( IsLetter(CHAR0) && !SepPos ) {
00505                 Name[i++] = CurrentLine[CurrentPos++];
00506                 GetSep();
00507                 mutString Name /* [GSP_MAX_LINE]*/ = mutT("");
00508 
00509         }
00510 
00511         Name[i] = 0;
00512 
00513 #endif
00514 
00515         DEBUGLOG2(other,_T("SepPos: %d"),SepPos);
00516 
00517         if ( SepPos )
00518                 return CheckError(Note(Name, accedentials, octave, duration));
00519 
00520         i = 0; // accedentials
00521 
00522         while ( CharIn(CHAR0, mutT("#&")) && !SepPos ) {
00523 #ifdef WX
00524                 accedentials += CurrentLine[CurrentPos++];
00525 #else
00526                 accedentials[i++] = CurrentLine[CurrentPos++];
00527 #endif
00528                 GetSep();
00529         }
00530 
00531 #ifndef WX
00532         accedentials[i] = 0;
00533 
00534 #endif
00535 
00536         DEBUGLOG2(other,_T("SepPos: %d"),SepPos);
00537 
00538         if ( SepPos )
00539                 return CheckError(Note(Name, accedentials, octave, duration));
00540 
00541         int cp = CurrentPos; // octave
00542 
00543         int oct = ReadLong(1);
00544 
00545         if ( cp != CurrentPos ) octave = oct;
00546 
00547         if ( SepPos || !CharIn(CHAR0, mutT("/*.")) )
00548                 return CheckError(Note(Name, accedentials, octave, duration));
00549 
00550         int DurOk = 0; // duration
00551 
00552         duration = frac(1,1);
00553 
00554         if ( CHAR0 == mutT('*') ) {
00555                 DurOk = 1;
00556                 CurrentPos++;
00557                 duration = frac(ReadLong(0));
00558 
00559                 if ( !duration )
00560                         return DoError(21); // error: nominator expected
00561         }
00562 
00563         if ( SepPos || !CharIn(CHAR0, mutT("/.")) )
00564                 return CheckError(Note(Name, accedentials, octave, duration));
00565 
00566         if ( CHAR0 == mutT('/') ) {
00567                 DurOk = 1;
00568                 CurrentPos++;
00569                 duration /= ReadLong(0);
00570 
00571                 if ( !duration )
00572                         return DoError(22); // error: denominator expected
00573         }
00574 
00575         if ( SepPos )
00576                 return CheckError(Note(Name, accedentials, octave, duration));
00577 
00578         if ( CHAR0 == mutT('.') && !DurOk )
00579                 return DoError(23); // error: dotting wihtout duration
00580 
00581         frac add = duration;
00582 
00583         while ( CHAR0 == mutT('.') && !SepPos ) {
00584                 add *= frac(1,2);
00585 
00586                 duration += add;
00587 
00588                 CurrentPos++;
00589 
00590                 GetSep();
00591         }
00592 
00593         return CheckError(Note(Name, accedentials, octave, duration));
00594 }
00595 
00596 // ##################################################################
00597 // parsing process
00598 
00599 // the parsing loop
00600 int DoParse()
00601 {
00602         ParaMode = 0;
00603 
00604         while ( !Eof ) {
00605                 mutChar c = CHAR0;
00606                 SavePos();
00607                 Komma = 0;
00608 
00609                 if ( ParaMode ) {
00610                         if ( mutIsdigit(c) || ( c == mutT('+')) || ( c == mutT('-')) ) // number parameter
00611                         {
00612 
00613                                 if ( ReadParaNumber() ) return GspError;
00614                         } else if ( c == mutT('"') ) // string parameter
00615                         {
00616 
00617                                 if ( ReadParaStr() ) return GspError;
00618                         } else // wrong parameter
00619                         {
00620                                 return DoError(10);
00621                         }
00622 
00623                         if ( CHAR0 == mutT('>') ) // end of parameterlist
00624                         {
00625                                 CurrentPos++;
00626                                 GetSep();
00627 
00628                                 if ( CheckError(EndParameter()) ) return GspError;
00629 
00630                                 ParaMode = 0;
00631 
00632                                 continue;
00633                         }
00634                         if ( !Komma ) // , or > expected
00635                         {
00636                                 return DoError(11);
00637                         }
00638                 } else // not ParaMode
00639                 {
00640                         if ( LastTag ) LastTag --;
00641 
00642                         if ( CharIn(c, DelimitChars) ) {
00643                                 mutChar i = 0;
00644 
00645                                 while ( DelimitChars[i] != c ) i++;
00646 
00647                                 if ( i & 1 ) // closing bracket
00648                                 {
00649 
00650                                         if ( !BracketDeep )
00651                                                 return DoError(1);
00652 
00653 #ifdef WX
00654                                         DEBUGLOGBASE (other,_T(""),
00655                                                       _T("brackets: %s, i= %d, last = %d"),
00656                                                       Brackets.c_str(),
00657                                                       i,
00658                                                       Brackets[Brackets.Len()-1]);
00659 
00660                                         if ( Brackets[Brackets.Len()-1] != i-1 )
00661                                                 return DoError(2 + (int) Brackets[BracketDeep-1]/2);
00662 
00663                                         Brackets = Brackets.Left(Brackets.Len()-1);
00664 
00665 #else
00666                                         if ( Brackets[--BracketDeep] != i-1 )
00667                                                 return DoError(2 + Brackets[BracketDeep]/2);
00668 
00669 #endif
00670                                 } else // opening bracket
00671 #ifdef WX
00672                                         Brackets += i;
00673 
00674 #else
00675                                         Brackets[BracketDeep++] = i;
00676 
00677 #endif
00678 #ifdef GMN_STRICT
00679                                 if ( !LastTag && c == mutT('(') ) return DoError(41); // error: range without tag
00680 
00681 #endif
00682                                 CurrentPos++;
00683 
00684                                 GetSep();
00685 
00686                                 switch ( c ) {
00687                                 case mutT('{'): if ( CheckError(BeginSegment()) ) return GspError;
00688 
00689                                         break;
00690 
00691                                 case mutT('}'): if ( CheckError(EndSegment()) ) return GspError;
00692 
00693                                         break;
00694 
00695                                 case mutT('['): if ( CheckError(BeginSequenz()) ) return GspError;
00696 
00697                                         break;
00698 
00699                                 case mutT(']'): if ( CheckError(EndSequenz()) ) return GspError;
00700 
00701                                         break;
00702 
00703                                 case mutT('('): if ( CheckError(BeginRange()) ) return GspError;
00704 
00705                                         break;
00706 
00707                                 case mutT(')'): if ( CheckError(EndRange()) ) return GspError;
00708 
00709                                         break;
00710                                 }
00711 
00712                                 /*                if ( Komma )
00713                                                          if ( CheckError(NextSequenz()) ) return GspError; */
00714                                 continue;
00715                         }
00716 
00717                         if ( c == mutT('\\') ) {
00718                                 if ( ReadTag() ) return GspError;
00719 
00720                                 /*                if ( !ParaMode && Komma )
00721                                                          if ( CheckError(NextSequenz()) ) return GspError; */
00722                                 continue;
00723                         }
00724 
00725                         if ( c == mutT('|') ) {
00726                                 CurrentPos++;
00727                                 GetSep();
00728 #ifdef NO_SHORT_BAR
00729 
00730                                 if ( CheckError(Tag(mutT("bar"))) ) return GspError;
00731 
00732 #else
00733                                 if ( CheckError(Tag(mutT("|"))) ) return GspError;
00734 
00735 #endif
00736                                 /*                if ( Komma )
00737                                                          if ( CheckError(NextSequenz()) ) return GspError; */
00738                                 continue;
00739                         }
00740 
00741                         if ( c == mutT(',') ) {
00742                                 if ( Brackets[BracketDeep-1] != 0 )
00743                                         return DoError(24); // unexpected comma
00744 
00745                                 CurrentPos++;
00746 
00747                                 GetSep();
00748 
00749                                 if ( CheckError(Comma()) ) return GspError;
00750 
00751                                 continue;
00752                         }
00753 
00754                         if ( IsLetter(c) ) {
00755                                 if ( ReadNote() ) return GspError;
00756 
00757                                 if ( Komma )
00758                                         if ( CheckError(NextSequenz()) ) return GspError;
00759 
00760                                 continue;
00761                         }
00762 
00763                         // unallowed char
00764                         return DoError(20);
00765                 }
00766         }
00767 
00768         return 0;
00769 }
00770 
00771 // ##################################################################
00772 // main procedure
00773 
00774 int GspParse(const mutString &FileName)
00775 {
00776         GspCurrentLineNr = 0;
00777         CurrentPos = 0;
00778         CurrentLine = _T("");
00779 
00780         GspErrorLineNr = 0;
00781         GspErrorPos = 0;
00782         GspErrorLine = mutEmptyString;
00783         GspError = 0;
00784 
00785         Eof = 0;
00786 #ifdef WX
00787         Brackets = mutEmptyString;
00788 #else
00789         BracketDeep = 0;
00790 #endif
00791         LastTag = 0;
00792 
00793         octave = 1;
00794         duration = frac(1,4);
00795 
00796         if ( OpenFile(FileName) )
00797                 return DoError(30); // couldn't open file
00798 
00799         GetSep();
00800 
00801         if ( CheckError(StartSep()) )
00802                 return GspError;
00803 
00804 #ifdef GMN_STRICT
00805         if ( !Eof && CHAR0 != '[' && CHAR0 != '{' )
00806                 DoError(40);
00807 
00808 #endif
00809         if ( !GspError) DoParse();
00810 
00811         if ( CloseFile() )
00812                 return DoError(31); // couldn't close file
00813 
00814         return GspError;
00815 };
00816 

Erzeugt am Sun Aug 21 2011 10:51:53 für Mutabor von doxygen 1.7.4