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

📄 sacalc.c

📁 WINDOW版的YACC編譯軟體
💻 C
字号:

# line 7 "sacalc.y"

#define YYSTYPE double    /* data type of yacc stack */
#define QUIT    ( (double) 101010 )

#define YYDEBUG

#define NUMBER 257
#define UNARYMINUS 258
#ifndef YYSTYPE
#define YYSTYPE int
#endif
YYSTYPE yylval, yyval;
#define YYERRCODE 256

# line 47 "sacalc.y"


#include <stdio.h>
#include <ctype.h>

char *progname;       /* for error messages */
int  lineno = 1;

extern int yyparse( void );

void main( int, char ** );
int  yylex( void );
void prompt( void );
void yyerror( char * );
void warning( char *, char * );

void
main( int argc, char **argv )
{
     if (argc > 1) fprintf(stderr, "nonmeaningful arguments\n");
     progname = *argv;

     fprintf(stdout, "\n****************************************************\n");
     fprintf(stdout, "*      SACALC: a Simple Arithmetic Calculator      *\n");
     fprintf(stdout, "*                                                  *\n");
     fprintf(stdout, "*      1)at the prompt READY>                      *\n");
     fprintf(stdout, "*        you type in an expression, e.g. 1+2*3<CR> *\n");
     fprintf(stdout, "*        SACALC will evaluate the expression       *\n");
     fprintf(stdout, "*        and the result is displayed               *\n");
     fprintf(stdout, "*      2)to terminate the program                  *\n");
     fprintf(stdout, "*        type QUIT                                 *\n");
     fprintf(stdout, "*      3)if you make a mistake                     *\n");
     fprintf(stdout, "*        SACALC will complain and start over again *\n");
     fprintf(stdout, "*                                                  *\n");
     fprintf(stdout, "****************************************************\n\n\n");
     yyparse();
     fprintf(stdout, "\n****************************************************\n");
     fprintf(stdout, "*       SACALC: a Simple Arithmetic Calculator     *\n");
     fprintf(stdout, "*                                                  *\n");
     fprintf(stdout, "*       normal termination -- bye!                 *\n");
     fprintf(stdout, "****************************************************\n");

}

int yylex( void )
{
     int c;

     while ((c=getchar()) == ' ' || c == '\t' )
          ;
     if (c == EOF)
         return 0;
     if (c == '.' || isdigit(c)) {          /* number */
         ungetc(c, stdin);
         scanf("%lf", &yylval);
         return NUMBER;
     }
     if (c == '\n')
         lineno++;
     if (c == 'Q' || c == 'q')              /* ugly code */
         if ((c=getchar()) == 'U' || c == 'u')
             if ((c=getchar()) == 'I' || c == 'i')
                 if ((c=getchar()) == 'T' || c == 't') {
                     yylval = QUIT;
                     return( EOF );
                 }
                 else return '?';
     return( c );
}
void
yyerror( char *s )             /* called for yacc syntax error */
{
     warning(s, (void *) 0);
}

void
warning( char *s, char *t )            /* print warning message */
{
    fprintf(stderr, "%s: %s", progname, s);

    if (t) fprintf(stderr, " %s", t);

    fprintf(stderr, " near line %d\n", lineno);
}

void
prompt( void )
{
  fprintf(stdout, "READY> ");
}

const int yyexca[] = {
  -1, 1,
  0, -1,
  -2, 0,
  0,
};

#define YYNPROD 12
#define YYLAST 248

const int yyact[] = {
       2,       7,      13,      20,      11,       9,       6,      10,
       8,      12,      11,       3,       1,       0,       0,      12,
       0,       0,      14,      15,       0,      16,      17,      18,
      19,       0,       0,       0,       0,       0,       7,       0,
       0,       0,       0,       6,       0,       0,       0,       0,
      11,       9,       0,      10,       0,      12,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       5,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       0,       0,
       0,       0,       0,       0,       0,       0,       4,       5,
};

const int yypact[] = {
   -4096,     -10,   -4096,      -2,      -8,   -4096,     -39,     -39,
   -4096,     -39,     -39,     -39,     -39,   -4096,   -4096,     -38,
     -32,     -32,   -4096,   -4096,   -4096,
};

const int yypgo[] = {
       0,      12,      11,
};

