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

📄 parser.c

📁 一个词法分析器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Parser.c (C) 1990, Mark C. Peterson, CompuServe [70441,3353]
   All rights reserved.

   Code may be used in any program provided the author is credited
    either during program execution or in the documentation.  Source
    code may be distributed only in combination with public domain or
    shareware source code.  Source code may be modified provided the
    copyright notice and this message is left unchanged and all
    modifications are clearly documented.

    I would appreciate a copy of any work which incorporates this code,
    however this is optional.

    Mark C. Peterson
    405-C Queen St. Suite #181
    Southington, CT 06489
    (203) 276-9721
*/

/*      Chuck Ebbert (CompuServe [76306,1226] ) changed code marked 'CAE fp'    */
/*   for fast 387 floating-point math.  See PARSERA.ASM and PARSERFP.C */
/*   (13 Dec 1992.)  */
/* */
/*   Modified 12 July 1993 by CAE to fix crash when formula not found.  */

#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <time.h>
#include "mpmath.h"
#include "prototyp.h"


#ifdef WATCH_MP
double x1, y1, x2, y2;
#endif

enum MATH_TYPE MathType = D_MATH;
/* moved _LCMPLX and union ARg to mpmath.h -6-20-90 TIW */

/* PB 910417 added MAX_OPS and MAX_ARGS defines */
/* TW 960101 made all defines depend on MAX_OPS */

#define MAX_OPS 250
#define MAX_ARGS 100
#define MAX_BOXX 8192  /* max size of boxx array */

unsigned Max_Ops  = MAX_OPS;
unsigned Max_Args = MAX_ARGS;

struct PEND_OP {
   void (far *f)(void);
   int p;
};
/* CAE fp added MAX_STORES and LOADS */
/* MAX_STORES must be even to make Unix alignment work */
/* TW made dependent on Max_Ops */

#define MAX_STORES ((Max_Ops/4)*2)  /* at most only half the ops can be stores */
#define MAX_LOADS  ((unsigned)(Max_Ops*.8))  /* and 80% can be loads */

/* PB 901103 made some of the following static for safety */
static struct PEND_OP far *o;

static void parser_allocate(void);

union Arg *Arg1, *Arg2;
/* PB 910417 removed unused "a" array */

/* CAE fp  made some of the following non-static for PARSERA.ASM */
/* Some of these variables should be renamed for safety */
union Arg s[20], far * far *Store, far * far *Load;     /* static CAE fp */
int StoPtr, LodPtr, OpPtr;      /* static CAE fp */

void (far * far *f)(void) = (void(far * far *)(void))0; /* static CAE fp */

unsigned posp, vsp, LastOp;     /* CAE fp made non-static */
static unsigned n, ErrPtr, NextOp, InitN;
static int paren, SyntaxErr, ExpectingArg;
struct ConstArg far *v = (struct ConstArg far *)0;      /* was static CAE fp */
int InitLodPtr, InitStoPtr, InitOpPtr, LastInitOp;      /* was static CAE fp */
static int Delta16;
double fgLimit;           /* TIW 05-04-91 */
static double fg;
static int ShiftBack;     /* TIW 06-18-90 */
static int SetRandom;     /* MCP 11-21-91 */
static int Randomized;
static unsigned long RandNum;
int uses_p1, uses_p2, uses_p3;

#ifndef XFRACT
#define ChkLongDenom(denom)\
    if (denom == 0 || (overflow && save_release > 1920)) {\
        overflow = 1;\
        return;\
    }
#endif

#define ChkFloatDenom(denom)\
    if (fabs(denom) <= DBL_MIN) {\
        overflow = 1;\
        return;\
    }

#ifndef TESTING_MATH
#define dShiftx dx1[row]
#define dShifty dy1[col]
#define lShiftx lx1[row]
#define lShifty ly1[col]
#else
#define dShiftx 0.0
#define dShifty 0.0
#define lShiftx 0L
#define lShifty 0L
#endif

#define LastSqr v[4].a

#if (_MSC_VER >= 700)
#pragma code_seg ("parser1_text")     /* place following in an overlay */
#endif

#define NO_MATCH_RIGHT_PAREN                       8
#define NO_LEFT_BRACKET_FIRST_LINE                 9
#define UNEXPECTED_EOF                            10
#define INVALID_SYM_USING_NOSYM                   11
#define FORMULA_TOO_LARGE                         12
#define INSUFFICIENT_MEM_FOR_TYPE_FORMULA         13
#define COULD_NOT_OPEN_FILE_WHERE_FORMULA_LOCATED 14

