📄 sacalc.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 + -