Category : Files from Magazines
Archive   : DDJ0689.ZIP
Filename : LANE.LST
by Alex Lane
[LISTING ONE]
yacc specification
/* TEST.Y
This specification is based largely on the yacc
specification for a simple desk calculator from "Compilers:
Principles, Techniques and Tools," by Aho, et al. (p. 259,
Addison-Wesley, 1986).
2/2/89 a.lane
*/
%{
#include
#include
%}
%token DIGIT
%left '+'
%left '*'
%%
line : /* nothing */
| expr '\n' { printf("%d\n", $1); }
;
expr : expr '+' term { $$ = $1 + $3; }
| term
;
term : term '*' factor { $$ = $1 * $3; }
| factor
;
factor: '(' expr ')' { $$ = $2; }
| DIGIT
;
%%
main() {
yyparse();
}
yylex() {
int c;
if ( isdigit( ( c = getchar() ) ) ) {
yylval = c - '0';
return DIGIT;
}
return c;
}
yyerror(s)
char *s;
{
fprintf(stderr, "PYERR: %s\n", s);
}
[LISTING TWO]
# line 11 "test.y"
#include
#include
#define DIGIT 257
#ifndef YYSTYPE
#define YYSTYPE int
#endif
YYSTYPE yylval, yyval;
#define YYERRCODE 256
# line 33 "test.y"
main() {
yyparse();
}
yylex() {
int c;
if ( isdigit( ( c = getchar() ) ) ) {
yylval = c - '0';
return DIGIT;
}
return c;
}
yyerror(s)
char *s;
{
fprintf(stderr, "PYERR: %s\n", s);
}
FILE *yytfilep;
char *yytfilen;
int yytflag = 0;
int svdprd[2];
char svdnams[2][2];
int yyexca[] = {
-1, 1,
0, -1,
-2, 0,
0,
};
#define YYNPROD 9
#define YYLAST 218
int yyact[] = {
5, 7, 13, 4, 8, 9, 3, 1,
2, 0, 0, 0, 0, 12, 10, 11,
4, 0, 3, 2, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 8, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 6,
};
int yypact[] = {
-40, -1000, -9, -37, -1000, -40, -1000, -1000,
-40, -40, -39, -37, -1000, -1000,
};
int yypgo[] = {
0, 7, 8, 6, 3,
};
int yyr1[] = {
0, 1, 1, 2, 2, 3, 3, 4,
4,
};
int yyr2[] = {
2, 0, 2, 3, 1, 3, 1, 3,
1,
};
int yychk[] = {
-1000, -1, -2, -3, -4, 40, 257, 10,
43, 42, -2, -3, -4, 41,
};
int yydef[] = {
1, -2, 0, 4, 6, 0, 8, 2,
0, 0, 0, 3, 5, 7,
};
int *yyxi;
/*****************************************************************/
/* 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 -1000
#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()
{
int statestack[YYMAXDEPTH]; /* state stack */
int j, m; /* working index */
YYSTYPE *yypvt;
int tmpstate, tmptoken, *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] > 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 */
if (yytflag) {
int ti; int tj;
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);
}
return (0);
}
}
if (n == 0) { /* error situation */
switch (pcyyerrfl) {
case WAS0ERR: /* an error just occurred */
yyerror("syntax error");
yyerrlab:
++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:
if (yytflag) {
int ti; int tj;
yytfilep = fopen(yytfilen, "w");
if (yytfilep == NULL) {
fprintf(stderr, "Can't open t file: %s\n", yytfilen);
return(1); }
for (ti=1; ti
while (strcmp(svdnams[tj], "$EOP"))
fprintf(yytfilep, "%s ", svdnams[tj++]);
fprintf(yytfilep, "\n");
}
fclose(yytfilep);
}
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
if (yytflag && redcnt
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 2:
# line 22 "test.y"
{ printf("%d\n", yypvt[-1]); } break;
case 3:
# line 24 "test.y"
{ yyval = yypvt[-2] + yypvt[-0]; } break;
case 5:
# line 27 "test.y"
{ yyval = yypvt[-2] * yypvt[-0]; } break;
case 7:
# line 30 "test.y"
{ yyval = yypvt[-1]; } break; }
goto enstack;
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/