⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.c

📁 frasr200的win 版本源码(18.21),使用make文件,使用的vc版本较低,在我的环境下编译有问题! 很不错的分形程序代码!
💻 C
📖 第 1 页 / 共 4 页
字号:
            ExpectingArg = 1;
         }
         break;
      case '&':
         if(ExpectingArg)
            SyntaxErr = 0;
         ExpectingArg = 1;
         if(Str[n+1] == '&') {
            n++;
            o[posp].f = StkAND;
            o[posp++].p = 7 - (paren + Equals)*15;
         }
         else
            SyntaxErr = 4;
         break;
      case '!':
         if(Str[n+1] == '=') {
            if(ExpectingArg)
               SyntaxErr = 0;
            ExpectingArg = 1;
            n++;
            o[posp].f = StkNE;
            o[posp++].p = 6 - (paren + Equals)*15;
         }
         else
            SyntaxErr = 4;
         break;
      case '<':
         if(ExpectingArg)
            SyntaxErr = 0;
         ExpectingArg = 1;
         if(Str[n+1] == '=') {
            n++;
            o[posp].f = StkLTE;
         }
         else
            o[posp].f = StkLT;
         o[posp++].p = 6 - (paren + Equals)*15;
         break;
      case '>':
         if(ExpectingArg)
            SyntaxErr = 0;
         ExpectingArg = 1;
         if(Str[n+1] == '=') {
            n++;
            o[posp].f = StkGTE;
         }
         else
            o[posp].f = StkGT;
         o[posp++].p = 6 - (paren + Equals)*15;
         break;
      case '*':
         if(ExpectingArg)
            SyntaxErr = 0;
         ExpectingArg = 1;
         o[posp].f = StkMul;
         o[posp++].p = 3 - (paren + Equals)*15;
         break;
      case '/':
         if(ExpectingArg)
            SyntaxErr = 0;
         ExpectingArg = 1;
         o[posp].f = StkDiv;
         o[posp++].p = 3 - (paren + Equals)*15;
         break;
      case '^':
         if(ExpectingArg)
            SyntaxErr = 0;
         ExpectingArg = 1;
         o[posp].f = StkPwr;
         o[posp++].p = 2 - (paren + Equals)*15;
         break;
      case '=':
         if(ExpectingArg)
            SyntaxErr = 0;
         ExpectingArg = 1;
         if(Str[n+1] == '=') {
            n++;
            o[posp].f = StkEQ;
            o[posp++].p = 6 - (paren + Equals)*15;
         }
         else
         {
            o[posp-1].f = StkSto;
            o[posp-1].p = 5 - (paren + Equals)*15;
            Store[StoPtr++] = Load[--LodPtr];
            Equals++;
         }
         break;
      default:
         if(isalnum(Str[n]) || Str[n] == '.') {
            while(isalnum(Str[n+1]) || Str[n+1] == '.')
               n++;
            if(!ExpectingArg) {
               SyntaxErr = 1;
            }
            NewStatement = ExpectingArg = 0;
            Len = (n+1)-InitN;
            o[posp].f = isfunct(&Str[InitN], Len);
            if(o[posp].f != NotAFnct) {
               if(o[posp].f == FnctNotFound) {
                  e[ErrPtr].n = InitN;
                  e[ErrPtr++].s = 5;
               }
               else
                  o[posp++].p = 1 - (paren + Equals)*15;
               ExpectingArg = 1;
            }
            else {
               c = isconst(&Str[InitN], Len);
               Load[LodPtr++] = &(c->a);
               o[posp].f = StkLod;
               o[posp++].p = 1 - (paren + Equals)*15;
               n = InitN + c->len - 1;
               if(vsp >= MAX_ARGS-1) { /* PB 910417 safety test */
                  e[ErrPtr].n = InitN;
                  e[ErrPtr++].s = 7;
                  break;
               }
            }
         }
         else {
            if(ExpectingArg)
               SyntaxErr = 0;
            ExpectingArg = 1;
            e[ErrPtr].n = InitN;
            e[ErrPtr++].s = 4;
         }
         break;
      }
      if(SyntaxErr >= 0) {
         e[ErrPtr].n = InitN;
         e[ErrPtr++].s = SyntaxErr;
         SyntaxErr = -1;
      }
      if(posp >= MAX_OPS-1) { /* PB 901103 added safety test here */
         e[ErrPtr].n = InitN;
         e[ErrPtr++].s = 7;
         break;
      }
      if(ErrPtr > 50)         /* PB 910417 safety test */
         break;
   }

   o[posp].f = (void(far*)(void))0;
   o[posp++].p = 16;
   if(paren > 0) {
      e[ErrPtr].n = n;
      e[ErrPtr++].s = 3;
   }
   if (ErrPtr) {
      int i, j, k, m;
      char msgbuf[700];  /* PB replaced printf loop by build msgbuf & stopmsg */
      /* stopmsg defined to have max 9 lines, show at most first 3 errors */
      msgbuf[0] = 0;
      for(n = 0; n < ErrPtr && n < 3; n++) {
         if (n)
            strcat(msgbuf,"\n");
#ifndef XFRACT
         sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %Fs\n  ", e[n].s, /*TIW 03-31-91 added %Fs*/
            ErrStrings[e[n].s]);
#else
         sprintf(&msgbuf[strlen(msgbuf)], "Error(%d):  %s\n  ", e[n].s,
            ErrStrings[e[n].s]);
#endif
         j = 24;
         if ((i = e[n].n - j) < 0) {
            j = e[n].n;
            i = 0;
         }
         else {
            strcat(msgbuf,"...");
            j += 3;
         }
         k = strlen(msgbuf);
         m = i + 66;
         while (i < m && Str[i]) {
            if ((msgbuf[k] = Str[i]) == '\n' || msgbuf[k] == '\t')
               msgbuf[k] = ' ';
            ++i;
            ++k;
         }
         if (Str[i]) {
            msgbuf[k++] = '.';
            msgbuf[k++] = '.';
            msgbuf[k++] = '.';
         }
         msgbuf[k++] = '\n';
         while (--j >= -2)
            msgbuf[k++] = ' ';
         msgbuf[k++] = '^';
         msgbuf[k] = 0;
      }
      stopmsg(8,msgbuf);
   }
   if(!ErrPtr) {
      NextOp = 0;
      LastOp = posp;
      while(NextOp < posp) {
         if(o[NextOp].f)
            RecSortPrec();
         else {
            NextOp++;
            LastOp--;
         }
      }
   }
   else
      posp = 0;
   farmemfree(o);
   farmemfree(e);
   /* PB 910417 free all arrays if error */
   if (ErrPtr)
      free_workarea();
   return(ErrPtr);
}