static char far *ParseErrs(int which)
{
   int lasterr;
   static FCODE e0[] = {"Should be an Argument"};
   static FCODE e1[] = {"Should be an Operator"};
   static FCODE e2[] = {"')' needs a matching '('"};
   static FCODE e3[] = {"Need more ')'"};
   static FCODE e4[] = {"Undefined Operator"};
   static FCODE e5[] = {"Undefined Function"};
   static FCODE e6[] = {"More than one ','"};
   static FCODE e7[] = {"Table overflow"};
   static FCODE e8[] = {"Didn't find matching ')'"};
   static FCODE e9[] = {"No '{' found on first line"};
   static FCODE e10[] = {"Unexpected EOF!"};
   static FCODE e11[] = {"Invalid symmetry declared, will use NOSYM"};
   static FCODE e12[] = {"Formula is too large"};
   static FCODE e13[] = {"Insufficient memory to run fractal type 'formula'"};
   static FCODE e14[] = {"Could not open file where formula located"};
   static FCODE e15[] = {"Invalid ParseErrs code"}; /* last one */
   static FCODE * far ErrStrings[] = 
     {e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15};
   lasterr = sizeof(ErrStrings)/sizeof(ErrStrings[0]) - 1;
   if(which > lasterr)
     which = lasterr;
   return((char far *)ErrStrings[which]);
}

#if (_MSC_VER >= 700)
#pragma code_seg ()       /* back to normal segment */
#endif

/* use the following when only float functions are implemented to
   get MP math and Integer math */

#ifndef XFRACT
#define FUNCT
#ifdef FUNCT /* use function form save space - isn't really slower */
static void mStkFunct(void (*fct)(void))   /* call lStk via dStk */
{
   Arg1->d = MPC2cmplx(Arg1->m);
   (*fct)();
   Arg1->m = cmplx2MPC(Arg1->d);
}

static void lStkFunct(void (*fct)(void))   /* call lStk via dStk */
{
   double y;
   /*
      intermediate variable needed for safety because of
      different size of double and long in Arg union
   */
   y = (double)Arg1->l.y / fg;
   Arg1->d.x = (double)Arg1->l.x / fg;
   Arg1->d.y = y;
   (*fct)();
   if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) {
      Arg1->l.x = (long)(Arg1->d.x * fg);
      Arg1->l.y = (long)(Arg1->d.y * fg);
   }
   else
      overflow = 1;
}
#else  /* use Macro form for (?) greater speed */
  /* call lStk via dStk */
#define mStkFunct(fct)  \
   Arg1->d = MPC2cmplx(Arg1->m);\
   (*fct)();\
   Arg1->m = cmplx2MPC(Arg1->d);


/* call lStk via dStk */
#define lStkFunct(fct) {\
   double y;\
   y = (double)Arg1->l.y / fg;\
   Arg1->d.x = (double)Arg1->l.x / fg;\
   Arg1->d.y = y;\
   (*fct)();\
   if(fabs(Arg1->d.x) < fgLimit && fabs(Arg1->d.y) < fgLimit) {\
      Arg1->l.x = (long)(Arg1->d.x * fg);\
      Arg1->l.y = (long)(Arg1->d.y * fg);\
   }\
   else\
      overflow = 1;\
}


#endif

#endif

/* Random number code, MCP 11-21-91 */

unsigned long NewRandNum(void)
{
   return(RandNum = ((RandNum << 15) + rand15()) ^ RandNum);
}

void lRandom(void)
{
   v[7].a.l.x = NewRandNum() >> (32 - bitshift);
   v[7].a.l.y = NewRandNum() >> (32 - bitshift);
}

void dRandom(void)
{
   long x, y;

   /* Use the same algorithm as for fixed math so that they will generate
          the same fractals when the srand() function is used. */
   x = NewRandNum() >> (32 - bitshift);
   y = NewRandNum() >> (32 - bitshift);
   v[7].a.d.x = ((double)x / (1L << bitshift));
   v[7].a.d.y = ((double)y / (1L << bitshift));
}