const int yyr1[] = {
       0,       1,       1,       1,       1,       2,       2,       2,
       2,       2,       2,       2,
};

const int yyr2[] = {
       0,       0,       2,       3,       3,       1,       2,       3,
       3,       3,       3,       3,
};

const int yychk[] = {
   -4096,      -1,      10,      -2,     256,     257,      45,      40,
      10,      43,      45,      42,      47,      10,      -2,      -2,
      -2,      -2,      -2,      -2,      41,
};

const int yydef[] = {
       1,      -2,       2,       0,       0,       5,       0,       0,
       3,       0,       0,       0,       0,       4,       6,       0,
       7,       8,       9,      10,      11,
};

/*****************************************************************/
/* PCYACC LALR parser driver routine -- a table driven procedure */
/* for recognizing sentences of a language defined by the        */
/* grammar that PCYACC analyzes. An LALR parsing table is then   */
/* constructed for the grammar and the skeletal parser uses the  */
/* table when performing syntactical analysis on input source    */
/* programs. The actions associated with grammar rules are       */
/* inserted into a switch statement for execution.               */
/*****************************************************************/


#ifndef YYMAXDEPTH
#define YYMAXDEPTH 200
#endif
#ifndef YYREDMAX
#define YYREDMAX 1000
#endif
#define PCYYFLAG -4096
#define WAS0ERR 0
#define WAS1ERR 1
#define WAS2ERR 2
#define WAS3ERR 3
#define yyclearin pcyytoken = -1
#define yyerrok   pcyyerrfl = 0
YYSTYPE yyv[YYMAXDEPTH];     /* value stack */
int pcyyerrct = 0;           /* error count */
int pcyyerrfl = 0;           /* error flag */
int redseq[YYREDMAX];
int redcnt = 0;
int pcyytoken = -1;          /* input token */