int Formula(void) {
   if(FormName[0] == 0 || overflow) return(1);

   LodPtr = InitLodPtr;
   StoPtr = InitStoPtr;
   OpPtr = InitOpPtr;

   /* Set the random number, MCP 11-21-91 */
   if(SetRandom || Randomized)
   {
      switch(MathType)
      {
      case D_MATH:
         dRandom();
         break;
#ifndef XFRACT
      case L_MATH:
         lRandom();
         break;
      case M_MATH:
         mRandom();
#endif
      }
   }

   Arg1 = &s[0];
   Arg2 = Arg1-1;
   while(OpPtr < LastOp) {
      f[OpPtr++]();
#ifdef WATCH_MP
      x1 = *MP2d(Arg1->m.x);
      y1 = *MP2d(Arg1->m.y);
      x2 = *MP2d(Arg2->m.x);
      y2 = *MP2d(Arg2->m.y);
#endif
   }

   switch(MathType) {
   case D_MATH:
      old = new = v[3].a.d;
      return(Arg1->d.x == 0.0);
#ifndef XFRACT
   case M_MATH:
      old = new = MPC2cmplx(v[3].a.m);
      return(Arg1->m.x.Exp == 0 && Arg1->m.x.Mant == 0);
   case L_MATH:
      lold = lnew = v[3].a.l;
      if(overflow)
         return(1);
      return(Arg1->l.x == 0L);
#endif
   }
   return(1);
}

int form_per_pixel(void) {
   if (FormName[0] == 0) return(1);
   overflow = LodPtr = StoPtr = OpPtr = 0;
   Arg1 = &s[0];
   Arg2 = Arg1;
   Arg2--;
   if(Transparent3D)
   {
      TranspPerPixel(MathType, &v[5].a, &v[6].a);
      v[0].a = v[5].a;
   }
   else
   {
      switch(MathType)
      {
      case D_MATH:
         v[5].a.d.x = (v[0].a.d.x = dx0[col]+dShiftx);
         v[5].a.d.x = (v[0].a.d.y = dy0[row]+dShifty);
         break;
#ifndef XFRACT
      case M_MATH:
         v[5].a.m.x = (v[0].a.m.x = *d2MP(dx0[col]+dShiftx));
         v[5].a.m.x = (v[0].a.m.y = *d2MP(dy0[row]+dShifty));
         break;
      case L_MATH:
         v[5].a.l.x = (v[0].a.l.x = lx0[col]+lShiftx);
         v[5].a.l.x = (v[0].a.l.y = ly0[row]+lShifty);
         break;
#endif
      }
   }

   if(LastInitOp)
      LastInitOp = LastOp;
   while(OpPtr < LastInitOp)
      f[OpPtr++]();

   InitLodPtr = LodPtr;
   InitStoPtr = StoPtr;
   InitOpPtr = OpPtr;

   if(overflow)
      return(0);
   else
      return(1);
}