#ifndef XFRACT
void mRandom(void)
{
   long x, y;

   /* Use the same algorithm as for fixed math so that they will generate
      the same fractals when the srand() function is used. */
   x = NewRandNum() >> (32 - bitshift);
   y = NewRandNum() >> (32 - bitshift);
   v[7].a.m.x = *fg2MP(x, bitshift);
   v[7].a.m.y = *fg2MP(y, bitshift);
}
#endif

void SetRandFnct(void)
{
   unsigned Seed;

   if(!SetRandom)
      RandNum = Arg1->l.x ^ Arg1->l.y;

   Seed = (unsigned)RandNum ^ (unsigned)(RandNum >> 16);
   srand(Seed);
   SetRandom = 1;

   /* Clear out the seed */
   NewRandNum();
   NewRandNum();
   NewRandNum();
}

void RandomSeed(void)
{
   time_t ltime;

   /* Use the current time to randomize the random number sequence. */
   time(&ltime);
   srand((unsigned int)ltime);

   NewRandNum();
   NewRandNum();
   NewRandNum();
   Randomized = 1;
}

#ifndef XFRACT
void lStkSRand(void)
{
   SetRandFnct();
   lRandom();
   Arg1->l = v[7].a.l;
}
#endif

#ifndef XFRACT
void mStkSRand(void)
{
   Arg1->l.x = Arg1->m.x.Mant ^ (long)Arg1->m.x.Exp;
   Arg1->l.y = Arg1->m.y.Mant ^ (long)Arg1->m.y.Exp;
   SetRandFnct();
   mRandom();
   Arg1->m = v[7].a.m;
}
#endif

void dStkSRand(void)
{
   Arg1->l.x = (long)(Arg1->d.x * (1L << bitshift));
   Arg1->l.y = (long)(Arg1->d.y * (1L << bitshift));
   SetRandFnct();
   dRandom();
   Arg1->d = v[7].a.d;
}

void (*StkSRand)(void) = dStkSRand;

void dStkAbs(void) {
   Arg1->d.x = fabs(Arg1->d.x);
   Arg1->d.y = fabs(Arg1->d.y);
}

#ifndef XFRACT
void mStkAbs(void) {
   if(Arg1->m.x.Exp < 0)
      Arg1->m.x.Exp = -Arg1->m.x.Exp;
   if(Arg1->m.y.Exp < 0)
      Arg1->m.y.Exp = -Arg1->m.y.Exp;
}

void lStkAbs(void) {
   Arg1->l.x = labs(Arg1->l.x);
   Arg1->l.y = labs(Arg1->l.y);
}
#endif

void (*StkAbs)(void) = dStkAbs;

void dStkSqr(void) {
   LastSqr.d.x = Arg1->d.x * Arg1->d.x;
   LastSqr.d.y = Arg1->d.y * Arg1->d.y;
   Arg1->d.y = Arg1->d.x * Arg1->d.y * 2.0;
   Arg1->d.x = LastSqr.d.x - LastSqr.d.y;
   LastSqr.d.x += LastSqr.d.y;
   LastSqr.d.y = 0;
}

#ifndef XFRACT
void mStkSqr(void) {
   LastSqr.m.x = *MPmul(Arg1->m.x, Arg1->m.x);
   LastSqr.m.y = *MPmul(Arg1->m.y, Arg1->m.y);
   Arg1->m.y = *MPmul(Arg1->m.x, Arg1->m.y);
   Arg1->m.y.Exp++;
   Arg1->m.x = *MPsub(LastSqr.m.x, LastSqr.m.y);
   LastSqr.m.x = *MPadd(LastSqr.m.x, LastSqr.m.y);
   LastSqr.m.y.Mant = (long)(LastSqr.m.y.Exp = 0);
}

void lStkSqr(void) {
   LastSqr.l.x = multiply(Arg1->l.x, Arg1->l.x, bitshift);
   LastSqr.l.y = multiply(Arg1->l.y, Arg1->l.y, bitshift);
   Arg1->l.y = multiply(Arg1->l.x, Arg1->l.y, bitshift) << 1;
   Arg1->l.x = LastSqr.l.x - LastSqr.l.y;
   LastSqr.l.x += LastSqr.l.y;
   LastSqr.l.y = 0L;
}
#endif

void (*StkSqr)(void) = dStkSqr;

