/***** * * Michael Riff * RPN software version 1.0 Oktob 2013. * * Diese Datei enthält die Funktionnen die das Durchlesen der Eingabe erfüllen : * Eine Prozedur zu Modul Initialisierung, * Eine beendubgprozedur die allokierten Speicher freigibt, * Eine Prozedur die die arithmetischen Sätze durchliest. Bei den { der Kontroll Strukturen * (if while for Strukturen) wird sie rekursiv aufgerufen. * Eine Prozedur um Bool Sätze durchzulesen (Kondition bei if while) * * Version 1.1: 07 Jan 2014 * parsen & parseBool: in default case for switch on binary operator, set mode to others (was missing) * * Version 1.3: 08 Feb 2014 * Identification of floating point values in text use decimal separator from UX_StdLib.c if USE_ITL is defined. * * Version 1.4: Jun 2014 * Error correction: when handling the unary + operator in parson & parseBool. No operator must be * taken off the stack (in fact nothing has to be done). * Note : Parsen has two varibale named aktOp (one local to whole rouotine and one to operator + - * / ^) * * Version 1.6: with compiler switch EXT_FOR 2 Sept 2014 * Full arithmetic and boolean expressions in for(;;). The last arithmetic expression * is now always put at the end of the loop. * * Version 1.7: 06 June 2016 * Implemented handling of additional routines that can be called out of the text code. As example * we used the following: print() and print("constant string") that print out * the value of a variable or a string. * Adaptations to compile the code with CodeWarrior and suppress warnings. * * Version 1.8: 23 July .2016 * Added compiler switch to prevent warning about unused variables. * parsen : for case of variable, use of macro to suppress blancs. * parseBool : set mode before continue instruction in case of value assignment to a variable. * String buffer Funktion & toConvert with counters put global instead of local in several routines. * parserBool : moved reset of counter for Funktion before using it, and corrected missig identification case * for ^ operator. * *****/ #ifdef DEBUG //#include //long Stack; int dbgidx; #endif #ifndef MAC_UI #include #include #include #else #ifdef USE_ITL extern char decSeparat; #endif #endif #include "Parser.h" #ifdef Mac #include "Calculs.h" // extern double (**Fonction)(void); extern Commande *Fonction; extern unsigned long nbFonctions; extern unsigned long maxFonctions; extern double *Pile; extern unsigned long maxArg; #ifdef MIT_VAR extern variables *Valeurs; extern long maxConst; extern unsigned short nbVar; #endif #ifdef ARG_DOUBLE extern double *constValues; extern unsigned int cntValues; #endif //extern unsigned int tailleDouble; extern unsigned int tailleFlottant; //extern unsigned int tailleuLong; extern unsigned int tailleEntier; extern Grph_struct *Graphs; extern int numGraphs; extern int aktGraphik; #ifdef ADD_FUNCT extern char **Msges; extern int numMsges; extern int maxMsges; #endif #else #include "Calculs.c" #endif /* Datei die Ausgelesen wird */ FILE *Datei; int currLine = 0; char dumy; #ifdef MIT_WHILE extern int whileEinsch; /* Anzahl der eingeschachtelten Strukturen */ #endif /* Alle Indexe in den Tabellen zeigen auf den ersten leeren Platz Letzter Eintrag an index - 1. */ char *Eingang; int indexEin; #ifdef DEBUG char *Ausgang; int indexAus; #endif /* Definierung der Priorität der Funktionnen/Operatoren. */ int Precedences[27] = {20,20,0,1,1,2,2,3,3,1,10,11,1,1,1,1,1,1,1,1,1,1,4,4,4,4,4}; /* Prioritaet der Bool Operatoren */ int BoolPrec[12] = {13,14,14,10,11,11,11,11,12,12,10,15}; /* Puffer zur Umschreibung zur Polnische Notation */ Pfr_Str *Puffer; int indexPuffer; /* Anzahl der eingeschachtelte Klammern. */ int Klammern = 0; /* Aus Eingang ausgelsener Charakter in Bearbeitung. */ char akt; /* Hilfsvariablen */ double operand; int aktPrio; /*double *tiers;*/ /* Funktion die aufgerufen wird bevor sie definiert ist */ #ifndef EXT_FOR void parseBool(void); #else #ifdef Mac void parseBool(Boolean stopOnSmiCol); #else void parseBool(bool stopOnSmiCol); #endif #endif // Eventuell auch die \t Zeichen überspringen #define SUPP_BLANC while (akt==' ' || akt=='\n' || akt=='\r' || akt=='\t') {\ if (akt=='\n' || akt=='\r') currLine++; \ akt = Eingang[indexEin++];\ } #ifdef EXT_FOR /* When reading in a for loop, we have to store the start and end position of the arithmetic expression of the for command that has to be put at the end of the loop. */ int forStack[10][2]; int numFor; #endif /* Initialisierung fuer dass Parsen ==========================*/ int InitParse(void) { Eingang = malloc(1400); if (NULL == Eingang) { printf("Allocation buffer buffer entrée échouée\n"); return 1; } Eingang[0] = '\0'; indexEin = 0; #ifdef DEBUG Ausgang = malloc(2000); if (NULL == Ausgang) { free(Eingang); printf("Allocation buffer buffer debug échouée\n"); return 1; } Ausgang[0] = '\0'; indexAus = 0; #endif indexPuffer = 0;// ToDo read out of input file Puffer = (Pfr_Str*)malloc(200 * sizeof(Pfr_Str)); if (Puffer == NULL) { free(Eingang); #ifdef DEBUG free(Ausgang); #endif printf("Allocation buffer RPN échouée\n"); return 1; } Datei = fopen("Text2.txt","r"); if(Datei == NULL) { printf("Fehler bei Datei oeffnen\n"); free(Puffer); Puffer = NULL; #ifdef DEBUG free(Ausgang); Ausgang = NULL; #endif free(Eingang); Eingang = NULL; return 1; } numGraphs = 0; aktGraphik = 0; return 0; } /* Verlassen de Einlesens ====================*/ void Quit(void) { free(Eingang); #ifdef DEBUG free(Ausgang); #endif /* Ausgang */ if (Puffer != NULL) free(Puffer); if (Fonction != NULL) free(Fonction); #ifdef MIT_VAR if (Valeurs != NULL) free(Valeurs); #endif #ifdef ARG_DOUBLE if (NULL != constValues) free(constValues); #endif #ifdef ADD_FUNCT // T.B.D Optimisation : if the pointers have been overtaken afar the parsing of the code, // do not free the pointers to the strings here. // for (int idx=0; idxRechnung); #ifdef MIT_VAR free((Graphs+indx)->Vars); #endif #ifdef ARG_DOUBLE free((Graphs+indx)->Constants); #endif #ifdef ADD_FUNCT for (indx2=0; indx2<(Graphs+indx)->numMsg; indx2++) free((Graphs+indx)->Msges[indx2]); free((Graphs+indx)->Msges); #endif } free(Graphs); } /* Operanden Stack der vor dem Parsen angelegt wurde wiederfreigeben */ free(Pile); } /* Leeren des Stacks der für die Umschreibung zur Polnische Notation benötigt wird : es wird nur bis zu dem Punkt geleert der am Aufruf von des parsenden Moduls der Stand war (wegen recursive Aufrufe). ===================================================*/ void emptyStack(long upto) { // while(indexPuffer>0) { while(indexPuffer>upto) { if ((Puffer + indexPuffer-1)->Typ == 2) { /* Wir haben einen arithmetischen Operator : ================================*/ switch((Puffer + indexPuffer-1)->Kommando) { case plus: (Fonction + nbFonctions)->cmd = nPlus; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"+ "); #endif break; case minus: (Fonction + nbFonctions)->cmd = nMoins; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"- "); #endif break; case chsg: (Fonction + nbFonctions)->cmd = chs; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"chs "); #endif break; case mult: (Fonction + nbFonctions)->cmd = nMult; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"* "); #endif break; case _div: (Fonction + nbFonctions)->cmd = nDiv; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"/ "); #endif break; case expos: (Fonction + nbFonctions)->cmd = nExpo; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"^ "); #endif break; #ifdef OPERAT_EQ case plusEq: (Fonction + nbFonctions)->cmd = nPlus; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"+ "); #endif break; case minusEq: (Fonction + nbFonctions)->cmd = nMoins; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"- "); #endif break; case multEq: (Fonction + nbFonctions)->cmd = nMult; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"* "); #endif break; case _divEq: (Fonction + nbFonctions)->cmd = nDiv; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"/ "); #endif break; case exposEq: (Fonction + nbFonctions)->cmd = nExpo; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"^ "); #endif break; #endif case _sqrt: (Fonction + nbFonctions)->cmd = nSqrt; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"sqrt "); #endif break; case _exp: (Fonction + nbFonctions)->cmd = nExp; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"exp "); #endif break; case _ln: (Fonction + nbFonctions)->cmd = nLog; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"ln "); #endif break; case _sin: (Fonction + nbFonctions)->cmd = nSin; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"sin "); #endif break; case _cos: (Fonction + nbFonctions)->cmd = nCos; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"cos "); #endif break; case _tan: (Fonction + nbFonctions)->cmd = nTan; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"tan "); #endif break; case _sinh: (Fonction + nbFonctions)->cmd = nSinh; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"sinh "); #endif break; case _cosh: (Fonction + nbFonctions)->cmd = nCosh; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"cosh "); #endif break; case _tanh: (Fonction + nbFonctions)->cmd = nTanh; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"tanh "); #endif break; case _asin: (Fonction + nbFonctions)->cmd = nAsin; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"asin "); #endif break; case _acos: (Fonction + nbFonctions)->cmd = nAcos; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"acos "); #endif break; case _atan: (Fonction + nbFonctions)->cmd = nAtan; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"atan "); #endif break; case assign: (Fonction + nbFonctions++)->cmd = stovar; (Fonction + nbFonctions++)->idx = ((Puffer + indexPuffer-1)->VarPos); #ifdef DEBUG strcat(Ausgang,Valeurs[(Puffer + indexPuffer-1)->VarPos].nom); strcat(Ausgang," Store "); #endif break; default: /* Fehler */ printf("Fehler in emptyStack\n"); #ifdef DEBUG Debugger(); strcat(Ausgang,"Fehler "); #endif } } else if ((Puffer + indexPuffer-1)->Typ == 1) { // Da die Operanden sofort zur Ausgabe Ùbeschrieben werden /* Wir haben einen Operand : sollte dieses nie nutzen =====================*/ printf("Möglicher Fehler wegen Operand aus den Operatoren/Funktionnen Stack ausgelesen\n"); (Fonction + nbFonctions)->cmd = put; /* Put Funktion aufrufen. */ nbFonctions++; /* Ne Compile pas (double)(*(Fonction + nbFonctions)) = (Puffer + indexPuffer)->Operand; // Danach den Wert speichern Apparemment Pb d'alignement tiers = (double*)&(*(Fonction + nbFonctions)); *tiers = (double)(Puffer + indexPuffer)->Operand; nbFonctions += tailleDouble; */ #ifndef ARG_DOUBLE (Fonction + nbFonctions)->dataf = (float)(Puffer + indexPuffer)->Operand; nbFonctions += tailleFlottant; #else (Fonction + nbFonctions)->idx = cntValues; constValues[cntValues] = (Puffer + indexPuffer)->Operand; nbFonctions += tailleEntier; cntValues++; #endif } else if ((Puffer + indexPuffer-1)->Typ == 3) { // Nur in parseBool Funktion benutzt /* Wir haben einen Boolean Operator : ===========================*/ switch((Puffer + indexPuffer-1)->Bool) { case and: (Fonction + nbFonctions)->cmd = nAnd; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"and "); #endif break; case or: (Fonction + nbFonctions)->cmd = nOr; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"or "); #endif break; case xor: (Fonction + nbFonctions)->cmd = nXor; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"xor "); #endif break; case not: (Fonction + nbFonctions)->cmd = nNot; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"not "); #endif break; case lth: (Fonction + nbFonctions)->cmd = nLth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"< "); #endif break; case gth: (Fonction + nbFonctions)->cmd = nGth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"> "); #endif break; case leth: (Fonction + nbFonctions)->cmd = nLeth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"<= "); #endif break; case geth: (Fonction + nbFonctions)->cmd = nGeth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,">= "); #endif break; case neq: (Fonction + nbFonctions)->cmd = nNeq; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"!= "); #endif break; case eq: (Fonction + nbFonctions)->cmd = nEq; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"== "); #endif break; case bassign: /* Zuerst dup Kommando damit Koie des Variable Wertes auf den Stack bleibt der vom Vergleich Kommando */ (Fonction + nbFonctions++)->cmd = dup; (Fonction + nbFonctions++)->cmd = stovar; (Fonction + nbFonctions++)->idx = ((Puffer + indexPuffer-1)->VarPos); #ifdef DEBUG strcat(Ausgang," dup "); strcat(Ausgang,Valeurs[(Puffer + indexPuffer-1)->VarPos].nom); strcat(Ausgang," store "); #endif break; default: /* Fehler */ printf("PB Fehler in Operator Identifizierung des Stacks :%d\n",(Puffer + indexPuffer)->Kommando); } } indexPuffer--; } } /* Auslesen der Operatoren mit höhere Priorität als die angegebene : ( Trick : wenn als Parameter Precedence[klauf]-1 (19) übergeben wird dann wird der Puffer bis zur nächsten ( nicht inklusiv geleert! Dabei nicht Precedence[klauf] (20) übergeben sonst können andere einschachtelnde Klammern vorzeitig ausgelesen werden) ===================================================*/ void emptyPrioOps(int aktPriorit) { while(indexPuffer>0 && ( (Puffer + indexPuffer-1)->Typ == 2 && Precedences[(Puffer + indexPuffer-1)->Kommando] <= aktPriorit || (Puffer + indexPuffer-1)->Typ == 3 && BoolPrec[(Puffer + indexPuffer-1)->Bool] <= aktPriorit)) { if ((Puffer + indexPuffer-1)->Typ == 2) { /* Wir haben einen arithmetischen Operator : ================================*/ switch((Puffer + indexPuffer-1)->Kommando) { case klauf : /* Fehler weil hat niedrigste Priorität. Die Klammern werden anders bearbeitet und haben deshalb die niedrigste Priorität. */ printf("Fehler Klammer auf in emptyPrioOps erreicht\n"); scanf("%c",&dumy); case plus: (Fonction + nbFonctions)->cmd = nPlus; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"+ "); #endif break; case minus: (Fonction + nbFonctions)->cmd = nMoins; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"- "); #endif break; case chsg: (Fonction + nbFonctions)->cmd = chs; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"chs "); #endif break; case mult: (Fonction + nbFonctions)->cmd = nMult; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"* "); #endif break; case _div: (Fonction + nbFonctions)->cmd = nDiv; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"/ "); #endif break; case expos: (Fonction + nbFonctions)->cmd = nExpo; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"^ "); #endif break; #ifdef OPERAT_EQ case plusEq: (Fonction + nbFonctions)->cmd = nPlus; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"+ "); #endif break; case minusEq: (Fonction + nbFonctions)->cmd = nMoins; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"- "); #endif break; case multEq: (Fonction + nbFonctions)->cmd = nMult; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"* "); #endif break; case _divEq: (Fonction + nbFonctions)->cmd = nDiv; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"/ "); #endif break; case exposEq: (Fonction + nbFonctions)->cmd = nExpo; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"^ "); #endif break; #endif case _sqrt: (Fonction + nbFonctions)->cmd = nSqrt; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"sqrt "); #endif break; case _exp: (Fonction + nbFonctions)->cmd = nExp; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"exp "); #endif break; case _ln: (Fonction + nbFonctions)->cmd = nLog; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"ln "); #endif break; case _sin: (Fonction + nbFonctions)->cmd = nSin; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"sin "); #endif break; case _cos: (Fonction + nbFonctions)->cmd = nCos; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"cos "); #endif break; case _tan: (Fonction + nbFonctions)->cmd = nTan; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"tan "); #endif break; case _sinh: (Fonction + nbFonctions)->cmd = nSinh; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"sinh "); #endif break; case _cosh: (Fonction + nbFonctions)->cmd = nCosh; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"cosh "); #endif break; case _tanh: (Fonction + nbFonctions)->cmd = nTanh; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"tanh "); #endif break; case _asin: (Fonction + nbFonctions)->cmd = nAsin; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"asin "); #endif break; case _acos: (Fonction + nbFonctions)->cmd = nAcos; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"acos "); #endif break; case _atan: (Fonction + nbFonctions)->cmd = nAtan; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"atan "); #endif break; case assign: (Fonction + nbFonctions++)->cmd = stovar; (Fonction + nbFonctions++)->idx = ((Puffer + indexPuffer-1)->VarPos); #ifdef DEBUG strcat(Ausgang,Valeurs[(Puffer + indexPuffer-1)->VarPos].nom); strcat(Ausgang," Store "); #endif break; default: /* Fehler */ printf("Fehler in emptyStack\n"); #ifdef DEBUG Debugger(); strcat(Ausgang,"Fehler "); #endif scanf("%c",&dumy); } } else if ((Puffer + indexPuffer-1)->Typ == 1) { // Da die Operanden sofort zur Ausgabe Ùbeschrieben werden /* Wir haben einen Operand : sollte dieses nie nutzen =====================*/ printf("Möglicher Fehler wegen Operand aus den Operatoren/Funktionnen Stack ausgelesen\n"); scanf("%c",&dumy); (Fonction + nbFonctions)->cmd = put; /* Put Funktion aufrufen. */ nbFonctions++; /* Ne Compile pas (double)(*(Fonction + nbFonctions)) = (Puffer + indexPuffer)->Operand; // Danach den Wert speichern Apparemment Pb d'alignement tiers = (double*)&(*(Fonction + nbFonctions)); *tiers = (double)(Puffer + indexPuffer)->Operand; nbFonctions += tailleDouble; */ #ifndef ARG_DOUBLE (Fonction + nbFonctions)->dataf = (float)(Puffer + indexPuffer)->Operand; nbFonctions += tailleFlottant; #else (Fonction + nbFonctions)->idx = cntValues; constValues[cntValues] = (Puffer + indexPuffer)->Operand; nbFonctions += tailleEntier; cntValues++; #endif } else if ((Puffer + indexPuffer-1)->Typ == 3) { // Nur in parseBool Funktion benutzt /* Wir haben einen Boolean Operator : ===========================*/ switch((Puffer + indexPuffer-1)->Bool) { case and: (Fonction + nbFonctions)->cmd = nAnd; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"and "); #endif break; case or: (Fonction + nbFonctions)->cmd = nOr; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"or "); #endif break; case xor: (Fonction + nbFonctions)->cmd = nXor; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"xor "); #endif break; case not: (Fonction + nbFonctions)->cmd = nNot; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"not "); #endif break; case lth: (Fonction + nbFonctions)->cmd = nLth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"< "); #endif break; case gth: (Fonction + nbFonctions)->cmd = nGth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"> "); #endif break; case leth: (Fonction + nbFonctions)->cmd = nLeth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"<= "); #endif break; case geth: (Fonction + nbFonctions)->cmd = nGeth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,">= "); #endif break; case neq: (Fonction + nbFonctions)->cmd = nNeq; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"!= "); #endif break; case eq: (Fonction + nbFonctions)->cmd = nEq; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"== "); #endif break; case bassign: /* Zuerst dup Kommando damit Kopie des Variable Wertes auf den Stack bleibt der vom Vergleich Kommando */ (Fonction + nbFonctions++)->cmd = dup; (Fonction + nbFonctions++)->cmd = stovar; (Fonction + nbFonctions++)->idx = ((Puffer + indexPuffer-1)->VarPos); #ifdef DEBUG strcat(Ausgang," dup "); strcat(Ausgang,Valeurs[(Puffer + indexPuffer-1)->VarPos].nom); strcat(Ausgang," store "); #endif break; default: /* Fehler */ printf("PB Fehler in Operator Identifizierung des Stacks :%d\n",(Puffer + indexPuffer)->Kommando); scanf("%c",&dumy); } } indexPuffer--; } } const int ModeFields[sonstiges+1] = { 1 << klamauf, 1 << klamzu, 1 << operatr, 1 << opernd, 1 << funktion, 1 << variable, 1 << parameter, 1 << ifelse, 1 << schleife, 1 << sonstiges }; /* String buffers used in parse & parseBool used temporary so may be global despite recusive calls. */ char toConvert[BUFFER_SIZE]; /* Zur Konverierung der Operanden. */ int indexConvert = 0; char Funktion[BUFFER_SIZE]; /* Zur Konverierung der Funktionsnamen. */ int indexFunktion = 0; /* Parsende Funktion : Preconditionen : akt IndexEin zeigt auf der ersten Ziffer der arthmetischen Zeichenkette oder einen Leerzeichen davor. Postkonditionnen : akt beinhaltet } oder \0 indexEin steht auf den Zeichen gerade nach der } der Stack zur polnische Notation Umschreibung ist leer, oder auf den selben Stand als vor dem Aufruf ============================================*/ #ifndef EXT_FOR void parsen(void) { #else /* Um die startarithmetic & Schleifenarithmetic der for Scheilfen (for(<>;...;<>) auszuwerten wird ein stopindex üergeben. Postkonditionnen : - wie parameterlose Version - indexEin hat den gleichen Wert wie den gegebenen Parameter. Akt beinhaltet das davorliegenedes Zeichen. */ void parsen(int to) { #endif long param_idx; /* Zur Konvertierung der Nr der Globalen Variable */ /* Um beim auslesen eines - zu wissen ob es Substrahierung oder ein Minus Zeichen handelt */ int Modus = ModeFields[sonstiges]; /* Zustand des operanden Puffers speichern. Beim Verlassen muss bis dahin wieder geleert werden */ long pufferStart = indexPuffer; #ifdef MIT_IF /* Hilfsvariable für if else Strukturen ============================*/ unsigned long ifIndex; /* Index eines if wonach die Indexe des else Zweiges Anfang und der if Struktur Ende gespeichert werden müssen */ #endif #ifdef MIT_WHILE /* Hilfvariablen für die Schleifen Programm Strukturen =========================================*/ unsigned long beginIndex; /* Index des Beginns eines Kondition Satzes eines while wohin die Endmethode einer solchen Struktur immer wieder führen muß */ unsigned long whileIndex; /* Index eines while Aufrufes um Index des Endes zu speichern */ unsigned long doIndex; /* Index des Beginns einer do while Struktur wohin der while Auruf führen muß wenn Kondition war ist */ #endif #ifdef MIT_FOR /* Hilsfsvariablen für for Schleifen Programm Strukturen ===========================================*/ unsigned long forIndex; /* Index des Anfangs der for Schleifen Kondition wohin die Endmethode immer wieder führen muß */ // float Beginn; /* Anfangswert der for Schleife */ // float Ende; /* Endwert der for Schleife */ #ifndef EXT_FOR BoolOp aktOp; /* Um den Vergleichs Operator der for Schleife zwischenzuspeichern. */ int Typ; /* Zwischenspeicher für Post Ink-Dekrementierung */ #else // To restore former parsing position when jumping to start or loop arithmetic for(<>;...<>) int formerPosition; int count; #endif #endif #ifdef MIT_VAR unsigned long varindex = 0; /* Um eine eingelesener Name an den in der Tabelle schon vorhandenen Variablen zu vergleichen */ #endif unsigned int oldIndex = 0; #ifdef DEBUG printf("\nEingang ist : \n"); printf(&Eingang[indexEin]); printf("\n"); /* Variablen Auflistung */ for (dbgidx=0;dbgidxGraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } Klammern++; /* Auf den Stack ablegen. */ (*(Puffer + indexPuffer)).Typ = 2; /* (*(Puffer + indexPuffer)).Operand = NULL;*/ (*(Puffer + indexPuffer)).Operand = 0; (*(Puffer + indexPuffer)).Kommando = klauf; indexPuffer++; /* Zustand merken */ Modus |= ModeFields[klamauf]; /* Leerziechen beseitigen */ akt = Eingang[indexEin++]; SUPP_BLANC continue; } else if (akt == 41) { /* ')' */ /* KLAMMER ZU ===========*/ #ifdef DEBUG printf("Fall )\n");fflush(stdout); #endif if (!(ModeFields[opernd] & Modus)) { // Error printf("%d Falscher Zustand bei ) %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Den Stack auslesen bis zur ( inklusiv und die Tabelle der Funktion Referenzen laden. Mit dem Trick von emptyPrioOps : */ emptyPrioOps(Precedences[klauf]-1); /* Die ( auch auslesen */ if ((*(Puffer + indexPuffer-1)).Kommando == klauf) { indexPuffer--; Klammern--; /* Zustand merken */ Modus |= ModeFields[klamzu]; } else { /* Fehler */ printf("%d Fehler in Fall ): ( nicht im Puffer gefunden\n",(Graphs + numGraphs)->GraphicID); /* Zustand merken */ Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Leerzeichen beseitigen */ akt = Eingang[indexEin++]; SUPP_BLANC continue; #if !defined(MAC_UI) || !defined(USE_ITL) } else if ((akt>=48 && akt<=57) || akt == '.') { /* 0-9 . */ #else } else if ((akt>=48 && akt<=57) || akt == decSeparat) { /* 0-9 . */ #endif /* NUMMER ========*/ #ifdef DEBUG printf("Fall 0-9 oder .\n");fflush(stdout); #endif if (!((ModeFields[operatr]|ModeFields[sonstiges]) & Modus)) { // Second case is for beginning of parsing // Error printf("%d Falscher Zustand bei constante %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } indexConvert = 0; /* Ganze Nummer auslesen. */ #if !defined(MAC_UI) || !defined(USE_ITL) while(indexConvert=48 && akt<=57) || akt == '.')) { #else while(indexConvert=48 && akt<=57) || akt == decSeparat)) { #endif toConvert[indexConvert++] = akt; akt = Eingang[indexEin++]; } toConvert[indexConvert] = '\0'; operand = atof(toConvert); indexConvert = 0; /* In der Tabelle der Funktion Referenzen laden. */ (Fonction + nbFonctions)->cmd = put; nbFonctions++; #ifndef ARG_DOUBLE (Fonction + nbFonctions)->dataf = (float)operand; nbFonctions += tailleFlottant; #else constValues[cntValues] = operand; (Fonction + nbFonctions)->idx = cntValues; ++cntValues; nbFonctions += tailleEntier; #endif #ifdef DEBUG /* strcat(Ausgang,"%3.2f"); sprintf(Ausgang,Ausgang,operand); // Verursacht Absturtz!! strcat(Ausgang," "); */ /* Optimaler ist */ sprintf(toConvert,"%3.2f ",operand); strcat(Ausgang,toConvert); #endif /* Zustand merken */ Modus = ModeFields[opernd]; /* STAND!! akt beinhaltet das erste Zeichen nach der Zahl. Die Ausleseung des daraufolgendes Zeichens am Ende der Schleifen darf nicht ausgeführt werden. */ SUPP_BLANC continue; } else if(akt == '+' || /* 43 */ akt == '-' || /* 45 */ akt == '*' || /* 42 */ akt == '/' || /* 47 */ akt == '^') { /* */ /* BINÄRER OPERATOR ================*/ /* Operator mit 2 Operanden Prioritat des Operators suchen. */ operation aktOp; #ifdef OPERAT_EQ if ('=' != Eingang[indexEin]) { #endif #ifndef EXT_FOR if (!(ModeFields[opernd] & Modus) && !((akt=='+'||akt=='-') && (Modus & (ModeFields[operatr]|ModeFields[sonstiges])))) { #else if (!(ModeFields[opernd] & Modus) && !((akt=='+'||akt=='-') && (Modus & (ModeFields[operatr]|ModeFields[sonstiges]))) && !(akt == '+' && Eingang[indexEin] == '+')) { #endif // Error printf("%d Falscher Zustand bei %c %s!\n",(Graphs + numGraphs)->GraphicID, akt, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } #ifdef EXT_FOR // If parsing mode is operator, the + or - signs may be part of the operand in form of a pre inc/derementation if ((ModeFields[operatr]|ModeFields[sonstiges]) & Modus && akt == '+' && Eingang[indexEin] == '+') { // Get name of variable indexFunktion = 0; akt = Eingang[++indexEin]; ++indexEin; while(indexFunktion= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_')) { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } /* STAND !! akt beinhaltet das erste Zeichen nach dem wort. indexEin steht auf den zweitnächste Buchstabe nach dem Ende des Wortes. Nicht die } verpassen. Die Ausleseung des daraufolgendes Zeichens am Ende der Schleifen darf nicht ausgeführt werden. Dies wird für alle Fälle der Zeichen Identifizierung sein !!! */ SUPP_BLANC Funktion[indexFunktion] = '\0'; // Get index of variable in variable table. Variable must already exist varindex = 0; while (varindexnom,Funktion)) { varindex++; } if (varindex>=nbVar) { // Error printf("%d ++ operator for non defined variable %s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // Store incrementation operator (Fonction + nbFonctions)->cmd = incVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; /* In case of expression --;, do not put value of variable onto the stack. First get to the following non white character. */ if (!(Modus == ModeFields[sonstiges] && (akt==';' || akt=='}'))) { // And the reading of its value (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; } /* Zustand merken */ Modus = ModeFields[variable] | ModeFields[opernd]; continue; } else if ((ModeFields[operatr]|ModeFields[sonstiges]) & Modus && akt == '-' && Eingang[indexEin] == '-') { // Get name of variable indexFunktion = 0; akt = Eingang[++indexEin]; ++indexEin; while(indexFunktion= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_')) { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } /* STAND !! akt beinhaltet das erste Zeichen nach dem wort. indexEin steht auf den zweitnächste Buchstabe nach dem Ende des Wortes. Nicht die } verpassen. Die Ausleseung des daraufolgendes Zeichens am Ende der Schleifen darf nicht ausgeführt werden. Dies wird für alle Fälle der Zeichen Identifizierung sein !!! */ SUPP_BLANC Funktion[indexFunktion] = '\0'; // Get index of variable in variable table. Variable must already exist varindex = 0; while (varindexnom,Funktion)) { varindex++; } if (varindex>=nbVar) { // Error printf("%d -- operator for non defined variable %s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // Store decrementation operator (Fonction + nbFonctions)->cmd = decVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; /* In case of expression --;, do not put value of variable onto the stack. First get to the following non white character. */ if (!(Modus == ModeFields[sonstiges] && (akt==';' || akt=='}'))) { // And the reading of its value (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; } /* Zustand merken */ Modus = ModeFields[variable] | ModeFields[opernd]; continue; } else { #endif switch (akt) { case '+': if (Modus & (ModeFields[opernd] | ModeFields[klamzu] | ModeFields[variable] | ModeFields[parameter])) { aktOp = plus; #ifdef DEBUG printf("Fall +\n");fflush(stdout); #endif } else { // Unary operator. Nothing to do aktOp = 0xFF; // ! aktOp is unsigned!! } break; case '-': if (Modus & (ModeFields[opernd] | ModeFields[klamzu] | ModeFields[variable] | ModeFields[parameter])) { aktOp = minus; #ifdef DEBUG printf("Fall -\n");fflush(stdout); #endif } else { aktOp = chsg; #ifdef DEBUG printf("Fall -(chs)\n");fflush(stdout); #endif } break; case '*': aktOp = mult; #ifdef DEBUG printf("Fall *\n");fflush(stdout); #endif break; case '/': aktOp = _div; #ifdef DEBUG printf("Fall /\n");fflush(stdout); #endif break; case '^': aktOp = expos; #ifdef DEBUG printf("Fall ^\n");fflush(stdout); #endif break; default : printf("%d Fehler bei binärer Operator %c\n",(Graphs + numGraphs)->GraphicID,akt); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } if (aktOp != 0xFF) { /* Operatoren mit höherer Priorität aus dem Puffer nehmen und Tabelle der Funktionsaufrufe laden. */ emptyPrioOps(Precedences[aktOp]); /* Operator selbst auf dem Stack ablegen. */ (Puffer + indexPuffer)->Typ = 2; (Puffer + indexPuffer)->Kommando = aktOp; indexPuffer++; /* Zustand merken */ Modus = ModeFields[operatr]; } /* Leerziechen beseitigen */ akt = Eingang[indexEin++]; SUPP_BLANC continue; #ifdef EXT_FOR } #endif #ifdef OPERAT_EQ } else { // Check that a variable has last been red out if (!(Modus & ModeFields[variable])) { // Error printf("%d Keine Variable vor %c %s!\n",(Graphs + numGraphs)->GraphicID, akt, Eingang+indexEin-1); /* Zustand merken */ #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // = Zeichen überspringen indexEin++; // Put operator to get value of variable onto the stack // Funktion and varindex still hold name and index of the variable /* Wert auslesen speichern !! schon beim auslesen der Variabel erledigt (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; */ #ifdef DEBUG strcat(Ausgang,Funktion); strcat(Ausgang," Eval "); #endif /* Den Wertzuweisungs Operator auf den Stack legen */ (Puffer + indexPuffer)->Typ = 2; (Puffer + indexPuffer)->Kommando = assign; (Puffer + indexPuffer)->VarPos = varindex; indexPuffer++; /* Den mit = kombinieren Operator auf dem Stack legen */ switch (akt) { case '+': aktOp = plusEq; #ifdef DEBUG printf("Fall +\n");fflush(stdout); #endif break; case '-': aktOp = minusEq; #ifdef DEBUG printf("Fall -\n");fflush(stdout); #endif break; case '*': aktOp = multEq; #ifdef DEBUG printf("Fall *\n");fflush(stdout); #endif break; case '/': aktOp = _divEq; #ifdef DEBUG printf("Fall /\n");fflush(stdout); #endif break; case '^': aktOp = exposEq; #ifdef DEBUG printf("Fall ^\n");fflush(stdout); #endif break; default : printf("%d Fehler bei binärer Operator %c=\n",(Graphs + numGraphs)->GraphicID,akt); scanf("%c",&dumy); ExecError(); return; } /* Operatoren mit höherer Priorität aus dem Puffer nehmen und Tabelle der Funktionsaufrufe laden. */ // emptyPrioOps(Precedences[aktOp]); /* Operator selbst auf dem Stack ablegen. */ (Puffer + indexPuffer)->Typ = 2; (Puffer + indexPuffer)->Kommando = aktOp; indexPuffer++; /* Zum nächsten Zeichen gehen */ akt = Eingang[indexEin++]; SUPP_BLANC /* Zustand merken. Wenn danach einen - gefunden wird dann ist es chs nicht minus */ Modus = ModeFields[operatr]; continue; } #endif } else if (akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122) { /* Buchstabe A-Z a-z */ /* WORT ======*/ #ifdef DEBUG printf("Fall Buchstabe 65-90 97-122\n");fflush(stdout); #endif /* Ganzes Wort auslesen. */ indexFunktion = 0; while(indexFunktion= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_')) { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } /* STAND !! akt beinhaltet das erste Zeichen nach dem wort. indexEin steht auf den zweitnächste Buchstabe nach dem Ende des Wortes. Nicht die } verpassen. Die Ausleseung des daraufolgendes Zeichens am Ende der Schleifen darf nicht ausgeführt werden. Dies wird für alle Fälle der Zeichen Identifizierung sein !!! */ SUPP_BLANC Funktion[indexFunktion] = '\0'; /* Zuerts nach mathematische Systemfunktionen suchen. Diese haben höchste Priorität. Direct auf den Stack ablegen. */ (Puffer + indexPuffer)->Typ = 2; // Macro for error checking when identifying a function call #define ErrorCheck(fName) if (!((ModeFields[operatr]|ModeFields[sonstiges]) & Modus)) { \ printf("%d Kein Operator vor Funktion %s %s!\n",(Graphs + numGraphs)->GraphicID, fName, Eingang+indexEin-1); \ Modus = ModeFields[sonstiges]; \ Debugger(); \ scanf("%c",&dumy); \ ExecError(); \ return; \ } if (0 == strcmp("sqrt",Funktion)) { if (!((ModeFields[opernd]|ModeFields[sonstiges]) & Modus)) { // Second case is for beginning (or after { : recursive call) // Error printf("%d Kein Operator vor Funktion %s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } (Puffer + indexPuffer)->Kommando = _sqrt; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; // A voir } else if (0 == strcmp("exp",Funktion)) { ErrorCheck("exp") (Puffer + indexPuffer)->Kommando = _exp; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("ln",Funktion)) { ErrorCheck("ln") (Puffer + indexPuffer)->Kommando = _ln; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("sin",Funktion)) { ErrorCheck("sin") (Puffer + indexPuffer)->Kommando = _sin; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("cos",Funktion)) { ErrorCheck("cos") (Puffer + indexPuffer)->Kommando = _cos; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("tan",Funktion)) { ErrorCheck("tan") (Puffer + indexPuffer)->Kommando = _tan; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("sinh",Funktion)) { ErrorCheck("sinh") (Puffer + indexPuffer)->Kommando = _sinh; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("cosh",Funktion)) { ErrorCheck("cosh") (Puffer + indexPuffer)->Kommando = _cosh; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("tanh",Funktion)) { ErrorCheck("tanh") (Puffer + indexPuffer)->Kommando = _tanh; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("asin",Funktion)) { ErrorCheck("asin") (Puffer + indexPuffer)->Kommando = _asin; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("acos",Funktion)) { ErrorCheck("acos") (Puffer + indexPuffer)->Kommando = _acos; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("atan",Funktion)) { ErrorCheck("atan") (Puffer + indexPuffer)->Kommando = _atan; indexPuffer++; /* Zustand merken */ Modus = ModeFields[funktion] | ModeFields[operatr]; continue; #ifdef MIT_IF } else if (0 == strcmp("if",Funktion)) { /* IF ELSE STRUKTUR ===============*/ #ifdef DEBUG printf("If/else Fall : %s.\n",Funktion); #endif if (!(Modus & (1<GraphicID, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Puffer leeren u. Bool Satz des if auslesen */ /* und die Zweige bearbeiten. */ // emptyStack(); /* Zur naechsten ( gehen */ SUPP_BLANC if (akt != '(') { /* Fehler */ printf("%d Fehler ( nicht gefunden nach else %d\n",(Graphs +numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Damit wieder mit der ( weitergegangen wird */ indexEin--; /* Bool Satz einlesen */ #ifndef EXT_FOR parseBool(); #else parseBool(false); #endif /* STAND !! akt beinhaltet das letzte ) Zeichen der Boolesche Expression. indexEin steht auf des Zeichen danach. */ /* In der Funktionreferenzen Tabelle if speichern. Danach werden die Indexe des ersten Kommando des else Zweiges und nach der if Struktur gespeichert */ (Fonction + nbFonctions)->cmd = branchif; ifIndex = nbFonctions + 1; nbFonctions += 3; #ifdef DEBUG strcat(Ausgang,"if\n"); #endif /* Auf dem Operanden Stack wird dann das Ergebnis berechnet. */ /* Bis zur naechsten { gehen */ akt = Eingang[indexEin++]; SUPP_BLANC if (akt != '{') { /* Fehler */ printf("%d Fehler { nicht gefunden nach if %d\n",(Graphs +numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Den Satz durchparsen */ #ifndef EXT_FOR parsen(); #else parsen(0x7FFFFFFF); #endif /* STAND !! akt beinhaltet } indexEin steht auf dem Zeichen gerade nach der } der Stack zur polnische Notation Umschreibung ist leer, oder auf den selben Stand als vor dem Aufruf */ /* Wir sind am else (wenn vorhanden) */ /* Das Ende des if Zweiges speichern (u. Anfang des else) */ (Fonction + ifIndex)->idx = nbFonctions; /* Index der ersten Kommandos des else zweiges */ /* normalerweise branchelse Aufruf wenn der else Zweig vorhanden ist. */ /* else suchen (nicht immer vorhanden) */ akt = Eingang[indexEin++]; SUPP_BLANC if (!strncmp(&Eingang[indexEin-1],"else",4)) { /* else Zweig ist vorhanden */ indexEin += 3; /* Referenz der Funktion zum Ueberspringen des else Zweiges */ (Fonction + nbFonctions)->cmd = branchelse; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"else\n"); #endif /* Bis zur naechsten { gehen */ akt = Eingang[indexEin++]; SUPP_BLANC if (akt != '{') { /* Fehler */ printf("%d Fehler { nicht gefunden nach else %d\n",(Graphs +numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Den Satz durchparsen */ #ifndef EXT_FOR parsen(); #else parsen(0x7FFFFFFF); #endif /* STAND !! akt beinhaltet } indexEin steht auf dem Zeichen gerade nach der } der Stack zur polnische Notation Umschreibung ist leer, oder auf den selben Stand als vor dem Aufruf */ akt = Eingang[indexEin++]; SUPP_BLANC /* Das Ende des else Zweiges speichern */ (Fonction + ifIndex + 1)->idx = (nbFonctions-1); /* Index des letzten Kommandos der if Struktur */ } else { (Fonction + ifIndex)->idx = nbFonctions-1; /* Index des letzten Kommandos des if zweiges */ /*vor nächste Aufruf wird index inkementiert und steht dann auf erstes Kommando nach if Zweig. */ (Fonction + ifIndex + 1)->idx = (unsigned int)NULL; /* Index der ersten Kommandos nach if Struktur */ #ifdef DEBUG printf("Kein else Zweig\n"); strcat(Ausgang,"\n"); #endif } /* Zustand merken */ Modus = ModeFields[ifelse] | ModeFields[sonstiges]; /* */ continue; #endif } else if (!strncmp(Funktion,"p_",2)) { /* GLOBALE VARIABLE ================*/ #ifdef DEBUG printf("Globale variable Fall : %s\n",Funktion); #endif if(!(Modus & (ModeFields[operatr]|ModeFields[sonstiges]))) { // Second case is for beginning // Error printf("%d Falscher Modus vor parameter%s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } param_idx = atoi(Funktion+2); if (param_idx<0 || param_idx>MAX_PARAM) { printf("Illegal parameter index p_%d\n", param_idx); // Generate code that return a NAN value Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } else { /* Auslesen der Globalen variable speichern */ (Fonction + nbFonctions)->cmd = readParam; (Fonction + nbFonctions+1)->idx = param_idx; nbFonctions+=2; } #ifdef DEBUG strcat(Ausgang,Funktion); strcat(Ausgang," Read "); #endif /* Zustand merken */ Modus = ModeFields[parameter] | ModeFields[opernd]; SUPP_BLANC /* */ continue; #ifdef MIT_WHILE } else if (0 == strcmp("while",Funktion)) { /* WHILE STRUKTUR ===============*/ #ifdef DEBUG printf("While schleife : %s\n",Funktion); #endif if (!(Modus & (1<GraphicID, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Puffer leeren u. Bool Satz des while auslesen */ // emptyStack(); /* Index des Beginnes der While Kondition speichern. Dahin muss die end Methode der Schleife immer wieder führen. */ // beginIndex = nbFonctions; //MODIF // Eine Position davor weil in Execute Schleife der index nochmals inkrementiert wird. beginIndex = nbFonctions-1; /* Zur naechsten ( gehen */ SUPP_BLANC if (akt != '(') { /* Fehler */ printf("%d Syntax Fehler, ( nicht gefunden linie %d %s\n",(Graphs + numGraphs)->GraphicID,currLine,Eingang[indexEin]); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Damit wieder mit der ( weitergegangen wird */ indexEin--; /* Bool Satz einlesen */ #ifndef EXT_FOR parseBool(); #else parseBool(false); #endif /* STAND !! akt beinhaltet das letzte ) Zeichen der Boolesche Expression. indexEin steht auf des Zeichen danach. */ /* In der Funktionreferenzen Tabelle while speichern. Danach wird der Index des ersten Kommandos nach der while Schleife gespeichert. */ (Fonction + nbFonctions)->cmd = nwhile; /* Position speichern denn Schleifenende ist noch nicht bekannt */ whileIndex = nbFonctions+1; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,"while\n"); #endif /* Auf dem Operanden Stack wird dann das Ergebnis berechnet. */ /* Bis zur naechsten { gehen */ akt = Eingang[indexEin++]; SUPP_BLANC if (akt != '{') { /* Fehler */ printf("%d Syntax Fehler, { nicht gefunden linie %d %s\n",(Graphs + numGraphs)->GraphicID,currLine,Eingang[indexEin]); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Den Satz durchparsen */ #ifndef EXT_FOR parsen(); #else parsen(0x7FFFFFFF); #endif /* STAND !! akt beinhaltet } indexEin steht auf dem Zeichen gerade nach der } der Stack zur polnische Notation Umschreibung ist leer, oder auf den selben Stand als vor dem Aufruf */ akt = Eingang[indexEin++]; SUPP_BLANC /* Ende der Schleife absolvieren. Nach endwhile wird der Index des Anfangs des Bool Satzes der Schleife in der Funktionsreferenzenliste.*/ // *(Fonction + nbFonctions) = endwhile; (Fonction + nbFonctions)->cmd = endloop; (Fonction + nbFonctions + 1)->idx = beginIndex; /* Index des Beginns eines Kondition Satzes eines while wohin die Endmethode einer solchen Struktur immer wieder führen muß */ nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,"end\n"); #endif /* Für while Aufruf Ende der Schleife speichern */ // *(Fonction + whileIndex) = (double (*)(void))nbFonctions; /* Index des ersten Kommandos nach // der while Schleife */ //MODIF (Fonction + whileIndex)->idx = (nbFonctions-1); /* Index des letzten elementes der while Schleife */ /* Zustand merken */ Modus = ModeFields[schleife] | ModeFields[sonstiges]; /* */ continue; } else if (0 == strcmp("do",Funktion)) { /* DO WHILE STRUKTUR =================*/ #ifdef DEBUG printf("Do While schleife : %s\n",Funktion); #endif if (!(Modus & (1<GraphicID, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Puffer leeren */ // emptyStack(); /* Beginn der Schleife speichern */ // doIndex = nbFonctions; //MODIF // Eine Position davor weil in Execute Schleife der index nochmals inkrementiert wird. doIndex = nbFonctions-1; #ifdef DEBUG strcat(Ausgang,"do\n"); #endif /* Bis zur naechsten { gehen */ SUPP_BLANC if (akt != '{') { /* Fehler */ printf("%d Fehler in do ( nicht gefunden %d\n",(Graphs +numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Den Satz durchparsen */ #ifndef EXT_FOR parsen(); #else parsen(0x7FFFFFFF); #endif /* STAND !! akt beinhaltet } indexEin steht auf dem Zeichen gerade nach der } der Stack zur polnische Notation Umschreibung ist leer, oder auf den selben Stand als vor dem Aufruf */ akt = Eingang[indexEin++]; SUPP_BLANC if (strncmp((const char*)Eingang+indexEin-1,"while",5)) { /* SyntaxFehler */ printf("%d Syntax Fehler, while nicht gefunden linie %d %s\n",(Graphs + numGraphs)->GraphicID,currLine,Eingang[indexEin]); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } else { indexEin += 4; /* Zur naechsten ( gehen */ akt = Eingang[indexEin++]; SUPP_BLANC if (akt != '(') { /* Fehler */ printf("%d Syntax Fehler, ( nicht gefunden linie %d %s\n",(Graphs + numGraphs)->GraphicID,currLine,Eingang[indexEin]); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Damit wieder mit der ( weitergegangen wird */ indexEin--; /* Bool Satz einlesen */ #ifndef EXT_FOR parseBool(); #else parseBool(false); #endif } /* STAND !! akt beinhaltet das letzte ) Zeichen der Boolesche Expression. indexEin steht auf des Zeichen danach. */ akt = Eingang[indexEin++]; SUPP_BLANC /* Ende der Schleife absolvieren */ (Fonction + nbFonctions)->cmd = dowhile; (Fonction + nbFonctions + 1)->idx = doIndex; /* Index des Beginns der Schleife-1weil nach aufruf noch inkrementiert wird */ nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,"while\n"); #endif /* Zustand merken */ Modus = ModeFields[schleife] | ModeFields[sonstiges]; /* */ continue; #endif #ifdef MIT_FOR } else if (0 == strcmp("for",Funktion)) { /* FOR SCHLEIFE ============*/ #ifdef DEBUG printf("For schleife : %s\n",Funktion); #endif if (!(Modus & (1<GraphicID, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Puffer leeren */ // emptyStack(); /* Zu naechste ( gehen wenn noch nicht erreicht */ SUPP_BLANC if (akt != '(') { /* Fehler */ printf("%d Fehler nach for Linie %d\n",(Graphs + numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } #ifndef EXT_FOR /* Grenzwerte auslesen und index Name Zuerst Name des Schleifenindexes auslesen : ================================*/ // Suppress potential blancs while (' ' == Eingang[indexEin]) indexEin++; indexFunktion = 0; while (indexFunktionnom,Funktion)) { varindex++; } if (varindex>=nbVar) { /* Neue Variable erzeugen : ====================*/ strcpy((Valeurs + nbVar)->nom,Funktion); (Valeurs + nbVar)->valeur = 0; /* Zur Sicherheit */ varindex = nbVar; nbVar++; } /* Beginn Wert auslesen : ===================*/ while (Eingang[indexEin] != '=') { if(Eingang[indexEin] != ' ') { /* Fehler */ printf("%d Fehler in for Linie %d\n",(Graphs + numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } indexEin++; } indexEin++; while (' ' == Eingang[indexEin]) indexEin++; indexConvert = 0; while (indexConvert < BUFFER_SIZE && (';' != Eingang[indexEin] && ' ' != Eingang[indexEin])) { // if(Eingang[indexEin] != ' ') { /* Fehler */ // printf("Fehler in for Grenzwert 1 Linie %d\n",currLine); // } toConvert[indexConvert++] = Eingang[indexEin++]; } while (';' != Eingang[indexEin]) indexEin++; toConvert[indexConvert] = '\0'; /* Beginn Wert zuweisung erstellen */ (Fonction + nbFonctions)->cmd = put; #ifndef ARG_DOUBLE (Fonction + nbFonctions +1)->dataf = (float)atof(toConvert); nbFonctions += tailleFlottant; #else constValues[cntValues] = atof(toConvert); (Fonction + nbFonctions+1)->idx = cntValues; ++cntValues; nbFonctions += tailleEntier; #endif (Fonction + nbFonctions + 1)->cmd = stovar; (Fonction + nbFonctions + 2)->idx = varindex; nbFonctions += 3; #ifdef DEBUG strcat(Ausgang,toConvert); strcat(Ausgang," "); strcat(Ausgang,(Valeurs + varindex)->nom); strcat(Ausgang," "); strcat(Ausgang,"Store "); #endif #else /* Parse start arithmetic : ===================*/ // Safety check: operator stack should be empty if (indexPuffer>0) Debugger(); // Find end of start arithmetic formerPosition = indexEin; while (';' != Eingang[formerPosition]) { if ('{' == Eingang[formerPosition] || '}' == Eingang[formerPosition]) { printf("%d Fehler bei for code %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin-1); scanf("%c",&dumy); Modus = ModeFields[sonstiges]; ExecError(); return; } formerPosition++; } parsen(formerPosition+1); // Check if (';' != akt) { printf("%d nach for start parsen %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin-1); scanf("%c",&dumy); } akt = Eingang[indexEin++]; // indexEin steht auf Zeichen nach ; SUPP_BLANC #endif #ifndef EXT_FOR /* End Wert auslesen. indexEin steht auf ; : ================================*/ indexEin++; // Suppress potential blancs while(Eingang[indexEin] == ' ') indexEin++; if(strncmp(&Eingang[indexEin],Funktion,indexFunktion)) { /* Fehler */ printf("%d Fehler in for index Name Linie %d\n",(Graphs + numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } indexEin += indexFunktion; /* Kondition bestimmen < < <= >= */ while ( Eingang[indexEin] != '<' && Eingang[indexEin] != '>') indexEin++; if(!strncmp("<=",&Eingang[indexEin],2)) { aktOp = leth; indexEin += 2; } else if(!strncmp(">=",&Eingang[indexEin],2)) { aktOp = geth; indexEin += 2; } else if(Eingang[indexEin] == '<') { aktOp = lth; indexEin++; } else if(Eingang[indexEin] == '>') { aktOp = gth; indexEin++; } else { printf("%d Fehler in for Ende Kondit Linie %d\n",(Graphs + numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // Suppress potential blancs while(Eingang[indexEin] == ' ') indexEin++; indexConvert = 0; while (indexConvert < BUFFER_SIZE && (Eingang[indexEin] != ';')) { // if(Eingang[indexEin] != ' ') { /* Fehler */ // printf("Fehler in for Grenzwert 1 Linie %d\n",currLine); // } toConvert[indexConvert++] = Eingang[indexEin++]; } toConvert[indexConvert] = '\0'; indexEin++; // Suppress potential blancs while (' ' == Eingang[indexEin]) indexEin++; /* Stand: indexEin zeigt auf Zeichen nach dem ; der Schleife Beendungs Kondition. */ /* Beginn der Schleife speichern und while Test erstellen : ===========================================*/ // forIndex = nbFonctions; //MODIF forIndex = nbFonctions-1; (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions + 1)->idx = varindex; if (!strncmp(toConvert,"p_",2)) { // Limit value given by parameter (Fonction + nbFonctions + 2)->cmd = readParam; (Fonction + nbFonctions + 3)->idx = atoi(toConvert+2); nbFonctions += tailleEntier; } else { (Fonction + nbFonctions + 2)->cmd = put; #ifndef ARG_DOUBLE (Fonction + nbFonctions + 3)->dataf = (float)atof(toConvert); nbFonctions += tailleFlottant; #else constValues[cntValues] = atof(toConvert); (Fonction + nbFonctions + 3)->idx = cntValues; cntValues++; nbFonctions += tailleEntier; #endif } nbFonctions += 3; #ifdef DEBUG strcat(Ausgang,"\n"); strcat(Ausgang,(Valeurs + varindex)->nom); strcat(Ausgang," Eval "); strcat(Ausgang,toConvert); #endif switch(aktOp) { case lth: (Fonction + nbFonctions)->cmd = nLth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"< "); #endif break; case gth: (Fonction + nbFonctions)->cmd = nGth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"> "); #endif break; case leth: (Fonction + nbFonctions)->cmd = nLeth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,"<= "); #endif break; case geth: (Fonction + nbFonctions)->cmd = nGeth; nbFonctions++; #ifdef DEBUG strcat(Ausgang,">= "); #endif break; } (Fonction + nbFonctions)->cmd = nwhile; whileIndex = nbFonctions + 1; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,"while "); #endif #else /* Parse loop condition. =======================*/ forIndex = nbFonctions-1; parseBool(true); (Fonction + nbFonctions)->cmd = nwhile; whileIndex = nbFonctions + 1; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,"while "); #endif // indexEin steht auf Zeichen nach ; forStack[++numFor][0] = indexEin; // Count ( and ) to find ending ) of the for command count = 0; do { if ('('==Eingang[indexEin]) { count++; } if (')'==Eingang[indexEin]) { count--; } ++indexEin; // Syntax check ??? { or ; if ('{'==Eingang[indexEin] || '}'==Eingang[indexEin]) { printf("%d Fehler bei for code %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin-1); scanf("%c",&dumy); ExecError(); return; } } while(count>-1); forStack[numFor][1] = indexEin-1; akt = Eingang[indexEin-1]; #endif #ifndef EXT_FOR /* Inkrement / Dekrement Verfahren auslesen. indexEin steht nach ; ===================================*/ if(!strncmp("++",&Eingang[indexEin],2)) { /* Inkrementierung muß am Anfang der Schleife erfolgen */ (Fonction + nbFonctions)->cmd = incVar; (Fonction + nbFonctions +1)->idx = varindex; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,(Valeurs + varindex)->nom); strcat(Ausgang,"++ "); printf("Pre Inkrementierung index %d bei %ld\n",varindex,nbFonctions-2); #endif indexEin += 2; Typ = 0; } if(!strncmp("--",&Eingang[indexEin],2)) { /* Dekrementierung muß am Anfang der Schleife erfolgen */ (Fonction + nbFonctions)->cmd = decVar; (Fonction + nbFonctions +1)->idx = varindex; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,(Valeurs + varindex)->nom); strcat(Ausgang,"-- "); printf("Pre Dekrementierung index %d bei %ld\n",varindex,nbFonctions-2); #endif indexEin += 2; Typ = 0; } if(strncmp(&Eingang[indexEin],Funktion,indexFunktion)) { /* Fehler */ printf("%d Fehler in for index Name Linie %d\n",(Graphs + numGraphs)->GraphicID,currLine); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } indexEin += indexFunktion; if(!strncmp("++",&Eingang[indexEin],2)) { /* Inkrementierung muß am Ende der Schleife erfolgen */ Typ = 1; } if(!strncmp("--",&Eingang[indexEin],2)) { /* Dekrementierung muß am Ende der Schleife erfolgen */ Typ = -1; } akt = Eingang[indexEin+2]; indexEin +=3; #endif // A VOIR while(Eingang[indexEin] != '{') indexEin++; /* Bis zur naechsten { gehen */ SUPP_BLANC /* STAND !! akt beinhaltet ) indexEin steht auf dem Zeichen gerade nach der ) der Stack zur polnische Notation Umschreibung ist leer, oder auf den selben Stand als vor dem Aufruf */ if (akt != ')') { /* Fehler */ printf("%d ) not found in for loop %s\n",(Graphs + numGraphs)->GraphicID,Eingang+indexEin-5); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } akt = Eingang[indexEin++]; SUPP_BLANC if (akt != '{') { /* Fehler */ printf("%d { not found in for loop %s\n",(Graphs + numGraphs)->GraphicID,Eingang+indexEin-5); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Schleife auslesen */ #ifndef EXT_FOR parsen(); #else parsen(0x7FFFFFFF); #endif /* STAND !! akt beinhaltet } indexEin steht auf dem Zeichen gerade nach der } der Stack zur polnische Notation Umschreibung ist leer, oder auf den selben Stand als vor dem Aufruf */ akt = Eingang[indexEin++]; SUPP_BLANC #ifndef EXT_FOR /* Post-Ink oder Dekrementierung erstellen : ==================================*/ if(Typ == 1) { (Fonction + nbFonctions)->cmd = incVar; (Fonction + nbFonctions +1)->idx = varindex; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,(Valeurs + varindex)->nom); strcat(Ausgang,"++ "); printf("Post Inkrementierung index %d bei %ld\n",varindex,nbFonctions-2); #endif } if(Typ == -1) { (Fonction + nbFonctions)->cmd = decVar; (Fonction + nbFonctions +1)->idx = varindex; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,(Valeurs + varindex)->nom); strcat(Ausgang,"-- "); printf("Post Dekrementierung index %d bei %ld\n",varindex,nbFonctions-2); #endif } /* Am Ende der Schleife immer zum Anfang gehen : ======================================*/ // *(Fonction + nbFonctions) = endwhile; (Fonction + nbFonctions)->cmd = endloop; (Fonction + nbFonctions + 1)->idx = forIndex; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,"End\n"); #endif /* Für while Ende der Schleife speichern */ // *(Fonction + whileIndex) = (double (*)(void))nbFonctions; //MODIF (Fonction + whileIndex)->idx = (nbFonctions-1); #else // Store present parsing position to formerPosition = indexEin; indexEin = forStack[numFor][0]; parsen(forStack[numFor][1]+1); --numFor; indexEin = formerPosition; akt = Eingang[indexEin-1]; /* Am Ende der Schleife immer zum Anfang gehen : ======================================*/ // *(Fonction + nbFonctions) = endwhile; (Fonction + nbFonctions)->cmd = endloop; (Fonction + nbFonctions + 1)->idx = forIndex; nbFonctions += 2; #ifdef DEBUG strcat(Ausgang,"End\n"); #endif /* Für while Ende der Schleife speichern */ // *(Fonction + whileIndex) = (double (*)(void))nbFonctions; //MODIF (Fonction + whileIndex)->idx = (nbFonctions-1); #endif /* Zustand merken */ Modus = ModeFields[schleife] | ModeFields[sonstiges]; /* */ continue; #endif #ifdef ADD_FUNCT /* Additional routines are positioned on the same level as control structures as if else / while ... or full arithmetic expression because they may only be used as single command: print(" "); and not be embedded in an expression sin(x) + printf(" ") - ... as they do not return a value. */ } else if (0 == strcmp("print",Funktion)) { if (!(Modus & (1<GraphicID, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // SUPP_BLANC if ('(' != akt) { // Error Debugger(); } akt = Eingang[indexEin++]; SUPP_BLANC if ('"' == akt) { // Constant string message akt = Eingang[indexEin++]; indexFunktion = 0; do { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } while('"'!=akt && indexFunktioncmd = printMsg; (Fonction + nbFonctions + 1)->idx = numMsges; /* */ nbFonctions += 2; numMsges++; // Stand:akt beinhaltet '"'. Bis ')' gehen und übersprimgen. do { akt = Eingang[indexEin++]; } while(')'!=akt); akt = Eingang[indexEin++]; } else if (akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || '_'==akt) { // Variable name indexFunktion = 0; do { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } while(' '!=akt && ')'!=akt && indexFunktionnom,Funktion)) { varindex++; } if (varindex>=nbVar) { // Allocate on each new text, and after // parsing, copy the pointer itself instead of buffer content Msges[numMsges] = malloc(17); if(NULL==Msges[numMsges]) { printf("Error message allocation code %d\n", numGraphs); } strcpy(Msges[numMsges], "Variable not set"); (Fonction + nbFonctions)->cmd = printMsg; (Fonction + nbFonctions + 1)->idx = numMsges; /* */ nbFonctions += 2; numMsges++; } else { (Fonction + nbFonctions)->cmd = printVar; (Fonction + nbFonctions + 1)->idx = varindex; /* */ nbFonctions += 2; } // Stand:akt beinhaltet ' '. oder ')'. Im ersten fall bis zu ')' gehen und übersprimgen. if(')' != akt) do { akt = Eingang[indexEin++]; } while(')'!=akt); akt = Eingang[indexEin++]; } else { // Error Debugger(); } #endif } else { #ifdef MIT_VAR /* VARIABLE =========*/ #ifdef DEBUG printf("Variable Fall : %s.\n",Funktion); #endif if (!(Modus & (ModeFields[operatr]|ModeFields[sonstiges]))) { // Second case is for beginning // Error printf("%d Falscher Modus vor %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Testen ob es eine neue Variable ist oder eine schon vorhanden */ varindex = 0; while (varindexnom,Funktion)) { varindex++; } /* Nach = Zeichen suchen und den arithmetischen Satz danach */ SUPP_BLANC if (varindex>=nbVar) { /* Neue Variable erzeugen : ====================*/ strcpy((Valeurs + nbVar)->nom,Funktion); (Valeurs + nbVar)->valeur = 0; /* Zur Sicherheit */ varindex = nbVar; nbVar++; if (akt != '=') { /* Fehler : =======*/ printf("%d Neue Variable angegeben ohne Wert Zuweisung :%s!\n",(Graphs + numGraphs)->GraphicID,Funktion); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; /* Eventuell die Variable mit einem Standard Wert initialisieren (Valeurs + nbVar)->valeur = valErreur; */ } } /* Variable vorhanden und gefunden */ /* Testen ob es nicht eine Wert Affectation ist */ if (akt == '=') { /* Wert Zuweisung : ==============*/ /* Zuerst den Operanden Puffer leeren */ // emptyStack(); /* Den Wertzuweisungs Operator auf den Stack legen */ (Puffer + indexPuffer)->Typ = 2; (Puffer + indexPuffer)->Kommando = assign; (Puffer + indexPuffer)->VarPos = varindex; indexPuffer++; /* Zum nächsten Zeichen gehen */ /* while (Eingang[indexEin] == ' ') { indexEin++; } */ SUPP_BLANC /* Zustand merken. Wenn danch einen - gefunden wird dann ist es chs nicht minus */ Modus = ModeFields[operatr]; /* Nächstes Symbol einlesen. */ akt = Eingang[indexEin++]; } else { /* Wert auslesen : =============*/ /* Wert auslesen speichern */ (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; #ifdef DEBUG strcat(Ausgang,Funktion); strcat(Ausgang," Eval "); #endif #ifdef EXT_FOR // Check if variable is not followed by incrementation or decrementation operator if (akt=='+' && Eingang[indexEin] == '+') { /* In case of expression ++;, do not put value of variable onto the stack. So overwrite previous access call. First get to the following non white character. */ count = indexEin+1; while (Eingang[count]==' ' || Eingang[count]=='\n' || Eingang[count]=='\r' || Eingang[count]=='\t') { count++; } if (Modus == ModeFields[sonstiges] && (Eingang[count]==';' || count==to-1)) { nbFonctions-=2; } // Store incrementation operator (Fonction + nbFonctions)->cmd = incVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; ++indexEin; akt = Eingang[indexEin++]; } if (akt=='-' && Eingang[indexEin] == '-') { /* In case of expression --;, do not put value of variable onto the stack. So overwrite previous access call. First get to the following non white character. */ count = indexEin+1; while (Eingang[count]==' ' || Eingang[count]=='\n' || Eingang[count]=='\r' || Eingang[count]=='\t') { count++; } if (Modus == ModeFields[sonstiges] && (Eingang[count]==';' || count==to-1)) { nbFonctions-=2; } // Store decrementation operator (Fonction + nbFonctions)->cmd = decVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; ++indexEin; akt = Eingang[indexEin++]; } #endif /* Zustand merken */ Modus = ModeFields[variable] | ModeFields[opernd]; } /* */ continue; #else /* Fehler */ printf("Fehler in Funktion Identifizierung : %s!",Funktion); Modus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; /* Zustand merken */ Modus = ModeFields[sonstiges]; #endif } // Ende des Zeichenkettenidentifikation /* ENDE ARITHMETIC EXPRESSION =========================*/ } else if (akt == ';') { /* Den Puffer leeren bis Position die bestand beim Aufruf von parsen */ emptyStack(pufferStart); /* TBC : es wird eine neue Arithmetik angefangen */ Modus = ModeFields[sonstiges]; /* Mögliche Leerzeichen werden am Ende de Schleide übersprungen. */ /* Und dann einfach weiter machen */ /* UNKLASSIFIZIERT ==============*/ // Revoir cas ' ' et '}' #ifndef MAC_UI } else if (akt == '\n') { // Sollte nicht mehr passieren #else } else if (akt == '\r') { //Debugger(); #endif /* Linie Aufzählung */ currLine++; } else if (akt != ' ' && akt != '\t') { /* Fehler */ #ifdef DEBUG Debugger(); #endif printf("Fehler in akt Identifizierung : %c!\n",akt); if (akt == ' ') { printf("Blanc not suppressed by %s\n", Eingang+indexEin); #ifdef DEBUG Debugger(); #endif } Modus = ModeFields[sonstiges]; } else { /* DAMIT AUFPASSEN */ // if (akt != ' ' && akt != '{') { /* Zustand merken (Leerzeichen ändert ihn nicht) */ // Modus = variable; // } /* Tests mit den parametern */ if(akt == '\0') { /* Ende der Eingabe erreicht. */ } } /* Nächstes Symbol einlesen. */ akt = Eingang[indexEin++]; SUPP_BLANC } /* Ende der Hauptschleife */ /*==================*/ #ifdef DEBUG printf("Auslesen des Eingangs beendet\n"); #endif /* Den Puffer leeren. */ emptyStack(pufferStart); /* Jetzt steht indexEin auf den Charakter gerade nach der } des ausgelesenen Satzes */ #ifdef DEBUG printf("%s",Ausgang); scanf("%c",&dumy); #endif } /* Parsende Funktion fuer Boolean Setze : Postkonditionnen : akt beinhaltet das letzte ) Zeichen der Boolesche Expression. indexEin steht auf des Zeichen danach. ==========================================*/ #ifndef EXT_FOR void parseBool(void) { #else /* In the normal call made to parse the condition of if or while control structures, by starting with the beginning ( and stopping on the corresponding ) by counting the ( and ). Otherwise it is used to parse the stopping condition of the for loops for(;;). Postkonditionnen : akt beinhaltet das ';' und indexEin steht auf das Zeichen danach. */ #ifdef Mac void parseBool(Boolean stopOnSmiCol) { #else void parseBool(bool stopOnSmiCol) { #endif #endif /* Wir stehen gerade nach der ( die den Satz beginnt. Bis zu letzten ) lesen. */ /* Zustand des operanden Puffers speichern. Beim Verlassen muss bis dahin wieder geleert werden */ long pufferStart = indexPuffer; long lgPuffer; /* Zur Konvertierung der Nr der Globalen Variable */ int BoolKlam = 0; /* Anzahl der eingeschachtelten Klammern */ #ifdef MIT_VAR unsigned long varindex = 0; /* Um eine eingelesener Name an den in der Tabelle schon vorhandenen Variablen zu vergleichen */ #endif unsigned int oldIndex; /* Um beim auslesen eines - zu wissen ob es Substrahierung oder ein Minus Zeichen handelt */ int BModus = ModeFields[sonstiges]; #ifdef EXT_FOR if(!stopOnSmiCol) #endif akt = Eingang[indexEin++]; oldIndex = 0; /* Hauptschleife : =============*/ do { #ifdef DEBUG // Safety check if (oldIndex == indexEin) Debugger(); #endif oldIndex = indexEin; if(akt == '+' || /* 43 */ akt == '-' || /* 45 */ akt == '*' || /* 42 */ akt == '/' || /* 47 */ akt == '^') { /* */ /* BINÄRER OPERATOR ================*/ /* Operator mit 2 Operanden Prioritat des Operators suchen. */ operation normOp; #ifdef OPERAT_EQ if ('=' != Eingang[indexEin]) { #endif #ifndef EXT_FOR if (!(ModeFields[opernd] & BModus) && !((akt=='+' || akt=='-') && (BModus & (ModeFields[operatr]|ModeFields[sonstiges])))) { #else if (!(ModeFields[opernd] & BModus) && !((akt=='+'||akt=='-') && (BModus & (ModeFields[operatr]|ModeFields[sonstiges]))) && !(akt == '+' && Eingang[indexEin] == '+') && !(akt == '-' && Eingang[indexEin] == '-')) { #endif // Error printf("%d Falscher Bool Zustand bei %c %s!\n",(Graphs + numGraphs)->GraphicID, akt, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } #ifdef EXT_FOR // If parsing mode is operator, the + or - signs may be part of the operand in form of a pre inc/derementation if ((ModeFields[operatr]|ModeFields[sonstiges]) & BModus && akt == '+' && Eingang[indexEin] == '+') { // Get name of variable indexFunktion = 0; akt = Eingang[++indexEin]; ++indexEin; while(akt >= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_') { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } /* STAND !! akt beinhaltet das erste Zeichen nach dem wort. indexEin steht auf den zweitnächste Buchstabe nach dem Ende des Wortes. Nicht die } verpassen. Die Ausleseung des daraufolgendes Zeichens am Ende der Schleifen darf nicht ausgeführt werden. Dies wird für alle Fälle der Zeichen Identifizierung sein !!! */ SUPP_BLANC Funktion[indexFunktion] = '\0'; // Get index of variable in variable table. Variable must already exist varindex = 0; while (varindexnom,Funktion)) { varindex++; } if (varindex>=nbVar) { // Error printf("%d ++ operator for non defined variable %s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // Store incrementation operator (Fonction + nbFonctions)->cmd = incVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; // And the reading of its value (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; /* Zustand merken */ BModus = ModeFields[variable] | ModeFields[opernd]; continue; } else if ((ModeFields[operatr]|ModeFields[sonstiges]) & BModus && akt == '-' && Eingang[indexEin] == '-') { // Get name of variable indexFunktion = 0; akt = Eingang[++indexEin]; ++indexEin; while(akt >= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_') { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } /* STAND !! akt beinhaltet das erste Zeichen nach dem wort. indexEin steht auf den zweitnächste Buchstabe nach dem Ende des Wortes. Nicht die } verpassen. Die Ausleseung des daraufolgendes Zeichens am Ende der Schleifen darf nicht ausgeführt werden. Dies wird für alle Fälle der Zeichen Identifizierung sein !!! */ SUPP_BLANC Funktion[indexFunktion] = '\0'; // Get index of variable in variable table. Variable must already exist varindex = 0; while (varindexnom,Funktion)) { varindex++; } if (varindex>=nbVar) { // Error printf("%d -- operator for non defined variable %s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // Store decrementation operator (Fonction + nbFonctions)->cmd = decVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; // And the reading of its value (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; /* Zustand merken */ BModus = ModeFields[variable] | ModeFields[opernd]; continue; } else { #endif switch (akt) { case '+': if (BModus & (ModeFields[opernd] | ModeFields[klamzu] | ModeFields[variable] | ModeFields[parameter])) { normOp = plus; #ifdef DEBUG printf("PB Fall +\n");fflush(stdout); #endif } else { // Unary operator. Nothing to do normOp = 0xFF; // !normOp is unsigned! } break; case '-': if (BModus & (ModeFields[opernd] | ModeFields[klamzu] | ModeFields[variable] | ModeFields[parameter])) { normOp = minus; #ifdef DEBUG printf("PB Fall -\n");fflush(stdout); #endif } else { normOp = chsg; #ifdef DEBUG printf("PB Fall -(chs)\n");fflush(stdout); #endif } break; case '*': normOp = mult; #ifdef DEBUG printf("PB Fall *\n");fflush(stdout); #endif break; case '/': normOp = _div; #ifdef DEBUG printf("PB Fall /\n");fflush(stdout); #endif break; case '^': normOp = expos; #ifdef DEBUG printf("Fall ^\n");fflush(stdout); #endif break; default : printf("Fehler in PB bei binärer Operator %c\n",akt); BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } if (normOp != 0xFF) { /* Operatoren mit höherer Priorität aus dem Puffer nehmen und Tabelle der Funktionsaufrufe laden. */ emptyPrioOps(Precedences[normOp]); /* Operator selbst auf dem Stack ablegen. */ (Puffer + indexPuffer)->Typ = 2; // 2 A REVOIR (Puffer + indexPuffer)->Kommando = normOp; indexPuffer++; /* Zustand merken */ BModus = ModeFields[operatr]; } /* Mögliche Leerzeichen überspringen */ akt = Eingang[indexEin++]; SUPP_BLANC continue; #ifdef EXT_FOR } #endif #ifdef OPERAT_EQ } else { // Check that a variable has last been read out if (!(BModus & ModeFields[variable])) { // Error printf("%d Falscher Bool Zustand bei %c %s!\n",(Graphs + numGraphs)->GraphicID, akt, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } // = Zeichen überspringen indexEin++; // Put operator to get value of variable onto the stack // Funktion and varindex still hold name and index of the variable /* Wert auslesen speichern !! schon beim auslesen der Variabel erledigt (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; */ #ifdef DEBUG strcat(Ausgang,Funktion); strcat(Ausgang," Eval "); #endif /* Den Wertzuweisungs Operator auf den Stack legen */ (Puffer + indexPuffer)->Typ = 3; (Puffer + indexPuffer)->Bool = bassign; (Puffer + indexPuffer)->VarPos = varindex; indexPuffer++; /* Den mit = kombinieren Operator auf dem Stack legen */ switch (akt) { case '+': normOp = plusEq; #ifdef DEBUG printf("PB Fall +\n");fflush(stdout); #endif break; case '-': normOp = minusEq; #ifdef DEBUG printf("PB Fall -\n");fflush(stdout); #endif break; case '*': normOp = multEq; #ifdef DEBUG printf("PB Fall *\n");fflush(stdout); #endif break; case '/': normOp = _divEq; #ifdef DEBUG printf("PB Fall /\n");fflush(stdout); #endif break; case '^': normOp = exposEq; #ifdef DEBUG printf("Fall ^\n");fflush(stdout); #endif break; default : printf("%d Fehler in PB bei binärer Operator %c\n",(Graphs + numGraphs)->GraphicID,akt); /* Zustand merken */ BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Operatoren mit höherer Priorität aus dem Puffer nehmen und Tabelle der Funktionsaufrufe laden. */ emptyPrioOps(Precedences[normOp]); /* Operator selbst auf dem Stack ablegen. */ (Puffer + indexPuffer)->Typ = 2; // 2 A REVOIR (Puffer + indexPuffer)->Kommando = normOp; indexPuffer++; /* Zustand merken. Wenn danach einen - gefunden wird dann ist es chs nicht minus */ BModus = ModeFields[operatr]; /* Zum nächsten Zeichen gehen */ akt = Eingang[indexEin++]; SUPP_BLANC continue; } #endif #if !defined(MAC_UI) || !defined(USE_ITL) } else if ((akt>=48 && akt<=57) || akt == '.') { /* 0-9 . */ #else } else if ((akt>=48 && akt<=57) || akt == decSeparat) { /* 0-9 . */ #endif /* NUMMER ========*/ #ifdef DEBUG printf("PB Fall 0-9 oder .\n");fflush(stdout); #endif if(!(BModus & (ModeFields[operatr]|ModeFields[sonstiges]))) { // Error printf("%d Falscher Bool Zustand bei Konstante %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Ganze Nummer auslesen. */ /* while((akt>=48 && akt<=57) || akt == 46) { toConvert[indexConvert++] = akt; akt = Eingang[indexEin++]; } */ /* akt Beinhaltet schon das Zeichen nach der Nr u. indexEin steht bereits ein Zeichen weiter */ /* akt beinhaltet der n”chste nicht bearbeitete Charakter. */ // indexEin--; indexConvert = 0; toConvert[indexConvert++] = akt; #if !defined(MAC_UI) || !defined(USE_ITL) while((Eingang[indexEin]>=48 && Eingang[indexEin]<=57) || Eingang[indexEin] == '.') { #else while((Eingang[indexEin]>=48 && Eingang[indexEin]<=57) || Eingang[indexEin] == decSeparat) { #endif toConvert[indexConvert++] = Eingang[indexEin++]; } /* indexEin zeigt jetzt auf das Zeichen nach dem Ausgelesenen Wort */ toConvert[indexConvert] = '\0'; /* Stand: indexEin zeigt auf Zeichen nach der Zahl */ operand = atof(toConvert); /* In der Tabelle der Funktion Referenzen laden. */ (Fonction + nbFonctions)->cmd = put; nbFonctions++; #ifndef ARG_DOUBLE (Fonction + nbFonctions)->dataf = (float)operand; nbFonctions += tailleFlottant; #else constValues[cntValues] = operand; (Fonction + nbFonctions)->idx = cntValues; ++cntValues; nbFonctions += tailleEntier; #endif #ifdef DEBUG /* Aufruf von diesen sprintf verursacht einen Crash unter MacOS */ // strcat(Ausgang,"%4.2f"); // sprintf(Ausgang,Ausgang,operand); strcat(Ausgang,toConvert); strcat(Ausgang," "); #endif /* Zustand merken */ BModus = ModeFields[opernd]; /* Mögliche Leerzeichen überspringen */ akt = Eingang[indexEin++]; SUPP_BLANC continue; } else if (akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122) { /* Buchstabe A-Z a-z */ /* WORT ======*/ /* Die hier benutzten Variablen muessen vorher schon existieren. */ #ifdef DEBUG printf("PB Fall Buchstabe 65-90 97-122\n");fflush(stdout); #endif // Macro for error checking when identifying a function call #ifdef DEBUG #define ErrorBoolCheck(fName) if (!((ModeFields[operatr]|ModeFields[sonstiges]) & BModus)) { \ printf("%d Kein Operator vor Bool Funktion %s %s!\n",(Graphs + numGraphs)->GraphicID, fName, Eingang+indexEin-1); \ Debugger(); \ BModus = ModeFields[sonstiges]; \ scanf("%c",&dumy); \ ExecError(); \ return; \ } #else #define ErrorBoolCheck(fName) if (!((ModeFields[operatr]|ModeFields[sonstiges]) & BModus)) { \ printf("%d Kein Operator vor Bool Funktion %s %s!\n",(Graphs + numGraphs)->GraphicID, fName, Eingang+indexEin-1); \ BModus = ModeFields[sonstiges]; \ scanf("%c",&dumy); \ ExecError(); \ return; \ } #endif /* Ganzer Name auslesen. */ /* while(akt >= 48 && akt <= 57 || akt >= 65 && akt <= 90 || akt >= 97 && akt <= 122 || akt == '_') { Funktion[indexFunktion++] = akt; akt = Eingang[indexEin++]; } */ /* Zustand: akt beinhaltet das Zeichen nach dem ausgelesenen Wort, und indexEin zeigt au das nächste. Um dieses Zeichen nicht zu verpassen*/ // indexEin--; indexFunktion = 0; Funktion[indexFunktion++] = akt; while(Eingang[indexEin] >= 48 && Eingang[indexEin] <= 57 || Eingang[indexEin] >= 65 && Eingang[indexEin] <= 90 || Eingang[indexEin] >= 97 && Eingang[indexEin] <= 122 || Eingang[indexEin] == '_') { Funktion[indexFunktion++] = Eingang[indexEin++]; } Funktion[indexFunktion++] = '\0'; /* Stand: indexEin zeigt jetzt auf das Zeichen nach dem ausgelesenen Wort */ akt = Eingang[indexEin++]; SUPP_BLANC #ifdef DEBUG printf("Identifizierung :%s.\n",Funktion);fflush(stdout); #endif /* Zuerst nach mathematische Systemfunktionen suchen. Diese haben höchste Priorität. Direct auf den Stack ablegen. */ (Puffer + indexPuffer)->Typ = 2; if (0 == strcmp("sqrt",Funktion)) { if (!((ModeFields[opernd]|ModeFields[sonstiges]) & BModus)) { // Second case is for beginning (or after { : recursive call) // Error printf("%d Kein Operator vor Bool Funktion %s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } (Puffer + indexPuffer)->Kommando = _sqrt; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; // A voir !!! } else if (0 == strcmp("exp",Funktion)) { ErrorBoolCheck("exp") (Puffer + indexPuffer)->Kommando = _exp; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("ln",Funktion)) { ErrorBoolCheck("ln") (Puffer + indexPuffer)->Kommando = _ln; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("sin",Funktion)) { ErrorBoolCheck("sin") (Puffer + indexPuffer)->Kommando = _sin; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("cos",Funktion)) { ErrorBoolCheck("cos") (Puffer + indexPuffer)->Kommando = _cos; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("tan",Funktion)) { ErrorBoolCheck("tan") (Puffer + indexPuffer)->Kommando = _tan; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("sinh",Funktion)) { ErrorBoolCheck("sinh") (Puffer + indexPuffer)->Kommando = _sinh; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("cosh",Funktion)) { ErrorBoolCheck("cosh") (Puffer + indexPuffer)->Kommando = _cosh; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("tanh",Funktion)) { ErrorBoolCheck("tanh") (Puffer + indexPuffer)->Kommando = _tanh; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("asin",Funktion)) { ErrorBoolCheck("asin") (Puffer + indexPuffer)->Kommando = _asin; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("acos",Funktion)) { ErrorBoolCheck("acos") (Puffer + indexPuffer)->Kommando = _acos; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } else if (0 == strcmp("atan",Funktion)) { ErrorBoolCheck("atan") (Puffer + indexPuffer)->Kommando = _atan; indexPuffer++; /* Zustand merken */ BModus = ModeFields[funktion] | ModeFields[operatr]; continue; } #define HandleOperat(aktOp) \ aktPrio = BoolPrec[aktOp]; \ emptyPrioOps(aktPrio); \ \ (Puffer + indexPuffer)->Typ = 3; \ (Puffer + indexPuffer)->Bool = aktOp; \ indexPuffer++; \ BModus = ModeFields[operatr]; \ continue; /* Operator Identifizieren. */ if (0 == strcmp("and",Funktion)) { aktPrio = BoolPrec[and]; /* Alle Operatoren die hˆhere Prioritˆ§t haben aus dem Puffer lesen und in der Tabelle der Funktionsaufrufe laden.*/ emptyPrioOps(aktPrio); /* Operator selbst auf dem Stack ablegen. */ (Puffer + indexPuffer)->Typ = 3; (Puffer + indexPuffer)->Bool = and; indexPuffer++; /* Zustand merken */ BModus = ModeFields[operatr]; continue; } else if (0 == strcmp("or",Funktion)) { HandleOperat(or) } else if (0 == strcmp("xor",Funktion)) { HandleOperat(xor) } else if (0 == strcmp("not",Funktion)) { HandleOperat(not) } else if (0 == strcmp("lth",Funktion)) { HandleOperat(lth) } else if (0 == strcmp("gth",Funktion)) { HandleOperat(gth) } else if (0 == strcmp("leth",Funktion)) { HandleOperat(leth) } else if (0 == strcmp("geth",Funktion)) { HandleOperat(geth) } else if (0 == strcmp("neq",Funktion)) { HandleOperat(neq) } else if (0 == strcmp("eq",Funktion)) { HandleOperat(eq) } else if (!strncmp(Funktion,"p_",2)) { /* GLOBALE VARIABLE ================*/ #ifdef DEBUG printf("PB globale Variable Fall : %s\n",Funktion); #endif if(!(BModus & (ModeFields[operatr]|ModeFields[sonstiges]))) { // second case when at beginning // Error printf("%d Falscher Bool Zustand bei Parameter %s %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } lgPuffer = atoi(Funktion+2); /* Auslesen der Globalen variable speichern */ (Fonction + nbFonctions)->cmd = readParam; (Fonction + nbFonctions+1)->idx = lgPuffer; nbFonctions+=2; #ifdef DEBUG strcat(Ausgang,Funktion); strcat(Ausgang," Read "); #endif /* Zustand merken */ BModus = ModeFields[parameter] | ModeFields[opernd]; #ifdef MIT_VAR } else { /* VARIABLE : ==========*/ #ifdef DEBUG printf("PB Variable Fall : %s\n",Funktion); #endif if(!(BModus & (ModeFields[operatr]|ModeFields[sonstiges]))) { // second case when at beginning // Error printf("%d Falscher Bool Zustand bei Variable %s!\n",(Graphs + numGraphs)->GraphicID, Funktion, Eingang+indexEin-1); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Variable Identifizierung */ varindex = 0; while (varindexnom,Funktion)) { varindex++; } /* Nach = Zeichen suchen und den arithmetischen Satz danach */ /* akt beinhaltet = und indexEin zeigt auf Zeichen nach folgendes Zeichen das !=' ' ist */ if (varindex>=nbVar) { /* Neue Variable erzeugen : ====================*/ strcpy((Valeurs + nbVar)->nom,Funktion); (Valeurs + nbVar)->valeur = 0; /* Zur Sicherheit */ varindex = nbVar; nbVar++; if (akt != '=') { /* Fehler : =======*/ printf("%d Neue Variable angegeben ohne Wert Zuweisung :%s!\n",(Graphs + numGraphs)->GraphicID,Funktion); /* Zustand merken */ BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } } /* Variable vorhanden und gefunden */ /* Testen ob es nicht eine Wert Affectation ist */ if (akt == '=') { /* Wert Zuweisung : ==============*/ /* Zuerst den Operanden Puffer leeren */ // emptyStack(); /* Den Wertzuweisungs Operator auf den Stack legen */ (Puffer + indexPuffer)->Typ = 3; (Puffer + indexPuffer)->Bool = bassign; (Puffer + indexPuffer)->VarPos = varindex; indexPuffer++; /* Zum nächsten Zeichen gehen */ akt = Eingang[indexEin++]; SUPP_BLANC /* Zustand merken. Wenn danch einen - gefunden wird dann ist es chs nicht minus */ BModus = ModeFields[operatr]; continue; } else { /* Wert auslesen : =============*/ /* Wert auslesen speichern */ (Fonction + nbFonctions)->cmd = getvar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; #ifdef EXT_FOR // Check if variable is not followed by incrementation or decrementation operator if (akt=='+' && Eingang[indexEin] == '+') { // Store incrementation operator (Fonction + nbFonctions)->cmd = incVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; ++indexEin; akt = Eingang[indexEin++]; } if (akt=='-' && Eingang[indexEin] == '-') { // Store decrementation operator (Fonction + nbFonctions)->cmd = decVar; (Fonction + nbFonctions+1)->idx = varindex; nbFonctions+=2; ++indexEin; akt = Eingang[indexEin++]; } #endif /* Zustand merken */ BModus = ModeFields[variable] | ModeFields[opernd]; #ifdef DEBUG strcat(Ausgang,Funktion); strcat(Ausgang," Eval "); #endif } } #else } else { /* Fehler */ printf("Fehler in Bool Operator Identifizierung %s\n",Funktion); BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } #endif #define HandleOperat2(aktOp) \ aktPrio = BoolPrec[aktOp]; \ emptyPrioOps(aktPrio); \ \ (Puffer + indexPuffer)->Typ = 3; \ (Puffer + indexPuffer)->Bool = aktOp; \ indexPuffer++; \ BModus = ModeFields[operatr]; } else if (akt == '=' && '=' == Eingang[indexEin]) { if (!(BModus & ModeFields[opernd])) { // Error printf("%d Falscher Bool Zustand bei Operator == %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } HandleOperat2(eq) indexEin++; akt = Eingang[indexEin++]; SUPP_BLANC continue; } else if (akt == '<') { if (!(BModus & ModeFields[opernd])) { // Error printf("%d Falscher Bool Zustand bei Operator < %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } if ('=' == Eingang[indexEin]) { HandleOperat2(leth) indexEin++; } else { HandleOperat2(lth) } akt = Eingang[indexEin++]; SUPP_BLANC continue; } else if (akt == '>') { if (!(BModus & ModeFields[opernd])) { // Error printf("%d Falscher Bool Zustand bei Operator > %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } if ('=' == Eingang[indexEin]) { HandleOperat2(geth) indexEin++; } else { HandleOperat2(gth) } akt = Eingang[indexEin++]; SUPP_BLANC continue; } else if (akt == '!') { if (!(BModus & (ModeFields[operatr]|ModeFields[sonstiges]))) { // Second case is for beginning of parsing // Error printf("%d Falscher Bool Zustand bei Operator ! %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } if ('=' == Eingang[indexEin]) { HandleOperat2(neq) indexEin++; } else { HandleOperat2(not) } akt = Eingang[indexEin++]; SUPP_BLANC continue; } else if (akt == 40) { /* '(' */ /* KLAMMER AUF ============*/ #ifdef DEBUG printf("PB Fall (\n"); #endif if (!((ModeFields[operatr]|ModeFields[sonstiges]) & BModus)) { // Second case is for beginning of parsing (or after { recursive call) // Error printf("%d Falscher Bool Zustand bei ( %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } BoolKlam++; /* Auf dem Stack ablegen */ (Puffer + indexPuffer)->Typ = 2; (Puffer + indexPuffer)->Kommando = klauf; indexPuffer++; /* Zustand merken */ BModus |= ModeFields[klamauf]; /* Mögliche Leerzeichen überspringen */ akt = Eingang[indexEin++]; SUPP_BLANC continue; } else if (akt == 41) { /* ')' */ /* KLAMMER ZU ===========*/ #ifdef DEBUG printf("PB Fall )\n"); #endif if (!(ModeFields[opernd] & BModus)) { // Second case is for beginning of parsing (or after { recursive call) // Error printf("%d Falscher Bool Zustand bei ) %s!\n",(Graphs + numGraphs)->GraphicID, Eingang+indexEin); #ifdef DEBUG Debugger(); #endif BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } /* Stack bis zum ( auslesen Mit dem Trick von emptyPrioOps */ emptyPrioOps(Precedences[klauf]-1); /* Die ( auch auslesen ( auch beseitigen (nur nicht für die Letzte da die erste nie auf dem Stack abgelegt wurde */ if (BoolKlam > 0) { if ((*(Puffer + indexPuffer-1)).Kommando == klauf) { indexPuffer--; BoolKlam--; } else { /* Fehler */ printf("%d Fehler in PB Fall ): ( nicht im Puffer gefunden sondern %d\n",(Graphs + numGraphs)->GraphicID,(*(Puffer + indexPuffer-1)).Kommando); BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } #ifndef EXT_FOR if (BoolKlam > 0) { #else if (BoolKlam > 0 || stopOnSmiCol) { #endif /* Mögliche Leerzeichen überspringen */ akt = Eingang[indexEin++]; SUPP_BLANC } continue; } /* Zustand merken */ BModus |= ModeFields[klamzu]; } else { /* FEHLER FALL ===========*/ /* Linie Aufzählung */ if (akt == '\n' || akt == '\r') { currLine++; #ifdef DEBUG Debugger(); #endif } else if (akt != ' ' && akt != '\t') { /* Fehler */ #ifdef DEBUG Debugger(); #endif printf("Fehler in Bool Satz mit %c\n",akt); printf("%s",Eingang +indexEin-5); BModus = ModeFields[sonstiges]; scanf("%c",&dumy); ExecError(); return; } if (akt == ' ') { printf("Blanc not suppressed by %s\n", Eingang+indexEin); #ifdef DEBUG Debugger(); #endif } /* Zustand merken */ BModus = ModeFields[sonstiges]; /* ACHTEN MIT OPERATOR CHS */ } #ifndef EXT_FOR } while(BoolKlam>0); /* Ende Hauptschleife */ #else } while((!stopOnSmiCol && BoolKlam>0) || (stopOnSmiCol && akt != ';')); /* Ende Hauptschleife */ #endif // Check: last element read out must be an operand if (!(BModus & ModeFields[opernd])) { // Error printf("%d Falscher Bool Zustand bei %c %s!\n",(Graphs + numGraphs)->GraphicID, akt, Eingang+indexEin); scanf("%c",&dumy); } #ifdef DEBUG printf("Vor leeren %d\n",indexPuffer); #endif /* Stack leeren */ emptyStack(pufferStart); } /* Token für die Felder der Datei lesen ------------------------------------*/ #ifndef ARG_DOUBLE typedef enum tokenType { GRAPHIK, ID, NAME, DATEI, PARAMETER, RESOLUTIONS, FORMEL, SPEICHER_KODE, SPEICHER_STACK } token; #else typedef enum tokenType { GRAPHIK, ID, NAME, DATEI, PARAMETER, RESOLUTIONS, FORMEL, SPEICHER_KODE, SPEICHER_STACK, SPEICHER_CONST } token; #endif /* Datei Parsende Funktion: Lex ähnlich liest sie die Datei Linie per Linie aus und gibt einen Token zurück Die Berechnugsformel wird in der Variable Eingang übergeben. -------------------------------------------------------------*/ token yybis2lex(void) { int idx; char DateiPuffer[100], *tmp; /* Datei Inhalt laden */ if (NULL != fgets(DateiPuffer,100,Datei)) { #ifdef DEBUG // printf("Ausgelesen :\n|%s|\n",DateiPuffer); #endif if(!strncmp("SPEICHER_KODE:",DateiPuffer,14)) { sscanf(DateiPuffer+14,"%d\n",&maxFonctions); return SPEICHER_KODE; } else if(!strncmp("SPEICHER_STACK:",DateiPuffer,15)) { sscanf(DateiPuffer+15,"%d\n",&maxArg); return SPEICHER_STACK; #ifdef ARG_DOUBLE } else if(!strncmp("SPEICHER_CONST:",DateiPuffer,15)) { #ifndef MAC_UI sscanf(DateiPuffer+15,"%d\n",&maxConst); #else for(idx=15; DateiPuffer[idx]>='0' && DateiPuffer[idx]<='9'; ++idx); DateiPuffer[14] = idx-14; StringToNum((unsigned char*)DateiPuffer+14, &maxConst); #endif return SPEICHER_CONST; #endif } else if(!strncmp("GRAPHIK:",DateiPuffer,8)) { nbFonctions = 0; #ifdef MIT_VAR nbVar = 1; /* Initial Variable Fehler nicht vergessen */ #endif #ifdef MIT_WHILE whileEinsch = 0; /* Eischachtelungsstufe der while Schleifen */ #endif #ifdef ARG_DOUBLE cntValues = 0; #endif return GRAPHIK; } else if(!strncmp("ID=>",DateiPuffer,4)) { sscanf(DateiPuffer+4,"%d\n",&(Graphs + numGraphs)->GraphicID); return ID; } else if(!strncmp("NAME=>",DateiPuffer,6)) { // Supprimer \n à la fin idx = strlen(DateiPuffer); if (DateiPuffer[idx-1] == '\r' || DateiPuffer[idx-1] == '\n') DateiPuffer[idx-1] = 0; strcpy((*(Graphs + numGraphs)).grphKey,DateiPuffer+6); return NAME; } else if(!strncmp("DATEI=>",DateiPuffer,7)) { // Supprimer \n à la fin idx = strlen(DateiPuffer); if (DateiPuffer[idx-1] == '\r' || DateiPuffer[idx-1] == '\n') DateiPuffer[idx-1] = 0; strcpy((*(Graphs + numGraphs)).lytFile,DateiPuffer+7); return DATEI; } else if(!strncmp("PARAMETER=>",DateiPuffer,11)) { sscanf(DateiPuffer+11,"%d\n",&(*(Graphs + numGraphs)).parmAnzahl); return PARAMETER; } else if(!strncmp("RESOLUTIONS=>",DateiPuffer,13)) { sscanf(DateiPuffer+13,"%f %f %f %f\n",(*(Graphs + numGraphs)).Resolution ,(*(Graphs + numGraphs)).Resolution+1 ,(*(Graphs + numGraphs)).Resolution+2 ,(*(Graphs + numGraphs)).Resolution+3); return RESOLUTIONS; } else if(!strncmp("FORMEL=>",DateiPuffer,8)) { /* Gesammte Formel kopieren */ // Nicht in parsen initialisieren denn diese wird recursiv aufgerufen !!!! indexEin = 0; Eingang[0] = '\0'; currLine = 0; #ifdef DEBUG indexAus = 0; Ausgang[0] = '\0'; #endif #ifdef EXT_FOR // Initialise stack counter for positions of loop arithmetic of for loops. numFor = -1; #endif #ifndef MAC_UI while((tmp = fgets(DateiPuffer,100,Datei)) != NULL && *tmp != '\n') { #else while((tmp = fgets(DateiPuffer,100,Datei)) != NULL && *tmp != '\r') { #endif strcat(Eingang,DateiPuffer); } #ifndef EXT_FOR parsen(); #else parsen(0x7FFFFFFF); #endif /* Speicher fuer die aufgebaute Funktionsreferenzen Liste allokieren */ // (*(Graphs + numGraphs)).Rechnung = (double(**)(void))malloc(nbFonctions * sizeof(double(*)(void))); (*(Graphs + numGraphs)).Rechnung = (Commande*)malloc(nbFonctions * sizeof(Commande)); if (NULL == (*(Graphs + numGraphs)).Rechnung) { printf("Error code allocation code %d\n", numGraphs); } /* Referenzen kopieren Hier koennte eine Optimierung des Kodes durchgefuehrt werden mit memcpy */ for (idx=0;idxvaleur = (Valeurs + idx)->valeur; strcpy(((*(Graphs + numGraphs)).Vars+idx)->nom,(Valeurs + idx)->nom); } (*(Graphs + numGraphs)).numVar = nbVar; #endif #ifdef ARG_DOUBLE /* Speicher fuer die Konstanten allokieren */ (*(Graphs + numGraphs)).Constants = (double*)malloc(cntValues*sizeof(double)); if (NULL == (*(Graphs + numGraphs)).Constants) { printf("Error constants allocation code %d\n", numGraphs); } for(idx=0; idx maxMsges) maxMsges = numMsges; // For next parsing numMsges = 0; #endif //Debugger(); if ( checkConsist(Graphs + numGraphs) ) { printf("Inconsistance graphe %d\n", numGraphs); } (numGraphs)++; return FORMEL; } else { if (0 != DateiPuffer[0]) printf("Problem mit :%s\n",DateiPuffer); return (token)(-1); } } else { // EOF erreicht return (token)(-1); } } /* Dieses Modul ist die obere Ebene des Auslesen der Datei. Es ruft nach und nach die Funktion yybis2lex auf um das nächste Token zu bekommen und überprüft etwas die Syntax. ---------------------------------------------------------------------------*/ int yybis2parse(void) { token altFeld = FORMEL; token neuFeld; token Sequenz[] = { FORMEL, GRAPHIK, ID, NAME, DATEI, PARAMETER, RESOLUTIONS }; /* Table pour les references sur les fonctions. */ neuFeld = yybis2lex(); if (SPEICHER_KODE != neuFeld) { // Fehler return -1; } Resa neuFeld = yybis2lex(); if (SPEICHER_STACK != neuFeld) { // Fehler return -1; } /* Table pour les arguments. */ Pile = (double*)malloc(maxArg*sizeof(double)); if(Pile == NULL) { printf("Allocation2 echouee\n"); free(Fonction); Fonction = NULL; #ifdef MIT_VAR Valeurs = NULL; #endif return 1; } #ifdef ARG_DOUBLE neuFeld = yybis2lex(); if (SPEICHER_CONST != neuFeld) { // Fehler return -1; } /* Table pour les arguments. */ /* Tableau pour les valeurs constantes */ constValues = (double*)malloc(maxConst*sizeof(double)); if (NULL == constValues) { printf("Allocation4 echouee\n"); free(Pile); free(Fonction); } #endif neuFeld = yybis2lex(); do { if (neuFeld != (token)(-1) && Sequenz[neuFeld] != altFeld) { // Pb /* Datei Schliessen */ fclose(Datei); return -1; } altFeld = neuFeld; neuFeld = yybis2lex(); } while (neuFeld != (token)(-1)); /* Datei Schliessen */ if (NULL != Datei) { fclose(Datei); } /* Test das zuletzt ein FORMEL Feld war */ if (altFeld != FORMEL) { // Pb return -1; } #ifdef MAC_UI SelectConsole(); #endif #ifdef DEBUG //printf("Groessen u long %d double %d float %d\n",tailleuLong,tailleDouble,tailleFlottant);fflush(stdout); printf("Parsing ended. Type return\n"); scanf("%c",&dumy); #else printf("Parsing ended\n"); #endif return 0; }