char *FormStr;

extern char FormFileName[];   /* BDT file to find the formulas in */
extern char FormName[];    /* BDT Name of the Formula (if not null) */

char *FindFormula(char *Str) {
   char *FormulaStr = (char *)0;
   char StrBuff[201];      /* PB, to match a safety fix in parser */
   /* MCP, changed to an automatic variable */
   char fullfilename[100]; /* BDT Full file name */
   unsigned Done;
   int c;
   FILE *File;

   findpath(FormFileName, fullfilename);  /* BDT get full path name */

   symmetry = 0;
   if((File = fopen(fullfilename, "rt")) != NULL) { /* BDT use variable files */
      while(StrBuff[0]=0,/* TIW 04-22-91 */ fscanf(File, "%200[^ \n\t({]", StrBuff) != EOF) {
         if(!stricmp(StrBuff, Str) || !Str[0]) {
            while((c = getc(File)) != EOF) {
               if(c == '(') {
                  StrBuff[0]=0; /* TIW 04-22-91 */
                  fscanf(File, "%200[^)]", StrBuff);
                  for(n = 0; SymStr[n].s[0]; n++) {
                     if(!stricmp(SymStr[n].s, StrBuff)) {
                        symmetry = SymStr[n].n;
                        break;
                     }
                  }
                  if(!SymStr[n].s[0]) {
                     sprintf(fullfilename,"Undefined symmetry:\n  %.76s",
                        StrBuff);
                     stopmsg(0,fullfilename); /* PB printf -> stopmsg */
                     FormulaStr = (char *)0;  /* PB 910511 */
Exit:
                     fclose(File);
                     return(FormulaStr);
                  }
               }
               else if(c == '{')
                  break;
            }

            /* MCP 4-9-91, Strip the comments inside the formula.  Might
                           as well allow unlimited formula lengths while
                           we're at it.
            */

            FormulaStr = boxx;
            n = Done = 0;
            while(!Done) {
               switch(c = getc(File)) {
                  static char far msg[]={"Unexpected EOF:  missing a '}'"};
               case EOF:
UnexpectedEOF:
                  stopmsg(0, msg);
                  FormulaStr = (char *)0;
                  goto Exit;
               case '}':
                  FormulaStr[n++] = 0;
                  Done = 1;
                  break;
               case ';':
                  while((c = getc(File)) != '\n') {
                     if(c == EOF)
                        goto UnexpectedEOF;
                  }
                  FormulaStr[n++] = ',';
                  break;
               case ' ':                     /* Also strip out the
                                                   white spaces */
                                    
               case '\t':
                  break;
               case '\n':
                  FormulaStr[n++] = ',';
                  break;
               default:
                  FormulaStr[n++] = c;
               }
               if (n >= 8192) { /* PB 4-9-91, added safety test */
                  static char far msg[]={"Definition too large, missing a '}'?"};
                  stopmsg(0, msg);
                  FormulaStr = (char *)0;
                  goto Exit;
               }
            }
            goto Exit;
         }

         StrBuff[0]=0;  /* TIW 04-22-91 */
         fscanf(File, "%200[ \n\t({]", StrBuff);
         if(StrBuff[strcspn(StrBuff, "({")]) {
skipcomments:
            fscanf(File, "%200[^}]", StrBuff);
            if (getc(File)!= '}') goto skipcomments;
         }
      }
      sprintf(fullfilename, "Formula \"%s\" not found", Str);
      stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
      FormulaStr = (char *)0;       /* PB 910511 */
      goto Exit;
   }
   sprintf(fullfilename, "Unable to open %s", FormFileName);
   stopmsg(0,fullfilename);      /* PB printf -> stopmsg */
   return((char *)0);            /* PB 910511 */
}

int BadFormula() {
   /*  moved from Parsera.Asm by CAE  12 July 1993  */

   /*  this is called when a formula is bad, instead of calling  */
   /*     the normal functions which will produce undefined results  */
   return 1;
}