yyparse()
{
#ifdef YYSHORT
  const short *yyxi;
#else
  const int *yyxi;
#endif
#ifdef YYASTFLAG
    int ti; int tj;
#endif

#ifdef YYDEBUG
int tmptoken;
#endif
  int statestack[YYMAXDEPTH]; /* state stack */
  int      j, m;              /* working index */
  YYSTYPE *yypvt;
  int      tmpstate, *yyps, n;
  YYSTYPE *yypv;


  tmpstate = 0;
  pcyytoken = -1;


#ifdef YYDEBUG
  tmptoken = -1;
#endif


  pcyyerrct = 0;
  pcyyerrfl = 0;
  yyps = &statestack[-1];
  yypv = &yyv[-1];


  enstack:    /* push stack */
#ifdef YYDEBUG
    printf("at state %d, next token %d\n", tmpstate, tmptoken);
#endif
    if (++yyps - &statestack[YYMAXDEPTH-1] > 0) {
      yyerror("pcyacc internal stack overflow");
      return(1);
    }
    *yyps = tmpstate;
    ++yypv;
    *yypv = yyval;


  newstate:
    n = yypact[tmpstate];
    if (n <= PCYYFLAG) goto defaultact; /*  a simple state */


    if (pcyytoken < 0) if ((pcyytoken=yylex()) < 0) pcyytoken = 0;
    if ((n += pcyytoken) < 0 || n >= YYLAST) goto defaultact;


    if (yychk[n=yyact[n]] == pcyytoken) { /* a shift */
#ifdef YYDEBUG
      tmptoken  = pcyytoken;
#endif
      pcyytoken = -1;
      yyval = yylval;
      tmpstate = n;
      if (pcyyerrfl > 0) --pcyyerrfl;
      goto enstack;
    }


  defaultact:


    if ((n=yydef[tmpstate]) == -2) {
      if (pcyytoken < 0) if ((pcyytoken=yylex())<0) pcyytoken = 0;
      for (yyxi=yyexca; (*yyxi!= (-1)) || (yyxi[1]!=tmpstate); yyxi += 2);
      while (*(yyxi+=2) >= 0) if (*yyxi == pcyytoken) break;
      if ((n=yyxi[1]) < 0) { /* an accept action */
#ifdef YYASTFLAG
          yytfilep = fopen(yytfilen, "w");
          if (yytfilep == NULL) {
            fprintf(stderr, "Can't open t file: %s\n", yytfilen);
            return(0);          }
          for (ti=redcnt-1; ti>=0; ti--) {
            tj = svdprd[redseq[ti]];
            while (strcmp(svdnams[tj], "$EOP"))
              fprintf(yytfilep, "%s ", svdnams[tj++]);
            fprintf(yytfilep, "\n");
          }
          fclose(yytfilep);
#endif

        return (0);
      }
    }


    if (n == 0) {        /* error situation */
      switch (pcyyerrfl) {
        case WAS0ERR:          /* an error just occurred */
          yyerror("syntax error");
            ++pcyyerrct;
        case WAS1ERR:
        case WAS2ERR:           /* try again */
          pcyyerrfl = 3;
	   /* find a state for a legal shift action */
          while (yyps >= statestack) {
	     n = yypact[*yyps] + YYERRCODE;
	     if (n >= 0 && n < YYLAST && yychk[yyact[n]] == YYERRCODE) {
	       tmpstate = yyact[n];  /* simulate a shift of "error" */
	       goto enstack;
            }
	     n = yypact[*yyps];


	     /* the current yyps has no shift on "error", pop stack */
#ifdef YYDEBUG
            printf("error: pop state %d, recover state %d\n", *yyps, yyps[-1]);
#endif
	     --yyps;
	     --yypv;
	   }


	   yyabort:

#ifdef YYASTFLAG
              yytfilep = fopen(yytfilen, "w");
              if (yytfilep == NULL) {
                fprintf(stderr, "Can't open t file: %s\n", yytfilen);
                return(1);              }
              for (ti=1; ti<redcnt; ti++) {
                tj = svdprd[redseq[ti]];
                while (strcmp(svdnams[tj], "$EOP"))
                  fprintf(yytfilep, "%s ", svdnams[tj++]);
                fprintf(yytfilep, "\n");
              }
              fclose(yytfilep);
#endif

	     return(1);


	 case WAS3ERR:  /* clobber input char */
#ifdef YYDEBUG
          printf("error: discard token %d\n", pcyytoken);
#endif
          if (pcyytoken == 0) goto yyabort; /* quit */
	   pcyytoken = -1;
	   goto newstate;      } /* switch */
    } /* if */


    /* reduction, given a production n */
#ifdef YYDEBUG
    printf("reduce with rule %d\n", n);
#endif
#ifdef YYASTFLAG
    if ( redcnt<YYREDMAX ) redseq[redcnt++] = n;
#endif
    yyps -= yyr2[n];
    yypvt = yypv;
    yypv -= yyr2[n];
    yyval = yypv[1];
    m = n;
    /* find next state from goto table */
    n = yyr1[n];
    j = yypgo[n] + *yyps + 1;
    if (j>=YYLAST || yychk[ tmpstate = yyact[j] ] != -n) tmpstate = yyact[yypgo[n]];
    switch (m) { /* actions associated with grammar rules */
      
      case 1:
# line 23 "sacalc.y"
      { prompt(); } break;
      case 2:
# line 25 "sacalc.y"
      { prompt(); } break;
      case 3:
# line 27 "sacalc.y"
      { if (yypvt[-1] == QUIT) {
                    return(0);
                 } else {
                   fprintf(stdout, "       RESULT ==========> %.8g\n", yypvt[-1]);
                   prompt();
                 }
               } break;
      case 4:
# line 35 "sacalc.y"
      { yyerrok;
                   prompt();
                 } break;
      case 5:
# line 39 "sacalc.y"
      { yyval = yypvt[-0]; } break;
      case 6:
# line 40 "sacalc.y"
      { yyval = -yypvt[-0]; } break;
      case 7:
# line 41 "sacalc.y"
      { yyval = yypvt[-2] + yypvt[-0]; } break;
      case 8:
# line 42 "sacalc.y"
      { yyval = yypvt[-2] - yypvt[-0]; } break;
      case 9:
# line 43 "sacalc.y"
      { yyval = yypvt[-2] * yypvt[-0]; } break;
      case 10:
# line 44 "sacalc.y"
      { yyval = yypvt[-2] / yypvt[-0]; } break;
      case 11:
# line 45 "sacalc.y"
      { yyval = yypvt[-1]; } break;    }
    goto enstack;
}

⌨️ 快捷键说明

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