void dStkAdd(void) {
   Arg2->d.x += Arg1->d.x;
   Arg2->d.y += Arg1->d.y;
   Arg1--;
   Arg2--;
}

#ifndef XFRACT
void mStkAdd(void) {
   Arg2->m = MPCadd(Arg2->m, Arg1->m);
   Arg1--;
   Arg2--;
}

void lStkAdd(void) {
   Arg2->l.x += Arg1->l.x;
   Arg2->l.y += Arg1->l.y;
   Arg1--;
   Arg2--;
}
#endif

void (*StkAdd)(void) = dStkAdd;

void dStkSub(void) {
   Arg2->d.x -= Arg1->d.x;
   Arg2->d.y -= Arg1->d.y;
   Arg1--;
   Arg2--;
}

#ifndef XFRACT
void mStkSub(void) {
   Arg2->m = MPCsub(Arg2->m, Arg1->m);
   Arg1--;
   Arg2--;
}

void lStkSub(void) {
   Arg2->l.x -= Arg1->l.x;
   Arg2->l.y -= Arg1->l.y;
   Arg1--;
   Arg2--;
}
#endif

void (*StkSub)(void) = dStkSub;

void dStkConj(void) {
   Arg1->d.y = -Arg1->d.y;
}

#ifndef XFRACT
void mStkConj(void) {
   Arg1->m.y.Exp ^= 0x8000;
}

void lStkConj(void) {
   Arg1->l.y = -Arg1->l.y;
}
#endif

void (*StkConj)(void) = dStkConj;

void dStkFloor(void) {
   Arg1->d.x = floor(Arg1->d.x);
   Arg1->d.y = floor(Arg1->d.y);
}

#ifndef XFRACT
void mStkFloor(void) {
   mStkFunct(dStkFloor);   /* call lStk via dStk */
}

void lStkFloor(void) {
   /* 
    * Kill fractional part. This operation truncates negative numbers 
    * toward negative infinity as desired.
    */
   Arg1->l.x = (Arg1->l.x) >> bitshift;
   Arg1->l.y = (Arg1->l.y) >> bitshift;
   Arg1->l.x = (Arg1->l.x) << bitshift;
   Arg1->l.y = (Arg1->l.y) << bitshift;
}
#endif

void (*StkFloor)(void) = dStkFloor;

void dStkCeil(void) {
   Arg1->d.x = ceil(Arg1->d.x);
   Arg1->d.y = ceil(Arg1->d.y);
}

#ifndef XFRACT
void mStkCeil(void) {
   mStkFunct(dStkCeil);   /* call lStk via dStk */
}

void lStkCeil(void) {
   /* the shift operation does the "floor" operation, so we 
      negate everything before the operation */
   Arg1->l.x = (-Arg1->l.x) >> bitshift;
   Arg1->l.y = (-Arg1->l.y) >> bitshift;
   Arg1->l.x = -((Arg1->l.x) << bitshift);
   Arg1->l.y = -((Arg1->l.y) << bitshift);
}
#endif

void (*StkCeil)(void) = dStkCeil;

void dStkTrunc(void) {
   Arg1->d.x = (int)(Arg1->d.x);
   Arg1->d.y = (int)(Arg1->d.y);
}

#ifndef XFRACT
void mStkTrunc(void) {
   mStkFunct(dStkTrunc);   /* call lStk via dStk */
}

void lStkTrunc(void) {
   /* shifting and shifting back truncates positive numbers,
      so we make the numbers positive */
   int signx, signy;
   signx = sign(Arg1->l.x);
   signy = sign(Arg1->l.y);
   Arg1->l.x = labs(Arg1->l.x);
   Arg1->l.y = labs(Arg1->l.y);
   Arg1->l.x = (Arg1->l.x) >> bitshift;
   Arg1->l.y = (Arg1->l.y) >> bitshift;
   Arg1->l.x = (Arg1->l.x) << bitshift;
   Arg1->l.y = (Arg1->l.y) << bitshift;
   Arg1->l.x = signx*Arg1->l.x;
   Arg1->l.y = signy*Arg1->l.y;
}
#endif

void (*StkTrunc)(void) = dStkTrunc;

void dStkRound(void) {
   Arg1->d.x = floor(Arg1->d.x+.5);
   Arg1->d.y = floor(Arg1->d.y+.5);
}

#ifndef XFRACT
void mStkRound(void) {

⌨️ 快捷键说明

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