int RunForm(char *Name) {  /*  returns 1 if an error occurred  */
   /*  CAE changed fn 12 July 1993 to fix problem when formula not found  */

   /*  first set the pointers so they point to a fn which always returns 1  */
   curfractalspecific->per_pixel = BadFormula;
   curfractalspecific->orbitcalc = BadFormula;

   if (FormName[0] == 0 ){
      return 1;  /*  and don't reset the pointers  */
   }

   parser_allocate();  /*  ParseStr() will test if this alloc worked  */

   if((FormStr = FindFormula(Name)) != NULL ){
      /*  formula was found  */
      if (ParseStr(FormStr)){
         /*  parse failed, don't change fn pointers  */
         return 1;
      }
      else {
         /*  parse succeeded so set the pointers back to good functions  */
         curfractalspecific->per_pixel = form_per_pixel;
         curfractalspecific->orbitcalc = Formula;
         return 0;
      }
   }
   else {
      /*  formula not found, leave pointers set to BadFormula  */
      return 1;                    /* PB, msg moved to FindFormula */
   }
}

int fpFormulaSetup(void) {
#ifndef XFRACT
   int RunFormRes;		/* CAE fp */

   if (fpu > 0) {
      MathType = D_MATH;
      /* CAE changed below for fp */
      RunFormRes = !RunForm(FormName); /* RunForm() returns 1 for failure */
      if (RunFormRes && fpu >=387 && debugflag != 90 )
         return CvtStk(); /* run fast assembler code in parsera.asm */
      return RunFormRes;
   }
   else {
      MathType = M_MATH;
      return !RunForm(FormName);
   }
#else
   MathType = D_MATH;
   return(!RunForm(FormName));
#endif
}

int intFormulaSetup(void) {
#ifdef XFRACT
      printf("intFormulaSetup called!!!\n");
      exit(-1);
#endif
      MathType = L_MATH;
      fg = (double)(1L << bitshift);
      fgLimit = (double)0x7fffffffL / fg;
      ShiftBack = 32 - bitshift;
      return(!RunForm(FormName));
   }


/* TIW added 06-20-90 so functions can be called from fractals.c */
void init_misc()
{
   static struct ConstArg far vv[5];
   static union Arg argfirst,argsecond;
   if(!v) /* PB 901103 added this test to avoid clobbering the real thing */
      v = vv;  /* this is needed by lStkSqr and dStkSqr */
   Arg1 = &argfirst; Arg2 = &argsecond; /* needed by all the ?Stk* functions */
   fg = (double)(1L << bitshift);
   fgLimit = (double)0x7fffffffL / fg;
   ShiftBack = 32 - bitshift;
   Delta16 = bitshift - 16;
   bitshiftless1 = bitshift-1;
}

/* PB 910417 here to end changed.
	Allocate sub-arrays from one main farmemalloc, using global variable
	typespecific_workarea; calcfrac.c releases this area when calculation
	ends or is terminated.
	Moved the "f" array to be allocated as part of this.
	*/

static void parser_allocate(void)
{
   /* CAE fp changed below for v18 */
   /* Note that XFRACT will waste about 6k here for pfls */
   /* Somewhat more memory is now allocated than in v17 here */
   /* however Store and Load were reduced in size to help make up for it */

   unsigned int f_size,Store_size,Load_size,v_size, p_size;
   free_workarea();
   f_size = sizeof(void(far * far *)(void)) * MAX_OPS;
   Store_size = sizeof(union Arg far *) * MAX_STORES;
   Load_size = sizeof(union Arg far *) * MAX_LOADS;
   v_size = sizeof(struct ConstArg) * MAX_ARGS;
   p_size = sizeof(struct fls far *) * MAX_OPS;
   typespecific_workarea =
   farmemalloc((long)(f_size+Load_size+Store_size+v_size+p_size));
   f = (void(far * far *)(void))typespecific_workarea;
   Store = (union Arg far * far *)(f + MAX_OPS);
   Load = (union Arg far * far *)(Store + MAX_STORES);
   v = (struct ConstArg far *)(Load + MAX_LOADS);
   pfls = (struct fls far *)(v + MAX_ARGS);
}

void free_workarea()
{
   if(typespecific_workarea) {
      farmemfree(typespecific_workarea);
      typespecific_workarea = NULL;
   }
   Store = (union Arg far * far *)0;
   Load = (union Arg far * far *)0;
   v = (struct ConstArg far *)0;
   f = (void(far * far *)(void))0;	/* CAE fp */
   pfls = (struct fls far * )0;   /* CAE fp */

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -