/***** * * Michael Riff * Object software version 1.0 Okto 2013. * * Diese Datei definiert die Initialisierung und Aufraümusgsroutinen zum Einlesen der Testdatei. * Zur Anzeige einer gespeicherten Berechnung ist die Routine Debug implementiert. * Zuletzt sind auch die Routinen definiert die die Gesammte Testdatei Einlesen. Um die Berechungen * einzulesen werden die Routinen in Parsers. cpp benutzt. * * Version 1.6: 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. *****/ #include #include //#include #include "Parser.h" //#include "OperandClasses.h" #include extern VarTableType *VarTable; extern int NumVars; GeneralOperand **Fonction; unsigned long numFunction; unsigned long maxFonctions; GeneralOperand *ParseArithmetic(); /* Datei die Ausgelesen wird */ FILE *Datei; int currLine = 0; char dumy; char *Entry; int IndxEntry; #ifdef DEBUG char *Ausgang; int indexAus; #endif extern Type_Erreur *Conversion; /* Fehler Wert Definierung Im Falle eines Fehlers während der Ausführung wird einen NAN Wert zurˆºckgegeben. */ extern double ValErr; int InitParse(void) { Entry = (char*)malloc(1400); if (NULL == Entry) { printf("Allocation buffer buffer entrée échouée\n"); return 1; } Entry[0] = '\0'; IndxEntry = 0; #ifdef DEBUG Ausgang = malloc(2000); if (NULL == Ausgang) { free(Entry); printf("Allocation buffer buffer debug échouée\n"); return 1; } Ausgang[0] = '\0'; indexAus = 0; #endif numGraphs = 0; aktGraphik = 0; #ifdef MIT_VAR // ToDo read size out of input file nbVar = 0; VarTable = (VarTableType*)malloc(50*sizeof(VarTableType)); if(VarTable == NULL) { free(Entry); #ifdef DEBUG free(Ausgang); #endif printf("Allocation3 echouee\n"); return 1; } /* Anlegen der Variable fuer Fehler Wert */ // ValErr = pow(2.0,64.0)-1; ValErr = pow(-1,0.5); // NAN Conversion = (Type_Erreur*)(&ValErr); Conversion->Brut[0] = 0x7FF00000; Conversion->Brut[1] = 0x00000001; VarTable->ActValue = ValErr; strcpy(VarTable->VarName,"Fehler"); NumVars = 1; #endif Datei = fopen("Text2.txt","r"); if(Datei == NULL) { printf("Fehler bei Datei oeffnen\n"); free(Entry); Entry = NULL; #ifdef DEBUG free(Ausgang); Ausgang = NULL; #endif #ifdef MIT_VAR free(VarTable); VarTable = NULL; #endif return 1; } numGraphs = 0; aktGraphik = 0; return 0; } void Quit(void) { free(Entry); #ifdef DEBUG free(Ausgang); #endif /* Ausgang */ #ifdef MIT_VAR if (VarTable != NULL) free(VarTable); #endif if (NULL != Fonction) free(Fonction); } void CleanUp(void) { int indx; if (Graphs != NULL) { /* Berechnugsformeln und Variablen der Graphiken */ for(indx=0;indxRechnung); #ifdef MIT_VAR free((Graphs+indx)->Vars); #endif } free(Graphs); } } /* Variables pour la conversion de nombres en texte ************************************************************/ #include Boolean quitter; EventRecord event; Point Cellule; short type; ControlHandle Controle; int idx; /* Fonctions et variables pour l'affichage de la fenˆtre dans lequel le code ˆ©xˆ©cutable va ˆtre affichˆ©. ************************************************************/ #include #define LARG_ASCENS 15 #define BORD 6 #define MARGE 20 extern OSErr erreur; Rect LogBounds; WindowPtr WinLog; ControlHandle Ascens; FontInfo infoTxt; TEHandle TextCode; Str63 numBuffer; Str63 TextLine; int visLines; /* Pour Debugger affichage du contenu de la liste d'instructions : =================================================*/ void Debug(void) { int idx; #ifdef MAC_UI GetFontInfo(&infoTxt); visLines = (int)floor(800.0 / (double)(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); // visLines = (short)floor(800.0 / ((*TextCode)->lineHeight + (*TextCode)->fontAscent)); SetRect(&LogBounds, 750, 50, 1100, 54+visLines*(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); // SetRect(&LogBounds, 100, 400, 1050, 400+visLines*((*TextCode)->lineHeight + (*TextCode)->fontAscent)); WinLog = NewWindow(NULL, &LogBounds, "\pLog", true, documentProc, (WindowPtr)-1, true, 0L); SetPort(WinLog); SetRect(&LogBounds, 350-LARG_ASCENS, 4, 350, 4+visLines*(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); Ascens = NewControl(WinLog, &LogBounds, "\p", true, 0, 0, 0, scrollBarProc, 0L); SetRect(&LogBounds, 0, 0, 1100-LARG_ASCENS,visLines*(infoTxt.ascent + infoTxt.descent + infoTxt.leading)); // En coordonn’àö¬©es locales InsetRect(&LogBounds, 4, 4); TextCode = TENew(&LogBounds, &(WinLog->portRect)); BlockMove("Code éxécutable de graphique: ", TextLine, 30); NumToString(aktGraphik, numBuffer); BlockMove(numBuffer+1, TextLine+30, numBuffer[0]); TextLine[30+numBuffer[0]] = '\r'; TESetText(TextLine, 31+numBuffer[0], TextCode); for (idx=0;idxPrint(TextCode); TEInsert(";\r", 2, TextCode); } TECalText(TextCode); SetCtlMin(Ascens, 0); SetCtlMax(Ascens, (*TextCode)->nLines-visLines); /* Boucle des ’àö¬©v’àö¬Ænements avec la fen’àö’Ñ¢tre des fichiers touch’àö¬©s ===============================================*/ quitter = false; do { WaitNextEvent(everyEvent, &event, 0xFFFFFFFF, 0L); switch(event.what) { case nullEvent: break; case keyDown: if ('q' == (event.message & charCodeMask)) quitter = true; break; case mouseDown: Cellule = event.where; GlobalToLocal(&Cellule); type = FindControl(Cellule, FrontWindow(), &Controle); if (0 != type) { idx = GetCtlValue(Controle); switch(type) { case kControlUpButtonPart: if (idx > 1) { idx = idx - 2; SetCtlValue(Controle, idx); TEScroll(0, 2 * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, 0); TEScroll(0, idx * (*TextCode)->lineHeight, TextCode); idx = 0; } break; case kControlDownButtonPart: if (idx < (*TextCode)->nLines-visLines) { idx = idx + 2; SetCtlValue(Controle, idx); TEScroll(0, -2 * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, (*TextCode)->nLines-visLines+1); TEScroll(0, -((*TextCode)->nLines-visLines-idx)* (*TextCode)->lineHeight, TextCode); idx = (*TextCode)->nLines-visLines; } break; case kControlPageUpPart: if (idx > visLines) { idx = idx - (visLines-1); SetCtlValue(Controle, idx); TEScroll(0, (visLines-1) * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, 0); TEScroll(0, idx * (*TextCode)->lineHeight, TextCode); idx = 0; } break; case kControlPageDownPart: if (idx < ((*TextCode)->nLines-2*visLines)) { idx = idx + (visLines-1); SetCtlValue(Controle, idx); TEScroll(0, -(visLines-1) * (*TextCode)->lineHeight, TextCode); } else { SetCtlValue(Controle, (*TextCode)->nLines-visLines); TEScroll(0, -((*TextCode)->nLines-visLines-idx)* (*TextCode)->lineHeight, TextCode); idx = (*TextCode)->nLines-visLines; } break; } Draw1Control(Ascens); } break; case updateEvt: BeginUpdate((WindowPtr)event.message); TEUpdate(&(FrontWindow()->portRect), TextCode); Draw1Control(Ascens); EndUpdate((WindowPtr)event.message); break; } } while (!quitter); // (*TextCode)->selStart = 0; // (*TextCode)->selEnd = (*TextLog)->teLength; TESetSelect(0, (*TextCode)->teLength,TextCode); TECopy(TextCode); erreur = ZeroScrap(); if (erreur) { NumToString(erreur, (unsigned char*)numBuffer); ParamText("\pInit presse papier:","\pNo", (unsigned char*)numBuffer, NULL); NoteAlert(128,NULL); } // Copier text vers presse-papier erreur = TEToScrap(); if (erreur) { NumToString(erreur, (unsigned char*)numBuffer); ParamText("\pCopie presse papier:","\pNo", (unsigned char*)numBuffer, NULL); NoteAlert(128,NULL); } TEDispose(TextCode); DisposeControl(Ascens); DisposeWindow(WinLog); #else for (idx=0;idxPrint(); printf(";\n"); } #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 Entry ˆº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",&idx); return SPEICHER_STACK; } else if(!strncmp("GRAPHIK:",DateiPuffer,8)) { #ifdef MIT_VAR NumVars = 1; /* Initial Variable Fehler nicht vergessen */ #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 !!!! IndxEntry = 0; Entry[0] = '\0'; #ifdef DEBUG indexAus = 0; Ausgang[0] = '\0'; #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((char*)Entry,DateiPuffer); } //Debugger(); numFunction = 0; do { Fonction[numFunction] = ParseArithmetic(); } while (Fonction[numFunction++]); numFunction--; /* Code Referenz speichern */ (*(Graphs + numGraphs)).Rechnung = (GeneralOperand**)malloc(numFunction*sizeof(GeneralOperand*)); if (NULL == (*(Graphs + numGraphs)).Rechnung) { printf("Error code allocation code %d\n", numGraphs); } memcpy((*(Graphs + numGraphs)).Rechnung, Fonction, numFunction*sizeof(GeneralOperand*)); (*(Graphs + numGraphs)).numFunctions = numFunction; #ifdef MIT_VAR /* Variablen Liste kopieren */ (*(Graphs + numGraphs)).Vars = (VarTableType*)malloc(NumVars * sizeof(VarTableType)); if (NULL == (*(Graphs + numGraphs)).Vars) { printf("Error variable allocation code %d\n", numGraphs); } for (idx=0;idx ActValue = (VarTable + idx)-> ActValue; strcpy(((*(Graphs + numGraphs)).Vars+idx)->VarName,(VarTable + idx)->VarName); } (*(Graphs + numGraphs)).numVar = NumVars; #endif //Debugger(); (numGraphs)++; return FORMEL; } else { if (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; } Fonction = (GeneralOperand**)malloc(maxFonctions*sizeof(GeneralOperand*)); if (!Fonction) { printf("Allocation for temporary code buffer failed\n"); Fonction = NULL; free(Entry); Entry = NULL; #ifdef DEBUG free(Ausgang); Ausgang = NULL; #endif #ifdef MIT_VAR free(VarTable); VarTable = NULL; #endif return 1; } neuFeld = yybis2lex(); if (SPEICHER_STACK != neuFeld) { // Fehler Fonction = NULL; #ifdef MIT_VAR VarTable = NULL; #endif return 1; } 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; } //printf("Groessen u long %d double %d float %d\n",tailleuLong,tailleDouble,tailleFlottant);fflush(stdout); #ifdef MAC_UI SelectConsole(); #endif #ifdef DEBUG printf("Parsing ended. Type return\n"); scanf("%c",&dumy); #else printf("Parsing ended\n"); #endif return 0; }