diff options
Diffstat (limited to 'usr.bin/yacc/tests')
34 files changed, 15082 insertions, 0 deletions
diff --git a/usr.bin/yacc/tests/Makefile b/usr.bin/yacc/tests/Makefile new file mode 100644 index 0000000..f8b7d85 --- /dev/null +++ b/usr.bin/yacc/tests/Makefile @@ -0,0 +1,41 @@ +# $FreeBSD$ + +TESTSDIR= ${TESTSBASE}/usr.bin/yacc + +TAP_TESTS_SH= legacy_test + +FILESDIR= ${TESTSDIR} +FILES= calc.y +FILES+= calc1.y +FILES+= calc2.y +FILES+= calc3.y +FILES+= code_calc.y +FILES+= code_error.y +FILES+= error.y +FILES+= ftp.y +FILES+= grammar.y +FILES+= pure_calc.y +FILES+= pure_error.y +FILES+= quote_calc.y +FILES+= quote_calc2.y +FILES+= quote_calc3.y +FILES+= quote_calc4.y +FILES+= regress.00.out +FILES+= regress.01.out +FILES+= regress.02.out +FILES+= regress.03.out +FILES+= regress.04.out +FILES+= regress.05.out +FILES+= regress.06.out +FILES+= regress.07.out +FILES+= regress.08.out +FILES+= regress.09.out +FILES+= regress.10.out +FILES+= regress.11.out +FILES+= regress.12.out +FILES+= regress.13.out +FILES+= regress.14.out +FILES+= regress.sh +FILES+= undefined.y + +.include <bsd.test.mk> diff --git a/usr.bin/yacc/tests/calc.y b/usr.bin/yacc/tests/calc.y new file mode 100644 index 0000000..c2e5a89 --- /dev/null +++ b/usr.bin/yacc/tests/calc.y @@ -0,0 +1,106 @@ +%{ +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +extern int yylex(void); +static void yyerror(const char *s); + +%} + +%start list + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr '+' expr + { $$ = $1 + $3; } + | expr '-' expr + { $$ = $1 - $3; } + | expr '*' expr + { $$ = $1 * $3; } + | expr '/' expr + { $$ = $1 / $3; } + | expr '%' expr + { $$ = $1 % $3; } + | expr '&' expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | '-' expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; base = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = base * $1 + $2; } + ; + +%% /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/calc1.y b/usr.bin/yacc/tests/calc1.y new file mode 100644 index 0000000..ec89736 --- /dev/null +++ b/usr.bin/yacc/tests/calc1.y @@ -0,0 +1,305 @@ +%{ + +/* http://dinosaur.compilertools.net/yacc/index.html */ + +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <math.h> + +typedef struct interval +{ + double lo, hi; +} +INTERVAL; + +INTERVAL vmul(double, double, INTERVAL); +INTERVAL vdiv(double, double, INTERVAL); + +extern int yylex(void); +static void yyerror(const char *s); + +int dcheck(INTERVAL); + +double dreg[26]; +INTERVAL vreg[26]; + +%} +%expect 18 + +%start line +%union +{ + int ival; + double dval; + INTERVAL vval; +} + +%token <ival> DREG VREG /* indices into dreg, vreg arrays */ +%token <dval> CONST /* floating point constant */ + +%type <dval> dexp /* expression */ +%type <vval> vexp /* interval expression */ + + /* precedence information about the operators */ + +%left '+' '-' +%left '*' '/' +%left UMINUS /* precedence for unary minus */ + +%% /* beginning of rules section */ + +lines : /* empty */ + | lines line + ; + +line : dexp '\n' + { + (void) printf("%15.8f\n", $1); + } + | vexp '\n' + { + (void) printf("(%15.8f, %15.8f)\n", $1.lo, $1.hi); + } + | DREG '=' dexp '\n' + { + dreg[$1] = $3; + } + | VREG '=' vexp '\n' + { + vreg[$1] = $3; + } + | error '\n' + { + yyerrok; + } + ; + +dexp : CONST + | DREG + { + $$ = dreg[$1]; + } + | dexp '+' dexp + { + $$ = $1 + $3; + } + | dexp '-' dexp + { + $$ = $1 - $3; + } + | dexp '*' dexp + { + $$ = $1 * $3; + } + | dexp '/' dexp + { + $$ = $1 / $3; + } + | '-' dexp %prec UMINUS + { + $$ = -$2; + } + | '(' dexp ')' + { + $$ = $2; + } + ; + +vexp : dexp + { + $$.hi = $$.lo = $1; + } + | '(' dexp ',' dexp ')' + { + $$.lo = $2; + $$.hi = $4; + if ( $$.lo > $$.hi ) + { + (void) printf("interval out of order\n"); + YYERROR; + } + } + | VREG + { + $$ = vreg[$1]; + } + | vexp '+' vexp + { + $$.hi = $1.hi + $3.hi; + $$.lo = $1.lo + $3.lo; + } + | dexp '+' vexp + { + $$.hi = $1 + $3.hi; + $$.lo = $1 + $3.lo; + } + | vexp '-' vexp + { + $$.hi = $1.hi - $3.lo; + $$.lo = $1.lo - $3.hi; + } + | dexp '-' vexp + { + $$.hi = $1 - $3.lo; + $$.lo = $1 - $3.hi; + } + | vexp '*' vexp + { + $$ = vmul( $1.lo, $1.hi, $3 ); + } + | dexp '*' vexp + { + $$ = vmul ($1, $1, $3 ); + } + | vexp '/' vexp + { + if (dcheck($3)) YYERROR; + $$ = vdiv ( $1.lo, $1.hi, $3 ); + } + | dexp '/' vexp + { + if (dcheck ( $3 )) YYERROR; + $$ = vdiv ($1, $1, $3 ); + } + | '-' vexp %prec UMINUS + { + $$.hi = -$2.lo; + $$.lo = -$2.hi; + } + | '(' vexp ')' + { + $$ = $2; + } + ; + +%% /* beginning of subroutines section */ + +#define BSZ 50 /* buffer size for floating point numbers */ + + /* lexical analysis */ + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) +{ + int c; + + while ((c = getchar()) == ' ') + { /* skip over blanks */ + } + + if (isupper(c)) + { + yylval.ival = c - 'A'; + return (VREG); + } + if (islower(c)) + { + yylval.ival = c - 'a'; + return (DREG); + } + + if (isdigit(c) || c == '.') + { + /* gobble up digits, points, exponents */ + char buf[BSZ + 1], *cp = buf; + int dot = 0, expr = 0; + + for (; (cp - buf) < BSZ; ++cp, c = getchar()) + { + + *cp = c; + if (isdigit(c)) + continue; + if (c == '.') + { + if (dot++ || expr) + return ('.'); /* will cause syntax error */ + continue; + } + + if (c == 'e') + { + if (expr++) + return ('e'); /* will cause syntax error */ + continue; + } + + /* end of number */ + break; + } + *cp = '\0'; + + if ((cp - buf) >= BSZ) + printf("constant too long: truncated\n"); + else + ungetc(c, stdin); /* push back last char read */ + yylval.dval = atof(buf); + return (CONST); + } + return (c); +} + +static INTERVAL +hilo(double a, double b, double c, double d) +{ + /* returns the smallest interval containing a, b, c, and d */ + /* used by *, / routines */ + INTERVAL v; + + if (a > b) + { + v.hi = a; + v.lo = b; + } + else + { + v.hi = b; + v.lo = a; + } + + if (c > d) + { + if (c > v.hi) + v.hi = c; + if (d < v.lo) + v.lo = d; + } + else + { + if (d > v.hi) + v.hi = d; + if (c < v.lo) + v.lo = c; + } + return (v); +} + +INTERVAL +vmul(double a, double b, INTERVAL v) +{ + return (hilo(a * v.hi, a * v.lo, b * v.hi, b * v.lo)); +} + +int +dcheck(INTERVAL v) +{ + if (v.hi >= 0. && v.lo <= 0.) + { + printf("divisor interval contains 0.\n"); + return (1); + } + return (0); +} + +INTERVAL +vdiv(double a, double b, INTERVAL v) +{ + return (hilo(a / v.hi, a / v.lo, b / v.hi, b / v.lo)); +} diff --git a/usr.bin/yacc/tests/calc2.y b/usr.bin/yacc/tests/calc2.y new file mode 100644 index 0000000..e742ff3 --- /dev/null +++ b/usr.bin/yacc/tests/calc2.y @@ -0,0 +1,120 @@ +%parse-param { int regs[26] } +%parse-param { int *base } + +%lex-param { int *base } + +%{ +# include <stdio.h> +# include <ctype.h> + +#ifdef YYBISON +#define YYLEX_PARAM base +#define YYLEX_DECL() yylex(int *YYLEX_PARAM) +#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s) +int YYLEX_DECL(); +static void YYERROR_DECL(); +#endif + +%} + +%start list + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr '+' expr + { $$ = $1 + $3; } + | expr '-' expr + { $$ = $1 - $3; } + | expr '*' expr + { $$ = $1 * $3; } + | expr '/' expr + { $$ = $1 / $3; } + | expr '%' expr + { $$ = $1 % $3; } + | expr '&' expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | '-' expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; (*base) = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = (*base) * $1 + $2; } + ; + +%% /* start of programs */ + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main (void) +{ + int regs[26]; + int base = 10; + + while(!feof(stdin)) { + yyparse(regs, &base); + } + return 0; +} + +static void +YYERROR_DECL() +{ + fprintf(stderr, "%s\n", s); +} + +int +YYLEX_DECL() +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = (c - '0') % (*base); + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/calc3.y b/usr.bin/yacc/tests/calc3.y new file mode 100644 index 0000000..252faa9 --- /dev/null +++ b/usr.bin/yacc/tests/calc3.y @@ -0,0 +1,123 @@ +%pure-parser + +%parse-param { int regs[26] } +%parse-param { int *base } + +%lex-param { int *base } + +%{ +# include <stdio.h> +# include <ctype.h> + +#ifdef YYBISON +#define YYSTYPE int +#define YYLEX_PARAM base +#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM) +#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s) +int YYLEX_DECL(); +static void YYERROR_DECL(); +#endif + +%} + +%start list + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr '+' expr + { $$ = $1 + $3; } + | expr '-' expr + { $$ = $1 - $3; } + | expr '*' expr + { $$ = $1 * $3; } + | expr '/' expr + { $$ = $1 / $3; } + | expr '%' expr + { $$ = $1 % $3; } + | expr '&' expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | '-' expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; (*base) = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = (*base) * $1 + $2; } + ; + +%% /* start of programs */ + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main (void) +{ + int regs[26]; + int base = 10; + + while(!feof(stdin)) { + yyparse(regs, &base); + } + return 0; +} + +static void +YYERROR_DECL() +{ + fprintf(stderr, "%s\n", s); +} + +int +YYLEX_DECL() +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + *yylval = (c - 'a'); + return ( LETTER ); + } + if( isdigit( c )) { + *yylval = (c - '0') % (*base); + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/code_calc.y b/usr.bin/yacc/tests/code_calc.y new file mode 100644 index 0000000..0a99456 --- /dev/null +++ b/usr.bin/yacc/tests/code_calc.y @@ -0,0 +1,112 @@ +%{ +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +#ifdef YYBISON +int yylex(void); +static void yyerror(const char *s); +#endif + +%} + +%start list + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr '+' expr + { $$ = $1 + $3; } + | expr '-' expr + { $$ = $1 - $3; } + | expr '*' expr + { $$ = $1 * $3; } + | expr '/' expr + { $$ = $1 / $3; } + | expr '%' expr + { $$ = $1 % $3; } + | expr '&' expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | '-' expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; base = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = base * $1 + $2; } + ; + +%% /* start of programs */ + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/code_error.y b/usr.bin/yacc/tests/code_error.y new file mode 100644 index 0000000..bb77156 --- /dev/null +++ b/usr.bin/yacc/tests/code_error.y @@ -0,0 +1,36 @@ +%{ + +#ifdef YYBISON +int yylex(void); +static void yyerror(const char *); +#endif + +%} +%% +S: error +%% + +#include <stdio.h> + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main(void) +{ + printf("yyparse() = %d\n", yyparse()); + return 0; +} + +int +yylex(void) +{ + return -1; +} + +static void +yyerror(const char* s) +{ + printf("%s\n", s); +} diff --git a/usr.bin/yacc/tests/error.y b/usr.bin/yacc/tests/error.y new file mode 100644 index 0000000..673c68d --- /dev/null +++ b/usr.bin/yacc/tests/error.y @@ -0,0 +1,28 @@ +%{ +int yylex(void); +static void yyerror(const char *); +%} +%% +S: error +%% + +#include <stdio.h> + +int +main(void) +{ + printf("yyparse() = %d\n", yyparse()); + return 0; +} + +int +yylex(void) +{ + return -1; +} + +static void +yyerror(const char* s) +{ + printf("%s\n", s); +} diff --git a/usr.bin/yacc/tests/ftp.y b/usr.bin/yacc/tests/ftp.y new file mode 100644 index 0000000..42c210b --- /dev/null +++ b/usr.bin/yacc/tests/ftp.y @@ -0,0 +1,1228 @@ +/* + * Copyright (c) 1985, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89 + */ + +/* + * Grammar for FTP commands. + * See RFC 959. + */ + +%{ + +/* sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89"; */ + +#include <sys/param.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <arpa/ftp.h> + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <signal.h> +#include <ctype.h> +#include <pwd.h> +#include <setjmp.h> +#include <syslog.h> +#include <sys/stat.h> +#include <string.h> +#include <time.h> +#include <assert.h> + +#ifdef YYBISON +int yylex(void); +static void yyerror(const char *); +#endif + +extern struct sockaddr_in data_dest; +extern int logged_in; +extern struct passwd *pw; +extern int guest; +extern int logging; +extern int type; +extern int form; +extern int debug; +extern int timeout; +extern int maxtimeout; +extern int pdata; +extern char hostname[], remotehost[]; +extern char proctitle[]; +extern char *globerr; +extern int usedefault; +extern int transflag; +extern char tmpline[]; + +extern char **glob(char *); +extern char *renamefrom(char *); +extern void cwd(const char *); + +extern void dologout(int); +extern void fatal(const char *); +extern void makedir(const char *); +extern void nack(const char *); +extern void pass(const char *); +extern void passive(void); +extern void pwd(void); +extern void removedir(char *); +extern void renamecmd(char *, char *); +extern void retrieve(const char *, const char *); +extern void send_file_list(const char *); +extern void statcmd(void); +extern void statfilecmd(const char *); +extern void store(char *, const char *, int); +extern void user(const char *); + +extern void perror_reply(int, const char *, ...); +extern void reply(int, const char *, ...); +extern void lreply(int, const char *, ...); + +static int cmd_type; +static int cmd_form; +static int cmd_bytesz; +char cbuf[512]; +char *fromname; + +struct tab { + const char *name; + short token; + short state; + short implemented; /* 1 if command is implemented */ + const char *help; +}; + +static char * copy(const char *); + +#ifdef YYBISON +static void sizecmd(char *filename); +static void help(struct tab *ctab, char *s); +struct tab cmdtab[]; +struct tab sitetab[]; +#endif + +static void +yyerror(const char *msg) +{ + perror(msg); +} +%} + +%token + A B C E F I + L N P R S T + + SP CRLF COMMA STRING NUMBER + + USER PASS ACCT REIN QUIT PORT + PASV TYPE STRU MODE RETR STOR + APPE MLFL MAIL MSND MSOM MSAM + MRSQ MRCP ALLO REST RNFR RNTO + ABOR DELE CWD LIST NLST SITE + STAT HELP NOOP MKD RMD PWD + CDUP STOU SMNT SYST SIZE MDTM + + UMASK IDLE CHMOD + + LEXERR + +%start cmd_list + +%% + +cmd_list: /* empty */ + | cmd_list cmd + { + fromname = (char *) 0; + } + | cmd_list rcmd + ; + +cmd: USER SP username CRLF + { + user((char *) $3); + free((char *) $3); + } + | PASS SP password CRLF + { + pass((char *) $3); + free((char *) $3); + } + | PORT SP host_port CRLF + { + usedefault = 0; + if (pdata >= 0) { + (void) close(pdata); + pdata = -1; + } + reply(200, "PORT command successful."); + } + | PASV CRLF + { + passive(); + } + | TYPE SP type_code CRLF + { + switch (cmd_type) { + + case TYPE_A: + if (cmd_form == FORM_N) { + reply(200, "Type set to A."); + type = cmd_type; + form = cmd_form; + } else + reply(504, "Form must be N."); + break; + + case TYPE_E: + reply(504, "Type E not implemented."); + break; + + case TYPE_I: + reply(200, "Type set to I."); + type = cmd_type; + break; + + case TYPE_L: +#if NBBY == 8 + if (cmd_bytesz == 8) { + reply(200, + "Type set to L (byte size 8)."); + type = cmd_type; + } else + reply(504, "Byte size must be 8."); +#else /* NBBY == 8 */ + UNIMPLEMENTED for NBBY != 8 +#endif /* NBBY == 8 */ + } + } + | STRU SP struct_code CRLF + { + switch ($3) { + + case STRU_F: + reply(200, "STRU F ok."); + break; + + default: + reply(504, "Unimplemented STRU type."); + } + } + | MODE SP mode_code CRLF + { + switch ($3) { + + case MODE_S: + reply(200, "MODE S ok."); + break; + + default: + reply(502, "Unimplemented MODE type."); + } + } + | ALLO SP NUMBER CRLF + { + reply(202, "ALLO command ignored."); + } + | ALLO SP NUMBER SP R SP NUMBER CRLF + { + reply(202, "ALLO command ignored."); + } + | RETR check_login SP pathname CRLF + { + if ($2 && $4 != 0) + retrieve((char *) 0, (char *) $4); + if ($4 != 0) + free((char *) $4); + } + | STOR check_login SP pathname CRLF + { + if ($2 && $4 != 0) + store((char *) $4, "w", 0); + if ($4 != 0) + free((char *) $4); + } + | APPE check_login SP pathname CRLF + { + if ($2 && $4 != 0) + store((char *) $4, "a", 0); + if ($4 != 0) + free((char *) $4); + } + | NLST check_login CRLF + { + if ($2) + send_file_list("."); + } + | NLST check_login SP STRING CRLF + { + if ($2 && $4 != 0) + send_file_list((char *) $4); + if ($4 != 0) + free((char *) $4); + } + | LIST check_login CRLF + { + if ($2) + retrieve("/bin/ls -lgA", ""); + } + | LIST check_login SP pathname CRLF + { + if ($2 && $4 != 0) + retrieve("/bin/ls -lgA %s", (char *) $4); + if ($4 != 0) + free((char *) $4); + } + | STAT check_login SP pathname CRLF + { + if ($2 && $4 != 0) + statfilecmd((char *) $4); + if ($4 != 0) + free((char *) $4); + } + | STAT CRLF + { + statcmd(); + } + | DELE check_login SP pathname CRLF + { + if ($2 && $4 != 0) + remove((char *) $4); + if ($4 != 0) + free((char *) $4); + } + | RNTO SP pathname CRLF + { + if (fromname) { + renamecmd(fromname, (char *) $3); + free(fromname); + fromname = (char *) 0; + } else { + reply(503, "Bad sequence of commands."); + } + free((char *) $3); + } + | ABOR CRLF + { + reply(225, "ABOR command successful."); + } + | CWD check_login CRLF + { + if ($2) + cwd(pw->pw_dir); + } + | CWD check_login SP pathname CRLF + { + if ($2 && $4 != 0) + cwd((char *) $4); + if ($4 != 0) + free((char *) $4); + } + | HELP CRLF + { + help(cmdtab, (char *) 0); + } + | HELP SP STRING CRLF + { + register char *cp = (char *)$3; + + if (strncasecmp(cp, "SITE", 4) == 0) { + cp = (char *)$3 + 4; + if (*cp == ' ') + cp++; + if (*cp) + help(sitetab, cp); + else + help(sitetab, (char *) 0); + } else + help(cmdtab, (char *) $3); + } + | NOOP CRLF + { + reply(200, "NOOP command successful."); + } + | MKD check_login SP pathname CRLF + { + if ($2 && $4 != 0) + makedir((char *) $4); + if ($4 != 0) + free((char *) $4); + } + | RMD check_login SP pathname CRLF + { + if ($2 && $4 != 0) + removedir((char *) $4); + if ($4 != 0) + free((char *) $4); + } + | PWD check_login CRLF + { + if ($2) + pwd(); + } + | CDUP check_login CRLF + { + if ($2) + cwd(".."); + } + | SITE SP HELP CRLF + { + help(sitetab, (char *) 0); + } + | SITE SP HELP SP STRING CRLF + { + help(sitetab, (char *) $5); + } + | SITE SP UMASK check_login CRLF + { + int oldmask; + + if ($4) { + oldmask = umask(0); + (void) umask(oldmask); + reply(200, "Current UMASK is %03o", oldmask); + } + } + | SITE SP UMASK check_login SP octal_number CRLF + { + int oldmask; + + if ($4) { + if (($6 == -1) || ($6 > 0777)) { + reply(501, "Bad UMASK value"); + } else { + oldmask = umask($6); + reply(200, + "UMASK set to %03o (was %03o)", + $6, oldmask); + } + } + } + | SITE SP CHMOD check_login SP octal_number SP pathname CRLF + { + if ($4 && ($8 != 0)) { + if ($6 > 0777) + reply(501, + "CHMOD: Mode value must be between 0 and 0777"); + else if (chmod((char *) $8, $6) < 0) + perror_reply(550, (char *) $8); + else + reply(200, "CHMOD command successful."); + } + if ($8 != 0) + free((char *) $8); + } + | SITE SP IDLE CRLF + { + reply(200, + "Current IDLE time limit is %d seconds; max %d", + timeout, maxtimeout); + } + | SITE SP IDLE SP NUMBER CRLF + { + if ($5 < 30 || $5 > maxtimeout) { + reply(501, + "Maximum IDLE time must be between 30 and %d seconds", + maxtimeout); + } else { + timeout = $5; + (void) alarm((unsigned) timeout); + reply(200, + "Maximum IDLE time set to %d seconds", + timeout); + } + } + | STOU check_login SP pathname CRLF + { + if ($2 && $4 != 0) + store((char *) $4, "w", 1); + if ($4 != 0) + free((char *) $4); + } + | SYST CRLF + { +#ifdef unix +#ifdef BSD + reply(215, "UNIX Type: L%d Version: BSD-%d", + NBBY, BSD); +#else /* BSD */ + reply(215, "UNIX Type: L%d", NBBY); +#endif /* BSD */ +#else /* unix */ + reply(215, "UNKNOWN Type: L%d", NBBY); +#endif /* unix */ + } + + /* + * SIZE is not in RFC959, but Postel has blessed it and + * it will be in the updated RFC. + * + * Return size of file in a format suitable for + * using with RESTART (we just count bytes). + */ + | SIZE check_login SP pathname CRLF + { + if ($2 && $4 != 0) + sizecmd((char *) $4); + if ($4 != 0) + free((char *) $4); + } + + /* + * MDTM is not in RFC959, but Postel has blessed it and + * it will be in the updated RFC. + * + * Return modification time of file as an ISO 3307 + * style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx + * where xxx is the fractional second (of any precision, + * not necessarily 3 digits) + */ + | MDTM check_login SP pathname CRLF + { + if ($2 && $4 != 0) { + struct stat stbuf; + if (stat((char *) $4, &stbuf) < 0) + perror_reply(550, "%s", (char *) $4); + else if ((stbuf.st_mode&S_IFMT) != S_IFREG) { + reply(550, "%s: not a plain file.", + (char *) $4); + } else { + register struct tm *t; + t = gmtime(&stbuf.st_mtime); + reply(213, + "%04d%02d%02d%02d%02d%02d", + 1900 + t->tm_year, + t->tm_mon+1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec); + } + } + if ($4 != 0) + free((char *) $4); + } + | QUIT CRLF + { + reply(221, "Goodbye."); + dologout(0); + } + | error CRLF + { + yyerrok; + } + ; +rcmd: RNFR check_login SP pathname CRLF + { + if ($2 && $4) { + fromname = renamefrom((char *) $4); + if (fromname == (char *) 0 && $4) { + free((char *) $4); + } + } + } + ; + +username: STRING + ; + +password: /* empty */ + { + *(const char **)(&($$)) = ""; + } + | STRING + ; + +byte_size: NUMBER + ; + +host_port: NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA + NUMBER COMMA NUMBER + { + register char *a, *p; + + a = (char *)&data_dest.sin_addr; + a[0] = $1; a[1] = $3; a[2] = $5; a[3] = $7; + p = (char *)&data_dest.sin_port; + p[0] = $9; p[1] = $11; + data_dest.sin_family = AF_INET; + } + ; + +form_code: N + { + $$ = FORM_N; + } + | T + { + $$ = FORM_T; + } + | C + { + $$ = FORM_C; + } + ; + +type_code: A + { + cmd_type = TYPE_A; + cmd_form = FORM_N; + } + | A SP form_code + { + cmd_type = TYPE_A; + cmd_form = $3; + } + | E + { + cmd_type = TYPE_E; + cmd_form = FORM_N; + } + | E SP form_code + { + cmd_type = TYPE_E; + cmd_form = $3; + } + | I + { + cmd_type = TYPE_I; + } + | L + { + cmd_type = TYPE_L; + cmd_bytesz = NBBY; + } + | L SP byte_size + { + cmd_type = TYPE_L; + cmd_bytesz = $3; + } + /* this is for a bug in the BBN ftp */ + | L byte_size + { + cmd_type = TYPE_L; + cmd_bytesz = $2; + } + ; + +struct_code: F + { + $$ = STRU_F; + } + | R + { + $$ = STRU_R; + } + | P + { + $$ = STRU_P; + } + ; + +mode_code: S + { + $$ = MODE_S; + } + | B + { + $$ = MODE_B; + } + | C + { + $$ = MODE_C; + } + ; + +pathname: pathstring + { + /* + * Problem: this production is used for all pathname + * processing, but only gives a 550 error reply. + * This is a valid reply in some cases but not in others. + */ + if (logged_in && $1 && strncmp((char *) $1, "~", 1) == 0) { + *(char **)&($$) = *glob((char *) $1); + if (globerr != 0) { + reply(550, globerr); + $$ = 0; + } + free((char *) $1); + } else + $$ = $1; + } + ; + +pathstring: STRING + ; + +octal_number: NUMBER + { + register int ret, dec, multby, digit; + + /* + * Convert a number that was read as decimal number + * to what it would be if it had been read as octal. + */ + dec = $1; + multby = 1; + ret = 0; + while (dec) { + digit = dec%10; + if (digit > 7) { + ret = -1; + break; + } + ret += digit * multby; + multby *= 8; + dec /= 10; + } + $$ = ret; + } + ; + +check_login: /* empty */ + { + if (logged_in) + $$ = 1; + else { + reply(530, "Please login with USER and PASS."); + $$ = 0; + } + } + ; + +%% + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +extern jmp_buf errcatch; + +static void upper(char *); + +#define CMD 0 /* beginning of command */ +#define ARGS 1 /* expect miscellaneous arguments */ +#define STR1 2 /* expect SP followed by STRING */ +#define STR2 3 /* expect STRING */ +#define OSTR 4 /* optional SP then STRING */ +#define ZSTR1 5 /* SP then optional STRING */ +#define ZSTR2 6 /* optional STRING after SP */ +#define SITECMD 7 /* SITE command */ +#define NSTR 8 /* Number followed by a string */ + +struct tab cmdtab[] = { /* In order defined in RFC 765 */ + { "USER", USER, STR1, 1, "<sp> username" }, + { "PASS", PASS, ZSTR1, 1, "<sp> password" }, + { "ACCT", ACCT, STR1, 0, "(specify account)" }, + { "SMNT", SMNT, ARGS, 0, "(structure mount)" }, + { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, + { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, + { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" }, + { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, + { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" }, + { "STRU", STRU, ARGS, 1, "(specify file structure)" }, + { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, + { "RETR", RETR, STR1, 1, "<sp> file-name" }, + { "STOR", STOR, STR1, 1, "<sp> file-name" }, + { "APPE", APPE, STR1, 1, "<sp> file-name" }, + { "MLFL", MLFL, OSTR, 0, "(mail file)" }, + { "MAIL", MAIL, OSTR, 0, "(mail to user)" }, + { "MSND", MSND, OSTR, 0, "(mail send to terminal)" }, + { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" }, + { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" }, + { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" }, + { "MRCP", MRCP, STR1, 0, "(mail recipient)" }, + { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" }, + { "REST", REST, ARGS, 0, "(restart command)" }, + { "RNFR", RNFR, STR1, 1, "<sp> file-name" }, + { "RNTO", RNTO, STR1, 1, "<sp> file-name" }, + { "ABOR", ABOR, ARGS, 1, "(abort operation)" }, + { "DELE", DELE, STR1, 1, "<sp> file-name" }, + { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" }, + { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" }, + { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" }, + { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" }, + { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" }, + { "SYST", SYST, ARGS, 1, "(get type of operating system)" }, + { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" }, + { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, + { "NOOP", NOOP, ARGS, 1, "" }, + { "MKD", MKD, STR1, 1, "<sp> path-name" }, + { "XMKD", MKD, STR1, 1, "<sp> path-name" }, + { "RMD", RMD, STR1, 1, "<sp> path-name" }, + { "XRMD", RMD, STR1, 1, "<sp> path-name" }, + { "PWD", PWD, ARGS, 1, "(return current directory)" }, + { "XPWD", PWD, ARGS, 1, "(return current directory)" }, + { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" }, + { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" }, + { "STOU", STOU, STR1, 1, "<sp> file-name" }, + { "SIZE", SIZE, OSTR, 1, "<sp> path-name" }, + { "MDTM", MDTM, OSTR, 1, "<sp> path-name" }, + { 0, 0, 0, 0, 0 } +}; + +struct tab sitetab[] = { + { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" }, + { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" }, + { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" }, + { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, + { 0, 0, 0, 0, 0 } +}; + +static struct tab * +lookup(struct tab *p, char *cmd) +{ + + for (; p->name != 0; p++) + if (strcmp(cmd, p->name) == 0) + return (p); + return (0); +} + +#include <arpa/telnet.h> + +/* + * get_line - a hacked up version of fgets to ignore TELNET escape codes. + */ +static char * +get_line(char *s, int n, FILE *iop) +{ + register int c; + register char *cs; + + cs = s; +/* tmpline may contain saved command from urgent mode interruption */ + for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) { + *cs++ = tmpline[c]; + if (tmpline[c] == '\n') { + *cs = '\0'; + if (debug) + syslog(LOG_DEBUG, "command: %s", s); + tmpline[0] = '\0'; + return(s); + } + if (c == 0) + tmpline[0] = '\0'; + } + while ((c = getc(iop)) != EOF) { + c &= 0377; + if (c == IAC) { + if ((c = getc(iop)) != EOF) { + c &= 0377; + switch (c) { + case WILL: + case WONT: + c = getc(iop); + printf("%c%c%c", IAC, DONT, 0377&c); + (void) fflush(stdout); + continue; + case DO: + case DONT: + c = getc(iop); + printf("%c%c%c", IAC, WONT, 0377&c); + (void) fflush(stdout); + continue; + case IAC: + break; + default: + continue; /* ignore command */ + } + } + } + *cs++ = c; + if (--n <= 0 || c == '\n') + break; + } + if (c == EOF && cs == s) + return (0); + *cs = '\0'; + if (debug) + syslog(LOG_DEBUG, "command: %s", s); + return (s); +} + +static void +toolong(int sig) +{ + time_t now; + + (void) sig; + reply(421, + "Timeout (%d seconds): closing control connection.", timeout); + (void) time(&now); + if (logging) { + syslog(LOG_INFO, + "User %s timed out after %d seconds at %s", + (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now)); + } + dologout(1); +} + +int +yylex(void) +{ + static int cpos, state; + register char *cp, *cp2; + register struct tab *p; + int n; + char c; + + for (;;) { + switch (state) { + + case CMD: + (void) signal(SIGALRM, toolong); + (void) alarm((unsigned) timeout); + if (get_line(cbuf, sizeof(cbuf)-1, stdin) == 0) { + reply(221, "You could at least say goodbye."); + dologout(0); + } + (void) alarm(0); +#ifdef SETPROCTITLE + if (strncasecmp(cbuf, "PASS", 4) != 0) + setproctitle("%s: %s", proctitle, cbuf); +#endif /* SETPROCTITLE */ + if ((cp = strchr(cbuf, '\r'))) { + *cp++ = '\n'; + *cp = '\0'; + } + if ((cp = strpbrk(cbuf, " \n"))) + cpos = cp - cbuf; + if (cpos == 0) + cpos = 4; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + upper(cbuf); + p = lookup(cmdtab, cbuf); + cbuf[cpos] = c; + if (p != 0) { + if (p->implemented == 0) { + nack(p->name); + longjmp(errcatch,0); + /* NOTREACHED */ + } + state = p->state; + *(const char **)(&yylval) = p->name; + return (p->token); + } + break; + + case SITECMD: + if (cbuf[cpos] == ' ') { + cpos++; + return (SP); + } + cp = &cbuf[cpos]; + if ((cp2 = strpbrk(cp, " \n"))) + cpos = cp2 - cbuf; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + upper(cp); + p = lookup(sitetab, cp); + cbuf[cpos] = c; + if (p != 0) { + if (p->implemented == 0) { + state = CMD; + nack(p->name); + longjmp(errcatch,0); + /* NOTREACHED */ + } + state = p->state; + *(const char **)(&yylval) = p->name; + return (p->token); + } + state = CMD; + break; + + case OSTR: + if (cbuf[cpos] == '\n') { + state = CMD; + return (CRLF); + } + /* FALLTHROUGH */ + + case STR1: + case ZSTR1: + dostr1: + if (cbuf[cpos] == ' ') { + cpos++; + if (state == OSTR) + state = STR2; + else + ++state; + return (SP); + } + break; + + case ZSTR2: + if (cbuf[cpos] == '\n') { + state = CMD; + return (CRLF); + } + /* FALLTHROUGH */ + + case STR2: + cp = &cbuf[cpos]; + n = strlen(cp); + cpos += n - 1; + /* + * Make sure the string is nonempty and \n terminated. + */ + if (n > 1 && cbuf[cpos] == '\n') { + cbuf[cpos] = '\0'; + *(char **)&yylval = copy(cp); + cbuf[cpos] = '\n'; + state = ARGS; + return (STRING); + } + break; + + case NSTR: + if (cbuf[cpos] == ' ') { + cpos++; + return (SP); + } + if (isdigit(cbuf[cpos])) { + cp = &cbuf[cpos]; + while (isdigit(cbuf[++cpos])) + ; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + yylval = atoi(cp); + cbuf[cpos] = c; + state = STR1; + return (NUMBER); + } + state = STR1; + goto dostr1; + + case ARGS: + if (isdigit(cbuf[cpos])) { + cp = &cbuf[cpos]; + while (isdigit(cbuf[++cpos])) + ; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + yylval = atoi(cp); + cbuf[cpos] = c; + return (NUMBER); + } + switch (cbuf[cpos++]) { + + case '\n': + state = CMD; + return (CRLF); + + case ' ': + return (SP); + + case ',': + return (COMMA); + + case 'A': + case 'a': + return (A); + + case 'B': + case 'b': + return (B); + + case 'C': + case 'c': + return (C); + + case 'E': + case 'e': + return (E); + + case 'F': + case 'f': + return (F); + + case 'I': + case 'i': + return (I); + + case 'L': + case 'l': + return (L); + + case 'N': + case 'n': + return (N); + + case 'P': + case 'p': + return (P); + + case 'R': + case 'r': + return (R); + + case 'S': + case 's': + return (S); + + case 'T': + case 't': + return (T); + + } + break; + + default: + fatal("Unknown state in scanner."); + } + yyerror((char *) 0); + state = CMD; + longjmp(errcatch,0); + } +} + +static void +upper(char *s) +{ + while (*s != '\0') { + if (islower(*s)) + *s = toupper(*s); + s++; + } +} + +static char * +copy(const char *s) +{ + char *p; + + p = (char * )malloc(strlen(s) + 1); + if (p == 0) + fatal("Ran out of memory."); + else + (void) strcpy(p, s); + return (p); +} + +static void +help(struct tab *ctab, char *s) +{ + register struct tab *c; + register int width, NCMDS; + const char *help_type; + + if (ctab == sitetab) + help_type = "SITE "; + else + help_type = ""; + width = 0, NCMDS = 0; + for (c = ctab; c->name != 0; c++) { + int len = strlen(c->name); + + if (len > width) + width = len; + NCMDS++; + } + width = (width + 8) &~ 7; + if (s == 0) { + register int i, j, w; + int columns, lines; + + lreply(214, "The following %scommands are recognized %s.", + help_type, "(* =>'s unimplemented)"); + columns = 76 / width; + if (columns == 0) + columns = 1; + lines = (NCMDS + columns - 1) / columns; + for (i = 0; i < lines; i++) { + printf(" "); + for (j = 0; j < columns; j++) { + c = ctab + j * lines + i; + assert(c->name != 0); + printf("%s%c", c->name, + c->implemented ? ' ' : '*'); + if (c + lines >= &ctab[NCMDS]) + break; + w = strlen(c->name) + 1; + while (w < width) { + putchar(' '); + w++; + } + } + printf("\r\n"); + } + (void) fflush(stdout); + reply(214, "Direct comments to ftp-bugs@%s.", hostname); + return; + } + upper(s); + c = lookup(ctab, s); + if (c == (struct tab *)0) { + reply(502, "Unknown command %s.", s); + return; + } + if (c->implemented) + reply(214, "Syntax: %s%s %s", help_type, c->name, c->help); + else + reply(214, "%s%-*s\t%s; unimplemented.", help_type, width, + c->name, c->help); +} + +static void +sizecmd(char *filename) +{ + switch (type) { + case TYPE_L: + case TYPE_I: { + struct stat stbuf; + if (stat(filename, &stbuf) < 0 || + (stbuf.st_mode&S_IFMT) != S_IFREG) + reply(550, "%s: not a plain file.", filename); + else +#ifdef HAVE_LONG_LONG + reply(213, "%llu", (long long) stbuf.st_size); +#else + reply(213, "%lu", stbuf.st_size); +#endif + break;} + case TYPE_A: { + FILE *fin; + register int c, count; + struct stat stbuf; + fin = fopen(filename, "r"); + if (fin == 0) { + perror_reply(550, filename); + return; + } + if (fstat(fileno(fin), &stbuf) < 0 || + (stbuf.st_mode&S_IFMT) != S_IFREG) { + reply(550, "%s: not a plain file.", filename); + (void) fclose(fin); + return; + } + + count = 0; + while((c=getc(fin)) != EOF) { + if (c == '\n') /* will get expanded to \r\n */ + count++; + count++; + } + (void) fclose(fin); + + reply(213, "%ld", count); + break;} + default: + reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]); + } +} diff --git a/usr.bin/yacc/tests/grammar.y b/usr.bin/yacc/tests/grammar.y new file mode 100644 index 0000000..a2f1883 --- /dev/null +++ b/usr.bin/yacc/tests/grammar.y @@ -0,0 +1,1183 @@ +/* $Id: grammar.y,v 1.5 2012/01/15 20:00:59 tom Exp $ + * + * yacc grammar for C function prototype generator + * This was derived from the grammar in Appendix A of + * "The C Programming Language" by Kernighan and Ritchie. + */ +%expect 1 +%{ +#ifdef YYBISON +#include <stdlib.h> +#define YYSTYPE_IS_DECLARED +#define yyerror yaccError +#endif + +#if defined(YYBISON) || !defined(YYBYACC) +static void yyerror(const char *s); +#endif +%} + +%token <text> '(' '*' '&' + /* identifiers that are not reserved words */ + T_IDENTIFIER T_TYPEDEF_NAME T_DEFINE_NAME + + /* storage class */ + T_AUTO T_EXTERN T_REGISTER T_STATIC T_TYPEDEF + /* This keyword included for compatibility with C++. */ + T_INLINE + /* This keyword included for compatibility with GCC */ + T_EXTENSION + + /* type specifiers */ + T_CHAR T_DOUBLE T_FLOAT T_INT T_VOID + T_LONG T_SHORT T_SIGNED T_UNSIGNED + T_ENUM T_STRUCT T_UNION + /* C9X new types */ + T_Bool T_Complex T_Imaginary + + /* type qualifiers */ + T_TYPE_QUALIFIER + + /* paired square brackets and everything between them: [ ... ] */ + T_BRACKETS + +%token + /* left brace */ + T_LBRACE + /* all input to the matching right brace */ + T_MATCHRBRACE + + /* three periods */ + T_ELLIPSIS + + /* constant expression or paired braces following an equal sign */ + T_INITIALIZER + + /* string literal */ + T_STRING_LITERAL + + /* asm */ + T_ASM + /* ( "string literal" ) following asm keyword */ + T_ASMARG + + /* va_dcl from <varargs.h> */ + T_VA_DCL + +%type <decl_spec> decl_specifiers decl_specifier +%type <decl_spec> storage_class type_specifier type_qualifier +%type <decl_spec> struct_or_union_specifier enum_specifier +%type <decl_list> init_declarator_list +%type <declarator> init_declarator declarator direct_declarator +%type <declarator> abs_declarator direct_abs_declarator +%type <param_list> parameter_type_list parameter_list +%type <parameter> parameter_declaration +%type <param_list> opt_identifier_list identifier_list +%type <text> struct_or_union pointer opt_type_qualifiers type_qualifier_list + any_id identifier_or_ref +%type <text> enumeration + +%{ +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +#define OPT_LINTLIBRARY 1 + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +/* #include "cproto.h" */ +#define MAX_TEXT_SIZE 1024 + +/* Prototype styles */ +#if OPT_LINTLIBRARY +#define PROTO_ANSI_LLIB -2 /* form ANSI lint-library source */ +#define PROTO_LINTLIBRARY -1 /* form lint-library source */ +#endif +#define PROTO_NONE 0 /* do not output any prototypes */ +#define PROTO_TRADITIONAL 1 /* comment out parameters */ +#define PROTO_ABSTRACT 2 /* comment out parameter names */ +#define PROTO_ANSI 3 /* ANSI C prototype */ + +typedef int PrototypeStyle; + +typedef char boolean; + +extern boolean types_out; +extern PrototypeStyle proto_style; + +#define ansiLintLibrary() (proto_style == PROTO_ANSI_LLIB) +#define knrLintLibrary() (proto_style == PROTO_LINTLIBRARY) +#define lintLibrary() (knrLintLibrary() || ansiLintLibrary()) + +#if OPT_LINTLIBRARY +#define FUNC_UNKNOWN -1 /* unspecified */ +#else +#define FUNC_UNKNOWN 0 /* unspecified (same as FUNC_NONE) */ +#endif +#define FUNC_NONE 0 /* not a function definition */ +#define FUNC_TRADITIONAL 1 /* traditional style */ +#define FUNC_ANSI 2 /* ANSI style */ +#define FUNC_BOTH 3 /* both styles */ + +typedef int FuncDefStyle; + +/* Source file text */ +typedef struct text { + char text[MAX_TEXT_SIZE]; /* source text */ + long begin; /* offset in temporary file */ +} Text; + +/* Declaration specifier flags */ +#define DS_NONE 0 /* default */ +#define DS_EXTERN 1 /* contains "extern" specifier */ +#define DS_STATIC 2 /* contains "static" specifier */ +#define DS_CHAR 4 /* contains "char" type specifier */ +#define DS_SHORT 8 /* contains "short" type specifier */ +#define DS_FLOAT 16 /* contains "float" type specifier */ +#define DS_INLINE 32 /* contains "inline" specifier */ +#define DS_JUNK 64 /* we're not interested in this declaration */ + +/* This structure stores information about a declaration specifier. */ +typedef struct decl_spec { + unsigned short flags; /* flags defined above */ + char *text; /* source text */ + long begin; /* offset in temporary file */ +} DeclSpec; + +/* This is a list of function parameters. */ +typedef struct _ParameterList { + struct parameter *first; /* pointer to first parameter in list */ + struct parameter *last; /* pointer to last parameter in list */ + long begin_comment; /* begin offset of comment */ + long end_comment; /* end offset of comment */ + char *comment; /* comment at start of parameter list */ +} ParameterList; + +/* This structure stores information about a declarator. */ +typedef struct _Declarator { + char *name; /* name of variable or function */ + char *text; /* source text */ + long begin; /* offset in temporary file */ + long begin_comment; /* begin offset of comment */ + long end_comment; /* end offset of comment */ + FuncDefStyle func_def; /* style of function definition */ + ParameterList params; /* function parameters */ + boolean pointer; /* TRUE if it declares a pointer */ + struct _Declarator *head; /* head function declarator */ + struct _Declarator *func_stack; /* stack of function declarators */ + struct _Declarator *next; /* next declarator in list */ +} Declarator; + +/* This structure stores information about a function parameter. */ +typedef struct parameter { + struct parameter *next; /* next parameter in list */ + DeclSpec decl_spec; + Declarator *declarator; + char *comment; /* comment following the parameter */ +} Parameter; + +/* This is a list of declarators. */ +typedef struct declarator_list { + Declarator *first; /* pointer to first declarator in list */ + Declarator *last; /* pointer to last declarator in list */ +} DeclaratorList; + +/* #include "symbol.h" */ +typedef struct symbol { + struct symbol *next; /* next symbol in list */ + char *name; /* name of symbol */ + char *value; /* value of symbol (for defines) */ + short flags; /* symbol attributes */ +} Symbol; + +/* parser stack entry type */ +typedef union { + Text text; + DeclSpec decl_spec; + Parameter *parameter; + ParameterList param_list; + Declarator *declarator; + DeclaratorList decl_list; +} YYSTYPE; + +/* The hash table length should be a prime number. */ +#define SYM_MAX_HASH 251 + +typedef struct symbol_table { + Symbol *bucket[SYM_MAX_HASH]; /* hash buckets */ +} SymbolTable; + +extern SymbolTable *new_symbol_table /* Create symbol table */ + (void); +extern void free_symbol_table /* Destroy symbol table */ + (SymbolTable *s); +extern Symbol *find_symbol /* Lookup symbol name */ + (SymbolTable *s, const char *n); +extern Symbol *new_symbol /* Define new symbol */ + (SymbolTable *s, const char *n, const char *v, int f); + +/* #include "semantic.h" */ +extern void new_decl_spec (DeclSpec *, const char *, long, int); +extern void free_decl_spec (DeclSpec *); +extern void join_decl_specs (DeclSpec *, DeclSpec *, DeclSpec *); +extern void check_untagged (DeclSpec *); +extern Declarator *new_declarator (const char *, const char *, long); +extern void free_declarator (Declarator *); +extern void new_decl_list (DeclaratorList *, Declarator *); +extern void free_decl_list (DeclaratorList *); +extern void add_decl_list (DeclaratorList *, DeclaratorList *, Declarator *); +extern Parameter *new_parameter (DeclSpec *, Declarator *); +extern void free_parameter (Parameter *); +extern void new_param_list (ParameterList *, Parameter *); +extern void free_param_list (ParameterList *); +extern void add_param_list (ParameterList *, ParameterList *, Parameter *); +extern void new_ident_list (ParameterList *); +extern void add_ident_list (ParameterList *, ParameterList *, const char *); +extern void set_param_types (ParameterList *, DeclSpec *, DeclaratorList *); +extern void gen_declarations (DeclSpec *, DeclaratorList *); +extern void gen_prototype (DeclSpec *, Declarator *); +extern void gen_func_declarator (Declarator *); +extern void gen_func_definition (DeclSpec *, Declarator *); + +extern void init_parser (void); +extern void process_file (FILE *infile, char *name); +extern char *cur_text (void); +extern char *cur_file_name (void); +extern char *implied_typedef (void); +extern void include_file (char *name, int convert); +extern char *supply_parm (int count); +extern char *xstrdup (const char *); +extern int already_declared (char *name); +extern int is_actual_func (Declarator *d); +extern int lint_ellipsis (Parameter *p); +extern int want_typedef (void); +extern void begin_tracking (void); +extern void begin_typedef (void); +extern void copy_typedef (char *s); +extern void ellipsis_varargs (Declarator *d); +extern void end_typedef (void); +extern void flush_varargs (void); +extern void fmt_library (int code); +extern void imply_typedef (const char *s); +extern void indent (FILE *outf); +extern void put_blankline (FILE *outf); +extern void put_body (FILE *outf, DeclSpec *decl_spec, Declarator *declarator); +extern void put_char (FILE *outf, int c); +extern void put_error (void); +extern void put_newline (FILE *outf); +extern void put_padded (FILE *outf, const char *s); +extern void put_string (FILE *outf, const char *s); +extern void track_in (void); + +extern boolean file_comments; +extern FuncDefStyle func_style; +extern char base_file[]; + +extern int yylex (void); + +/* declaration specifier attributes for the typedef statement currently being + * scanned + */ +static int cur_decl_spec_flags; + +/* pointer to parameter list for the current function definition */ +static ParameterList *func_params; + +/* A parser semantic action sets this pointer to the current declarator in + * a function parameter declaration in order to catch any comments following + * the parameter declaration on the same line. If the lexer scans a comment + * and <cur_declarator> is not NULL, then the comment is attached to the + * declarator. To ignore subsequent comments, the lexer sets this to NULL + * after scanning a comment or end of line. + */ +static Declarator *cur_declarator; + +/* temporary string buffer */ +static char buf[MAX_TEXT_SIZE]; + +/* table of typedef names */ +static SymbolTable *typedef_names; + +/* table of define names */ +static SymbolTable *define_names; + +/* table of type qualifiers */ +static SymbolTable *type_qualifiers; + +/* information about the current input file */ +typedef struct { + char *base_name; /* base input file name */ + char *file_name; /* current file name */ + FILE *file; /* input file */ + unsigned line_num; /* current line number in input file */ + FILE *tmp_file; /* temporary file */ + long begin_comment; /* tmp file offset after last written ) or ; */ + long end_comment; /* tmp file offset after last comment */ + boolean convert; /* if TRUE, convert function definitions */ + boolean changed; /* TRUE if conversion done in this file */ +} IncludeStack; + +static IncludeStack *cur_file; /* current input file */ + +/* #include "yyerror.c" */ + +static int haveAnsiParam (void); + + +/* Flags to enable us to find if a procedure returns a value. + */ +static int return_val; /* nonzero on BRACES iff return-expression found */ + +static const char * +dft_decl_spec (void) +{ + return (lintLibrary() && !return_val) ? "void" : "int"; +} + +static int +haveAnsiParam (void) +{ + Parameter *p; + if (func_params != 0) { + for (p = func_params->first; p != 0; p = p->next) { + if (p->declarator->func_def == FUNC_ANSI) { + return TRUE; + } + } + } + return FALSE; +} +%} +%% + +program + : /* empty */ + | translation_unit + ; + +translation_unit + : external_declaration + | translation_unit external_declaration + ; + +external_declaration + : declaration + | function_definition + | ';' + | linkage_specification + | T_ASM T_ASMARG ';' + | error T_MATCHRBRACE + { + yyerrok; + } + | error ';' + { + yyerrok; + } + ; + +braces + : T_LBRACE T_MATCHRBRACE + ; + +linkage_specification + : T_EXTERN T_STRING_LITERAL braces + { + /* Provide an empty action here so bison will not complain about + * incompatible types in the default action it normally would + * have generated. + */ + } + | T_EXTERN T_STRING_LITERAL declaration + { + /* empty */ + } + ; + +declaration + : decl_specifiers ';' + { +#if OPT_LINTLIBRARY + if (types_out && want_typedef()) { + gen_declarations(&$1, (DeclaratorList *)0); + flush_varargs(); + } +#endif + free_decl_spec(&$1); + end_typedef(); + } + | decl_specifiers init_declarator_list ';' + { + if (func_params != NULL) { + set_param_types(func_params, &$1, &$2); + } else { + gen_declarations(&$1, &$2); +#if OPT_LINTLIBRARY + flush_varargs(); +#endif + free_decl_list(&$2); + } + free_decl_spec(&$1); + end_typedef(); + } + | any_typedef decl_specifiers + { + cur_decl_spec_flags = $2.flags; + free_decl_spec(&$2); + } + opt_declarator_list ';' + { + end_typedef(); + } + ; + +any_typedef + : T_EXTENSION T_TYPEDEF + { + begin_typedef(); + } + | T_TYPEDEF + { + begin_typedef(); + } + ; + +opt_declarator_list + : /* empty */ + | declarator_list + ; + +declarator_list + : declarator + { + int flags = cur_decl_spec_flags; + + /* If the typedef is a pointer type, then reset the short type + * flags so it does not get promoted. + */ + if (strcmp($1->text, $1->name) != 0) + flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT); + new_symbol(typedef_names, $1->name, NULL, flags); + free_declarator($1); + } + | declarator_list ',' declarator + { + int flags = cur_decl_spec_flags; + + if (strcmp($3->text, $3->name) != 0) + flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT); + new_symbol(typedef_names, $3->name, NULL, flags); + free_declarator($3); + } + ; + +function_definition + : decl_specifiers declarator + { + check_untagged(&$1); + if ($2->func_def == FUNC_NONE) { + yyerror("syntax error"); + YYERROR; + } + func_params = &($2->head->params); + func_params->begin_comment = cur_file->begin_comment; + func_params->end_comment = cur_file->end_comment; + } + opt_declaration_list T_LBRACE + { + /* If we're converting to K&R and we've got a nominally K&R + * function which has a parameter which is ANSI (i.e., a prototyped + * function pointer), then we must override the deciphered value of + * 'func_def' so that the parameter will be converted. + */ + if (func_style == FUNC_TRADITIONAL + && haveAnsiParam() + && $2->head->func_def == func_style) { + $2->head->func_def = FUNC_BOTH; + } + + func_params = NULL; + + if (cur_file->convert) + gen_func_definition(&$1, $2); + gen_prototype(&$1, $2); +#if OPT_LINTLIBRARY + flush_varargs(); +#endif + free_decl_spec(&$1); + free_declarator($2); + } + T_MATCHRBRACE + | declarator + { + if ($1->func_def == FUNC_NONE) { + yyerror("syntax error"); + YYERROR; + } + func_params = &($1->head->params); + func_params->begin_comment = cur_file->begin_comment; + func_params->end_comment = cur_file->end_comment; + } + opt_declaration_list T_LBRACE T_MATCHRBRACE + { + DeclSpec decl_spec; + + func_params = NULL; + + new_decl_spec(&decl_spec, dft_decl_spec(), $1->begin, DS_NONE); + if (cur_file->convert) + gen_func_definition(&decl_spec, $1); + gen_prototype(&decl_spec, $1); +#if OPT_LINTLIBRARY + flush_varargs(); +#endif + free_decl_spec(&decl_spec); + free_declarator($1); + } + ; + +opt_declaration_list + : /* empty */ + | T_VA_DCL + | declaration_list + ; + +declaration_list + : declaration + | declaration_list declaration + ; + +decl_specifiers + : decl_specifier + | decl_specifiers decl_specifier + { + join_decl_specs(&$$, &$1, &$2); + free($1.text); + free($2.text); + } + ; + +decl_specifier + : storage_class + | type_specifier + | type_qualifier + ; + +storage_class + : T_AUTO + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_EXTERN + { + new_decl_spec(&$$, $1.text, $1.begin, DS_EXTERN); + } + | T_REGISTER + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_STATIC + { + new_decl_spec(&$$, $1.text, $1.begin, DS_STATIC); + } + | T_INLINE + { + new_decl_spec(&$$, $1.text, $1.begin, DS_INLINE); + } + | T_EXTENSION + { + new_decl_spec(&$$, $1.text, $1.begin, DS_JUNK); + } + ; + +type_specifier + : T_CHAR + { + new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR); + } + | T_DOUBLE + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_FLOAT + { + new_decl_spec(&$$, $1.text, $1.begin, DS_FLOAT); + } + | T_INT + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_LONG + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_SHORT + { + new_decl_spec(&$$, $1.text, $1.begin, DS_SHORT); + } + | T_SIGNED + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_UNSIGNED + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_VOID + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_Bool + { + new_decl_spec(&$$, $1.text, $1.begin, DS_CHAR); + } + | T_Complex + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_Imaginary + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_TYPEDEF_NAME + { + Symbol *s; + s = find_symbol(typedef_names, $1.text); + if (s != NULL) + new_decl_spec(&$$, $1.text, $1.begin, s->flags); + } + | struct_or_union_specifier + | enum_specifier + ; + +type_qualifier + : T_TYPE_QUALIFIER + { + new_decl_spec(&$$, $1.text, $1.begin, DS_NONE); + } + | T_DEFINE_NAME + { + /* This rule allows the <pointer> nonterminal to scan #define + * names as if they were type modifiers. + */ + Symbol *s; + s = find_symbol(define_names, $1.text); + if (s != NULL) + new_decl_spec(&$$, $1.text, $1.begin, s->flags); + } + ; + +struct_or_union_specifier + : struct_or_union any_id braces + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "%s %s", $1.text, $2.text); + new_decl_spec(&$$, s, $1.begin, DS_NONE); + } + | struct_or_union braces + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "%s {}", $1.text); + new_decl_spec(&$$, s, $1.begin, DS_NONE); + } + | struct_or_union any_id + { + (void)sprintf(buf, "%s %s", $1.text, $2.text); + new_decl_spec(&$$, buf, $1.begin, DS_NONE); + } + ; + +struct_or_union + : T_STRUCT + { + imply_typedef($$.text); + } + | T_UNION + { + imply_typedef($$.text); + } + ; + +init_declarator_list + : init_declarator + { + new_decl_list(&$$, $1); + } + | init_declarator_list ',' init_declarator + { + add_decl_list(&$$, &$1, $3); + } + ; + +init_declarator + : declarator + { + if ($1->func_def != FUNC_NONE && func_params == NULL && + func_style == FUNC_TRADITIONAL && cur_file->convert) { + gen_func_declarator($1); + fputs(cur_text(), cur_file->tmp_file); + } + cur_declarator = $$; + } + | declarator '=' + { + if ($1->func_def != FUNC_NONE && func_params == NULL && + func_style == FUNC_TRADITIONAL && cur_file->convert) { + gen_func_declarator($1); + fputs(" =", cur_file->tmp_file); + } + } + T_INITIALIZER + ; + +enum_specifier + : enumeration any_id braces + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "enum %s", $2.text); + new_decl_spec(&$$, s, $1.begin, DS_NONE); + } + | enumeration braces + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "%s {}", $1.text); + new_decl_spec(&$$, s, $1.begin, DS_NONE); + } + | enumeration any_id + { + (void)sprintf(buf, "enum %s", $2.text); + new_decl_spec(&$$, buf, $1.begin, DS_NONE); + } + ; + +enumeration + : T_ENUM + { + imply_typedef("enum"); + $$ = $1; + } + ; + +any_id + : T_IDENTIFIER + | T_TYPEDEF_NAME + ; + +declarator + : pointer direct_declarator + { + $$ = $2; + (void)sprintf(buf, "%s%s", $1.text, $$->text); + free($$->text); + $$->text = xstrdup(buf); + $$->begin = $1.begin; + $$->pointer = TRUE; + } + | direct_declarator + ; + +direct_declarator + : identifier_or_ref + { + $$ = new_declarator($1.text, $1.text, $1.begin); + } + | '(' declarator ')' + { + $$ = $2; + (void)sprintf(buf, "(%s)", $$->text); + free($$->text); + $$->text = xstrdup(buf); + $$->begin = $1.begin; + } + | direct_declarator T_BRACKETS + { + $$ = $1; + (void)sprintf(buf, "%s%s", $$->text, $2.text); + free($$->text); + $$->text = xstrdup(buf); + } + | direct_declarator '(' parameter_type_list ')' + { + $$ = new_declarator("%s()", $1->name, $1->begin); + $$->params = $3; + $$->func_stack = $1; + $$->head = ($1->func_stack == NULL) ? $$ : $1->head; + $$->func_def = FUNC_ANSI; + } + | direct_declarator '(' opt_identifier_list ')' + { + $$ = new_declarator("%s()", $1->name, $1->begin); + $$->params = $3; + $$->func_stack = $1; + $$->head = ($1->func_stack == NULL) ? $$ : $1->head; + $$->func_def = FUNC_TRADITIONAL; + } + ; + +pointer + : '*' opt_type_qualifiers + { + (void)sprintf($$.text, "*%s", $2.text); + $$.begin = $1.begin; + } + | '*' opt_type_qualifiers pointer + { + (void)sprintf($$.text, "*%s%s", $2.text, $3.text); + $$.begin = $1.begin; + } + ; + +opt_type_qualifiers + : /* empty */ + { + strcpy($$.text, ""); + $$.begin = 0L; + } + | type_qualifier_list + ; + +type_qualifier_list + : type_qualifier + { + (void)sprintf($$.text, "%s ", $1.text); + $$.begin = $1.begin; + free($1.text); + } + | type_qualifier_list type_qualifier + { + (void)sprintf($$.text, "%s%s ", $1.text, $2.text); + $$.begin = $1.begin; + free($2.text); + } + ; + +parameter_type_list + : parameter_list + | parameter_list ',' T_ELLIPSIS + { + add_ident_list(&$$, &$1, "..."); + } + ; + +parameter_list + : parameter_declaration + { + new_param_list(&$$, $1); + } + | parameter_list ',' parameter_declaration + { + add_param_list(&$$, &$1, $3); + } + ; + +parameter_declaration + : decl_specifiers declarator + { + check_untagged(&$1); + $$ = new_parameter(&$1, $2); + } + | decl_specifiers abs_declarator + { + check_untagged(&$1); + $$ = new_parameter(&$1, $2); + } + | decl_specifiers + { + check_untagged(&$1); + $$ = new_parameter(&$1, (Declarator *)0); + } + ; + +opt_identifier_list + : /* empty */ + { + new_ident_list(&$$); + } + | identifier_list + ; + +identifier_list + : any_id + { + new_ident_list(&$$); + add_ident_list(&$$, &$$, $1.text); + } + | identifier_list ',' any_id + { + add_ident_list(&$$, &$1, $3.text); + } + ; + +identifier_or_ref + : any_id + { + $$ = $1; + } + | '&' any_id + { +#if OPT_LINTLIBRARY + if (lintLibrary()) { /* Lint doesn't grok C++ ref variables */ + $$ = $2; + } else +#endif + (void)sprintf($$.text, "&%s", $2.text); + $$.begin = $1.begin; + } + ; + +abs_declarator + : pointer + { + $$ = new_declarator($1.text, "", $1.begin); + } + | pointer direct_abs_declarator + { + $$ = $2; + (void)sprintf(buf, "%s%s", $1.text, $$->text); + free($$->text); + $$->text = xstrdup(buf); + $$->begin = $1.begin; + } + | direct_abs_declarator + ; + +direct_abs_declarator + : '(' abs_declarator ')' + { + $$ = $2; + (void)sprintf(buf, "(%s)", $$->text); + free($$->text); + $$->text = xstrdup(buf); + $$->begin = $1.begin; + } + | direct_abs_declarator T_BRACKETS + { + $$ = $1; + (void)sprintf(buf, "%s%s", $$->text, $2.text); + free($$->text); + $$->text = xstrdup(buf); + } + | T_BRACKETS + { + $$ = new_declarator($1.text, "", $1.begin); + } + | direct_abs_declarator '(' parameter_type_list ')' + { + $$ = new_declarator("%s()", "", $1->begin); + $$->params = $3; + $$->func_stack = $1; + $$->head = ($1->func_stack == NULL) ? $$ : $1->head; + $$->func_def = FUNC_ANSI; + } + | direct_abs_declarator '(' ')' + { + $$ = new_declarator("%s()", "", $1->begin); + $$->func_stack = $1; + $$->head = ($1->func_stack == NULL) ? $$ : $1->head; + $$->func_def = FUNC_ANSI; + } + | '(' parameter_type_list ')' + { + Declarator *d; + + d = new_declarator("", "", $1.begin); + $$ = new_declarator("%s()", "", $1.begin); + $$->params = $2; + $$->func_stack = d; + $$->head = $$; + $$->func_def = FUNC_ANSI; + } + | '(' ')' + { + Declarator *d; + + d = new_declarator("", "", $1.begin); + $$ = new_declarator("%s()", "", $1.begin); + $$->func_stack = d; + $$->head = $$; + $$->func_def = FUNC_ANSI; + } + ; + +%% + +/* lex.yy.c */ +#define BEGIN yy_start = 1 + 2 * + +#define CPP1 1 +#define INIT1 2 +#define INIT2 3 +#define CURLY 4 +#define LEXYACC 5 +#define ASM 6 +#define CPP_INLINE 7 + +extern char *yytext; +extern FILE *yyin, *yyout; + +static int curly; /* number of curly brace nesting levels */ +static int ly_count; /* number of occurrences of %% */ +static int inc_depth; /* include nesting level */ +static SymbolTable *included_files; /* files already included */ +static int yy_start = 0; /* start state number */ + +#define grammar_error(s) yaccError(s) + +static void +yaccError (const char *msg) +{ + func_params = NULL; + put_error(); /* tell what line we're on, and what file */ + fprintf(stderr, "%s at token '%s'\n", msg, yytext); +} + +/* Initialize the table of type qualifier keywords recognized by the lexical + * analyzer. + */ +void +init_parser (void) +{ + static const char *keywords[] = { + "const", + "restrict", + "volatile", + "interrupt", +#ifdef vms + "noshare", + "readonly", +#endif +#if defined(MSDOS) || defined(OS2) + "__cdecl", + "__export", + "__far", + "__fastcall", + "__fortran", + "__huge", + "__inline", + "__interrupt", + "__loadds", + "__near", + "__pascal", + "__saveregs", + "__segment", + "__stdcall", + "__syscall", + "_cdecl", + "_cs", + "_ds", + "_es", + "_export", + "_far", + "_fastcall", + "_fortran", + "_huge", + "_interrupt", + "_loadds", + "_near", + "_pascal", + "_saveregs", + "_seg", + "_segment", + "_ss", + "cdecl", + "far", + "huge", + "near", + "pascal", +#ifdef OS2 + "__far16", +#endif +#endif +#ifdef __GNUC__ + /* gcc aliases */ + "__builtin_va_arg", + "__builtin_va_list", + "__const", + "__const__", + "__inline", + "__inline__", + "__restrict", + "__restrict__", + "__volatile", + "__volatile__", +#endif + }; + unsigned i; + + /* Initialize type qualifier table. */ + type_qualifiers = new_symbol_table(); + for (i = 0; i < sizeof(keywords)/sizeof(keywords[0]); ++i) { + new_symbol(type_qualifiers, keywords[i], NULL, DS_NONE); + } +} + +/* Process the C source file. Write function prototypes to the standard + * output. Convert function definitions and write the converted source + * code to a temporary file. + */ +void +process_file (FILE *infile, char *name) +{ + char *s; + + if (strlen(name) > 2) { + s = name + strlen(name) - 2; + if (*s == '.') { + ++s; + if (*s == 'l' || *s == 'y') + BEGIN LEXYACC; +#if defined(MSDOS) || defined(OS2) + if (*s == 'L' || *s == 'Y') + BEGIN LEXYACC; +#endif + } + } + + included_files = new_symbol_table(); + typedef_names = new_symbol_table(); + define_names = new_symbol_table(); + inc_depth = -1; + curly = 0; + ly_count = 0; + func_params = NULL; + yyin = infile; + include_file(strcpy(base_file, name), func_style != FUNC_NONE); + if (file_comments) { +#if OPT_LINTLIBRARY + if (lintLibrary()) { + put_blankline(stdout); + begin_tracking(); + } +#endif + put_string(stdout, "/* "); + put_string(stdout, cur_file_name()); + put_string(stdout, " */\n"); + } + yyparse(); + free_symbol_table(define_names); + free_symbol_table(typedef_names); + free_symbol_table(included_files); +} + +#ifdef NO_LEAKS +void +free_parser(void) +{ + free_symbol_table (type_qualifiers); +#ifdef FLEX_SCANNER + if (yy_current_buffer != 0) + yy_delete_buffer(yy_current_buffer); +#endif +} +#endif diff --git a/usr.bin/yacc/tests/legacy_test.sh b/usr.bin/yacc/tests/legacy_test.sh new file mode 100644 index 0000000..1b6b806 --- /dev/null +++ b/usr.bin/yacc/tests/legacy_test.sh @@ -0,0 +1,6 @@ +#!/bin/sh +# $FreeBSD$ + +SRCDIR="$(dirname "${0}")"; export SRCDIR + +m4 "${SRCDIR}/../regress.m4" "${SRCDIR}/regress.sh" | sh diff --git a/usr.bin/yacc/tests/pure_calc.y b/usr.bin/yacc/tests/pure_calc.y new file mode 100644 index 0000000..3cd0433 --- /dev/null +++ b/usr.bin/yacc/tests/pure_calc.y @@ -0,0 +1,116 @@ +%{ +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +#ifdef YYBISON +#define YYSTYPE int +#define YYLEX_PARAM &yylval +#define YYLEX_DECL() yylex(YYSTYPE *yylval) +#define YYERROR_DECL() yyerror(const char *s) +int YYLEX_DECL(); +static void YYERROR_DECL(); +#endif + +%} + +%start list + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr '+' expr + { $$ = $1 + $3; } + | expr '-' expr + { $$ = $1 - $3; } + | expr '*' expr + { $$ = $1 * $3; } + | expr '/' expr + { $$ = $1 / $3; } + | expr '%' expr + { $$ = $1 % $3; } + | expr '&' expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | '-' expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; base = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = base * $1 + $2; } + ; + +%% /* start of programs */ + +#ifdef YYBYACC +static int YYLEX_DECL(); +#endif + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +YYERROR_DECL() +{ + fprintf(stderr, "%s\n", s); +} + +int +YYLEX_DECL() +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + *yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + *yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/pure_error.y b/usr.bin/yacc/tests/pure_error.y new file mode 100644 index 0000000..fe7a3c3 --- /dev/null +++ b/usr.bin/yacc/tests/pure_error.y @@ -0,0 +1,41 @@ +%{ + +#ifdef YYBISON +#define YYSTYPE int +#define YYLEX_PARAM &yylval +#define YYLEX_DECL() yylex(YYSTYPE *yylval) +#define YYERROR_DECL() yyerror(const char *s) +int YYLEX_DECL(); +static void YYERROR_DECL(); +#endif + +%} + +%% +S: error +%% + +#include <stdio.h> + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main(void) +{ + printf("yyparse() = %d\n", yyparse()); + return 0; +} + +int +yylex(YYSTYPE *value) +{ + return value ? 0 : -1; +} + +static void +yyerror(const char* s) +{ + printf("%s\n", s); +} diff --git a/usr.bin/yacc/tests/quote_calc.y b/usr.bin/yacc/tests/quote_calc.y new file mode 100644 index 0000000..9304dd8 --- /dev/null +++ b/usr.bin/yacc/tests/quote_calc.y @@ -0,0 +1,112 @@ +%{ +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +%} + +%start list + +%token OP_ADD "ADD" +%token OP_SUB "SUB" +%token OP_MUL "MUL" +%token OP_DIV "DIV" +%token OP_MOD "MOD" +%token OP_AND "AND" + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr OP_ADD expr + { $$ = $1 + $3; } + | expr OP_SUB expr + { $$ = $1 - $3; } + | expr OP_MUL expr + { $$ = $1 * $3; } + | expr OP_DIV expr + { $$ = $1 / $3; } + | expr OP_MOD expr + { $$ = $1 % $3; } + | expr OP_AND expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | OP_SUB expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; base = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = base * $1 + $2; } + ; + +%% /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/quote_calc2.y b/usr.bin/yacc/tests/quote_calc2.y new file mode 100644 index 0000000..ab72a28 --- /dev/null +++ b/usr.bin/yacc/tests/quote_calc2.y @@ -0,0 +1,112 @@ +%{ +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +%} + +%start list + +%token OP_ADD "ADD" +%token OP_SUB "SUB" +%token OP_MUL "MUL" +%token OP_DIV "DIV" +%token OP_MOD "MOD" +%token OP_AND "AND" + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr "ADD" expr + { $$ = $1 + $3; } + | expr "SUB" expr + { $$ = $1 - $3; } + | expr "MUL" expr + { $$ = $1 * $3; } + | expr "DIV" expr + { $$ = $1 / $3; } + | expr "MOD" expr + { $$ = $1 % $3; } + | expr "AND" expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | "SUB" expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; base = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = base * $1 + $2; } + ; + +%% /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/quote_calc3.y b/usr.bin/yacc/tests/quote_calc3.y new file mode 100644 index 0000000..5feeb4a --- /dev/null +++ b/usr.bin/yacc/tests/quote_calc3.y @@ -0,0 +1,112 @@ +%{ +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +%} + +%start list + +%token OP_ADD "ADD-operator" +%token OP_SUB "SUB-operator" +%token OP_MUL "MUL-operator" +%token OP_DIV "DIV-operator" +%token OP_MOD "MOD-operator" +%token OP_AND "AND-operator" + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr OP_ADD expr + { $$ = $1 + $3; } + | expr OP_SUB expr + { $$ = $1 - $3; } + | expr OP_MUL expr + { $$ = $1 * $3; } + | expr OP_DIV expr + { $$ = $1 / $3; } + | expr OP_MOD expr + { $$ = $1 % $3; } + | expr OP_AND expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | OP_SUB expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; base = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = base * $1 + $2; } + ; + +%% /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/quote_calc4.y b/usr.bin/yacc/tests/quote_calc4.y new file mode 100644 index 0000000..34b790e --- /dev/null +++ b/usr.bin/yacc/tests/quote_calc4.y @@ -0,0 +1,112 @@ +%{ +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +%} + +%start list + +%token OP_ADD "ADD-operator" +%token OP_SUB "SUB-operator" +%token OP_MUL "MUL-operator" +%token OP_DIV "DIV-operator" +%token OP_MOD "MOD-operator" +%token OP_AND "AND-operator" + +%token DIGIT LETTER + +%left '|' +%left '&' +%left '+' '-' +%left '*' '/' '%' +%left UMINUS /* supplies precedence for unary minus */ + +%% /* beginning of rules section */ + +list : /* empty */ + | list stat '\n' + | list error '\n' + { yyerrok ; } + ; + +stat : expr + { printf("%d\n",$1);} + | LETTER '=' expr + { regs[$1] = $3; } + ; + +expr : '(' expr ')' + { $$ = $2; } + | expr "ADD-operator" expr + { $$ = $1 + $3; } + | expr "SUB-operator" expr + { $$ = $1 - $3; } + | expr "MUL-operator" expr + { $$ = $1 * $3; } + | expr "DIV-operator" expr + { $$ = $1 / $3; } + | expr "MOD-operator" expr + { $$ = $1 % $3; } + | expr "AND-operator" expr + { $$ = $1 & $3; } + | expr '|' expr + { $$ = $1 | $3; } + | "SUB-operator" expr %prec UMINUS + { $$ = - $2; } + | LETTER + { $$ = regs[$1]; } + | number + ; + +number: DIGIT + { $$ = $1; base = ($1==0) ? 8 : 10; } + | number DIGIT + { $$ = base * $1 + $2; } + ; + +%% /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} diff --git a/usr.bin/yacc/tests/regress.00.out b/usr.bin/yacc/tests/regress.00.out new file mode 100644 index 0000000..39a8ca2 --- /dev/null +++ b/usr.bin/yacc/tests/regress.00.out @@ -0,0 +1,386 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, +}; +static const short yylen[] = { 2, + 0, +}; +static const short yydefred[] = { 1, + 0, +}; +static const short yydgoto[] = { 1, +}; +static const short yysindex[] = { 0, + 0, +}; +static const short yyrindex[] = { 0, + 0, +}; +static const short yygindex[] = { 0, +}; +#define YYTABLESIZE 0 +static const short yytable[] = { 0, +}; +static const short yycheck[] = { -1, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 0 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : rule", +"rule :", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.01.out b/usr.bin/yacc/tests/regress.01.out new file mode 100644 index 0000000..8187502 --- /dev/null +++ b/usr.bin/yacc/tests/regress.01.out @@ -0,0 +1,589 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "calc.y" +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +extern int yylex(void); +static void yyerror(const char *s); + +#line 29 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define DIGIT 257 +#define LETTER 258 +#define UMINUS 259 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 17, 0, 0, 0, 0, 0, 0, 3, + 0, 15, 14, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 9, + 10, 11, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -40, -7, 0, -55, -38, -38, 1, -29, -247, 0, + -38, 0, 0, 22, 0, -38, -38, -38, -38, -38, + -38, -38, 0, -29, 0, 51, 60, -20, -20, 0, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 2, 0, 0, 0, 9, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, -6, 14, 5, 13, 0, + 0, 0, +}; +static const short yygindex[] = { 0, + 0, 65, 0, +}; +#define YYTABLESIZE 220 +static const short yytable[] = { 6, + 16, 6, 10, 13, 5, 11, 5, 22, 17, 23, + 15, 15, 20, 18, 7, 19, 22, 21, 4, 5, + 0, 20, 8, 12, 0, 0, 21, 16, 16, 0, + 0, 16, 16, 16, 13, 16, 0, 16, 15, 15, + 0, 0, 7, 15, 15, 7, 15, 7, 15, 7, + 8, 12, 0, 8, 12, 8, 0, 8, 22, 17, + 0, 0, 25, 20, 18, 0, 19, 0, 21, 13, + 14, 0, 0, 0, 0, 24, 0, 0, 0, 0, + 26, 27, 28, 29, 30, 31, 32, 22, 17, 0, + 0, 0, 20, 18, 16, 19, 22, 21, 0, 0, + 0, 20, 18, 0, 19, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 8, 12, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 3, 4, 3, 12, +}; +static const short yycheck[] = { 40, + 10, 40, 10, 10, 45, 61, 45, 37, 38, 257, + 10, 10, 42, 43, 10, 45, 37, 47, 10, 10, + -1, 42, 10, 10, -1, -1, 47, 37, 38, -1, + -1, 41, 42, 43, 41, 45, -1, 47, 37, 38, + -1, -1, 38, 42, 43, 41, 45, 43, 47, 45, + 38, 38, -1, 41, 41, 43, -1, 45, 37, 38, + -1, -1, 41, 42, 43, -1, 45, -1, 47, 5, + 6, -1, -1, -1, -1, 11, -1, -1, -1, -1, + 16, 17, 18, 19, 20, 21, 22, 37, 38, -1, + -1, -1, 42, 43, 124, 45, 37, 47, -1, -1, + -1, 42, 43, -1, 45, -1, 47, -1, -1, -1, + -1, -1, -1, -1, 124, -1, -1, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, 124, -1, + -1, -1, -1, -1, -1, -1, 124, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, 257, 258, 257, 258, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 259 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"DIGIT","LETTER","UMINUS","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr '*' expr", +"expr : expr '/' expr", +"expr : expr '%' expr", +"expr : expr '&' expr", +"expr : expr '|' expr", +"expr : '-' expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 66 "calc.y" + /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} +#line 267 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 28 "calc.y" + { yyerrok ; } +break; +case 4: +#line 32 "calc.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 34 "calc.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 38 "calc.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 40 "calc.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 42 "calc.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 44 "calc.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 46 "calc.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 48 "calc.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 50 "calc.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 52 "calc.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 54 "calc.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 56 "calc.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 61 "calc.y" + { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 63 "calc.y" + { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 529 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.02.out b/usr.bin/yacc/tests/regress.02.out new file mode 100644 index 0000000..30de536 --- /dev/null +++ b/usr.bin/yacc/tests/regress.02.out @@ -0,0 +1,831 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "calc1.y" + +/* http://dinosaur.compilertools.net/yacc/index.html */ + +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <math.h> + +typedef struct interval +{ + double lo, hi; +} +INTERVAL; + +INTERVAL vmul(double, double, INTERVAL); +INTERVAL vdiv(double, double, INTERVAL); + +extern int yylex(void); +static void yyerror(const char *s); + +int dcheck(INTERVAL); + +double dreg[26]; +INTERVAL vreg[26]; + +#line 31 "calc1.y" +#ifdef YYSTYPE +#undef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +#endif +#ifndef YYSTYPE_IS_DECLARED +#define YYSTYPE_IS_DECLARED 1 +typedef union +{ + int ival; + double dval; + INTERVAL vval; +} YYSTYPE; +#endif /* !YYSTYPE_IS_DECLARED */ +#line 59 "/dev/stdout" + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define DREG 257 +#define VREG 258 +#define CONST 259 +#define UMINUS 260 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 3, 3, 0, 0, 0, 0, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, +}; +static const short yylen[] = { 2, + 0, 2, 2, 2, 4, 4, 2, 1, 1, 3, + 3, 3, 3, 2, 3, 1, 5, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 3, +}; +static const short yydefred[] = { 0, + 0, 0, 0, 8, 0, 0, 0, 0, 0, 7, + 0, 0, 9, 18, 14, 27, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 15, 0, 28, 0, 0, 0, 0, + 12, 24, 13, 26, 0, 0, 23, 25, 14, 0, + 0, 0, 0, 0, 5, 6, 0, 0, 0, 12, + 13, 17, +}; +static const short yydgoto[] = { 7, + 32, 9, 0, +}; +static const short yysindex[] = { -40, + -8, -48, -47, 0, -37, -37, 0, 2, 17, 0, + -34, -37, 0, 0, 0, 0, -25, 90, -37, -37, + -37, -37, 0, -37, -37, -37, -37, 0, -34, -34, + 25, 125, 31, 0, -34, 0, -11, 37, -11, 37, + 0, 0, 0, 0, 37, 37, 0, 0, 0, 111, + -34, -34, -34, -34, 0, 0, 118, 69, 69, 0, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 38, 44, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, -9, 0, 0, 0, 0, 51, -3, 56, 61, + 0, 0, 0, 0, 67, 72, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 78, 83, 0, + 0, 0, +}; +static const short yygindex[] = { 0, + 4, 124, 0, +}; +#define YYTABLESIZE 225 +static const short yytable[] = { 6, + 16, 10, 6, 8, 5, 30, 20, 5, 15, 17, + 29, 23, 11, 12, 31, 34, 21, 19, 35, 20, + 0, 22, 37, 39, 41, 43, 28, 0, 0, 0, + 21, 16, 49, 50, 55, 22, 0, 20, 57, 20, + 56, 20, 0, 21, 19, 0, 20, 9, 22, 0, + 0, 0, 0, 18, 58, 59, 60, 61, 26, 24, + 10, 25, 0, 27, 0, 11, 53, 51, 0, 52, + 22, 54, 26, 24, 0, 25, 19, 27, 26, 9, + 9, 21, 9, 27, 9, 18, 18, 10, 18, 0, + 18, 10, 11, 10, 10, 10, 11, 0, 11, 11, + 11, 22, 0, 22, 0, 22, 0, 19, 0, 19, + 53, 19, 21, 0, 21, 54, 21, 0, 10, 0, + 10, 0, 10, 11, 0, 11, 0, 11, 16, 18, + 36, 26, 24, 0, 25, 33, 27, 0, 0, 0, + 0, 0, 38, 40, 42, 44, 0, 45, 46, 47, + 48, 34, 53, 51, 0, 52, 0, 54, 62, 53, + 51, 0, 52, 0, 54, 0, 21, 19, 0, 20, + 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 3, 4, 13, + 14, 4, 13, 0, 4, +}; +static const short yycheck[] = { 40, + 10, 10, 40, 0, 45, 40, 10, 45, 5, 6, + 45, 10, 61, 61, 11, 41, 42, 43, 44, 45, + -1, 47, 19, 20, 21, 22, 10, -1, -1, -1, + 42, 41, 29, 30, 10, 47, -1, 41, 35, 43, + 10, 45, -1, 42, 43, -1, 45, 10, 47, -1, + -1, -1, -1, 10, 51, 52, 53, 54, 42, 43, + 10, 45, -1, 47, -1, 10, 42, 43, -1, 45, + 10, 47, 42, 43, -1, 45, 10, 47, 42, 42, + 43, 10, 45, 47, 47, 42, 43, 10, 45, -1, + 47, 41, 10, 43, 44, 45, 41, -1, 43, 44, + 45, 41, -1, 43, -1, 45, -1, 41, -1, 43, + 42, 45, 41, -1, 43, 47, 45, -1, 41, -1, + 43, -1, 45, 41, -1, 43, -1, 45, 5, 6, + 41, 42, 43, -1, 45, 12, 47, -1, -1, -1, + -1, -1, 19, 20, 21, 22, -1, 24, 25, 26, + 27, 41, 42, 43, -1, 45, -1, 47, 41, 42, + 43, -1, 45, -1, 47, -1, 42, 43, -1, 45, + -1, 47, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, 257, 258, 259, 257, + 258, 259, 257, -1, 259, +}; +#define YYFINAL 7 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 260 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,"'('","')'","'*'","'+'","','","'-'",0,"'/'",0,0,0,0,0,0,0,0,0, +0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,"DREG","VREG","CONST","UMINUS","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : line", +"lines :", +"lines : lines line", +"line : dexp '\\n'", +"line : vexp '\\n'", +"line : DREG '=' dexp '\\n'", +"line : VREG '=' vexp '\\n'", +"line : error '\\n'", +"dexp : CONST", +"dexp : DREG", +"dexp : dexp '+' dexp", +"dexp : dexp '-' dexp", +"dexp : dexp '*' dexp", +"dexp : dexp '/' dexp", +"dexp : '-' dexp", +"dexp : '(' dexp ')'", +"vexp : dexp", +"vexp : '(' dexp ',' dexp ')'", +"vexp : VREG", +"vexp : vexp '+' vexp", +"vexp : dexp '+' vexp", +"vexp : vexp '-' vexp", +"vexp : dexp '-' vexp", +"vexp : vexp '*' vexp", +"vexp : dexp '*' vexp", +"vexp : vexp '/' vexp", +"vexp : dexp '/' vexp", +"vexp : '-' vexp", +"vexp : '(' vexp ')'", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 176 "calc1.y" + /* beginning of subroutines section */ + +#define BSZ 50 /* buffer size for floating point numbers */ + + /* lexical analysis */ + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) +{ + int c; + + while ((c = getchar()) == ' ') + { /* skip over blanks */ + } + + if (isupper(c)) + { + yylval.ival = c - 'A'; + return (VREG); + } + if (islower(c)) + { + yylval.ival = c - 'a'; + return (DREG); + } + + if (isdigit(c) || c == '.') + { + /* gobble up digits, points, exponents */ + char buf[BSZ + 1], *cp = buf; + int dot = 0, expr = 0; + + for (; (cp - buf) < BSZ; ++cp, c = getchar()) + { + + *cp = c; + if (isdigit(c)) + continue; + if (c == '.') + { + if (dot++ || expr) + return ('.'); /* will cause syntax error */ + continue; + } + + if (c == 'e') + { + if (expr++) + return ('e'); /* will cause syntax error */ + continue; + } + + /* end of number */ + break; + } + *cp = '\0'; + + if ((cp - buf) >= BSZ) + printf("constant too long: truncated\n"); + else + ungetc(c, stdin); /* push back last char read */ + yylval.dval = atof(buf); + return (CONST); + } + return (c); +} + +static INTERVAL +hilo(double a, double b, double c, double d) +{ + /* returns the smallest interval containing a, b, c, and d */ + /* used by *, / routines */ + INTERVAL v; + + if (a > b) + { + v.hi = a; + v.lo = b; + } + else + { + v.hi = b; + v.lo = a; + } + + if (c > d) + { + if (c > v.hi) + v.hi = c; + if (d < v.lo) + v.lo = d; + } + else + { + if (d > v.hi) + v.hi = d; + if (c < v.lo) + v.lo = c; + } + return (v); +} + +INTERVAL +vmul(double a, double b, INTERVAL v) +{ + return (hilo(a * v.hi, a * v.lo, b * v.hi, b * v.lo)); +} + +int +dcheck(INTERVAL v) +{ + if (v.hi >= 0. && v.lo <= 0.) + { + printf("divisor interval contains 0.\n"); + return (1); + } + return (0); +} + +INTERVAL +vdiv(double a, double b, INTERVAL v) +{ + return (hilo(a / v.hi, a / v.lo, b / v.hi, b / v.lo)); +} +#line 406 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 57 "calc1.y" + { + (void) printf("%15.8f\n", yystack.l_mark[-1].dval); + } +break; +case 4: +#line 61 "calc1.y" + { + (void) printf("(%15.8f, %15.8f)\n", yystack.l_mark[-1].vval.lo, yystack.l_mark[-1].vval.hi); + } +break; +case 5: +#line 65 "calc1.y" + { + dreg[yystack.l_mark[-3].ival] = yystack.l_mark[-1].dval; + } +break; +case 6: +#line 69 "calc1.y" + { + vreg[yystack.l_mark[-3].ival] = yystack.l_mark[-1].vval; + } +break; +case 7: +#line 73 "calc1.y" + { + yyerrok; + } +break; +case 9: +#line 80 "calc1.y" + { + yyval.dval = dreg[yystack.l_mark[0].ival]; + } +break; +case 10: +#line 84 "calc1.y" + { + yyval.dval = yystack.l_mark[-2].dval + yystack.l_mark[0].dval; + } +break; +case 11: +#line 88 "calc1.y" + { + yyval.dval = yystack.l_mark[-2].dval - yystack.l_mark[0].dval; + } +break; +case 12: +#line 92 "calc1.y" + { + yyval.dval = yystack.l_mark[-2].dval * yystack.l_mark[0].dval; + } +break; +case 13: +#line 96 "calc1.y" + { + yyval.dval = yystack.l_mark[-2].dval / yystack.l_mark[0].dval; + } +break; +case 14: +#line 100 "calc1.y" + { + yyval.dval = -yystack.l_mark[0].dval; + } +break; +case 15: +#line 104 "calc1.y" + { + yyval.dval = yystack.l_mark[-1].dval; + } +break; +case 16: +#line 110 "calc1.y" + { + yyval.vval.hi = yyval.vval.lo = yystack.l_mark[0].dval; + } +break; +case 17: +#line 114 "calc1.y" + { + yyval.vval.lo = yystack.l_mark[-3].dval; + yyval.vval.hi = yystack.l_mark[-1].dval; + if ( yyval.vval.lo > yyval.vval.hi ) + { + (void) printf("interval out of order\n"); + YYERROR; + } + } +break; +case 18: +#line 124 "calc1.y" + { + yyval.vval = vreg[yystack.l_mark[0].ival]; + } +break; +case 19: +#line 128 "calc1.y" + { + yyval.vval.hi = yystack.l_mark[-2].vval.hi + yystack.l_mark[0].vval.hi; + yyval.vval.lo = yystack.l_mark[-2].vval.lo + yystack.l_mark[0].vval.lo; + } +break; +case 20: +#line 133 "calc1.y" + { + yyval.vval.hi = yystack.l_mark[-2].dval + yystack.l_mark[0].vval.hi; + yyval.vval.lo = yystack.l_mark[-2].dval + yystack.l_mark[0].vval.lo; + } +break; +case 21: +#line 138 "calc1.y" + { + yyval.vval.hi = yystack.l_mark[-2].vval.hi - yystack.l_mark[0].vval.lo; + yyval.vval.lo = yystack.l_mark[-2].vval.lo - yystack.l_mark[0].vval.hi; + } +break; +case 22: +#line 143 "calc1.y" + { + yyval.vval.hi = yystack.l_mark[-2].dval - yystack.l_mark[0].vval.lo; + yyval.vval.lo = yystack.l_mark[-2].dval - yystack.l_mark[0].vval.hi; + } +break; +case 23: +#line 148 "calc1.y" + { + yyval.vval = vmul( yystack.l_mark[-2].vval.lo, yystack.l_mark[-2].vval.hi, yystack.l_mark[0].vval ); + } +break; +case 24: +#line 152 "calc1.y" + { + yyval.vval = vmul (yystack.l_mark[-2].dval, yystack.l_mark[-2].dval, yystack.l_mark[0].vval ); + } +break; +case 25: +#line 156 "calc1.y" + { + if (dcheck(yystack.l_mark[0].vval)) YYERROR; + yyval.vval = vdiv ( yystack.l_mark[-2].vval.lo, yystack.l_mark[-2].vval.hi, yystack.l_mark[0].vval ); + } +break; +case 26: +#line 161 "calc1.y" + { + if (dcheck ( yystack.l_mark[0].vval )) YYERROR; + yyval.vval = vdiv (yystack.l_mark[-2].dval, yystack.l_mark[-2].dval, yystack.l_mark[0].vval ); + } +break; +case 27: +#line 166 "calc1.y" + { + yyval.vval.hi = -yystack.l_mark[0].vval.lo; + yyval.vval.lo = -yystack.l_mark[0].vval.hi; + } +break; +case 28: +#line 171 "calc1.y" + { + yyval.vval = yystack.l_mark[-1].vval; + } +break; +#line 771 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.03.out b/usr.bin/yacc/tests/regress.03.out new file mode 100644 index 0000000..a8c9f8c --- /dev/null +++ b/usr.bin/yacc/tests/regress.03.out @@ -0,0 +1,603 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 1 + +#line 9 "calc3.y" +# include <stdio.h> +# include <ctype.h> + +#ifdef YYBISON +#define YYSTYPE int +#define YYLEX_PARAM base +#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM) +#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s) +int YYLEX_DECL(); +static void YYERROR_DECL(); +#endif + +#line 32 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(int regs[26], int * base) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# ifdef YYLEX_PARAM_TYPE +# define YYLEX_DECL() yylex(YYSTYPE *yylval, YYLEX_PARAM_TYPE YYLEX_PARAM) +# else +# define YYLEX_DECL() yylex(YYSTYPE *yylval, void * YYLEX_PARAM) +# endif +# define YYLEX yylex(&yylval, YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(YYSTYPE *yylval, int * base) +# define YYLEX yylex(&yylval, base) +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(int regs[26], int * base, const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(regs, base, msg) +#endif + +extern int YYPARSE_DECL(); + +#define DIGIT 257 +#define LETTER 258 +#define UMINUS 259 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 17, 0, 0, 0, 0, 0, 0, 3, + 0, 15, 14, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 9, + 10, 11, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -40, -7, 0, -55, -38, -38, 1, -29, -247, 0, + -38, 0, 0, 22, 0, -38, -38, -38, -38, -38, + -38, -38, 0, -29, 0, 51, 60, -20, -20, 0, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 2, 0, 0, 0, 9, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, -6, 14, 5, 13, 0, + 0, 0, +}; +static const short yygindex[] = { 0, + 0, 65, 0, +}; +#define YYTABLESIZE 220 +static const short yytable[] = { 6, + 16, 6, 10, 13, 5, 11, 5, 22, 17, 23, + 15, 15, 20, 18, 7, 19, 22, 21, 4, 5, + 0, 20, 8, 12, 0, 0, 21, 16, 16, 0, + 0, 16, 16, 16, 13, 16, 0, 16, 15, 15, + 0, 0, 7, 15, 15, 7, 15, 7, 15, 7, + 8, 12, 0, 8, 12, 8, 0, 8, 22, 17, + 0, 0, 25, 20, 18, 0, 19, 0, 21, 13, + 14, 0, 0, 0, 0, 24, 0, 0, 0, 0, + 26, 27, 28, 29, 30, 31, 32, 22, 17, 0, + 0, 0, 20, 18, 16, 19, 22, 21, 0, 0, + 0, 20, 18, 0, 19, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 8, 12, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 3, 4, 3, 12, +}; +static const short yycheck[] = { 40, + 10, 40, 10, 10, 45, 61, 45, 37, 38, 257, + 10, 10, 42, 43, 10, 45, 37, 47, 10, 10, + -1, 42, 10, 10, -1, -1, 47, 37, 38, -1, + -1, 41, 42, 43, 41, 45, -1, 47, 37, 38, + -1, -1, 38, 42, 43, 41, 45, 43, 47, 45, + 38, 38, -1, 41, 41, 43, -1, 45, 37, 38, + -1, -1, 41, 42, 43, -1, 45, -1, 47, 5, + 6, -1, -1, -1, -1, 11, -1, -1, -1, -1, + 16, 17, 18, 19, 20, 21, 22, 37, 38, -1, + -1, -1, 42, 43, 124, 45, 37, 47, -1, -1, + -1, 42, 43, -1, 45, -1, 47, -1, -1, -1, + -1, -1, -1, -1, 124, -1, -1, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, 124, -1, + -1, -1, -1, -1, -1, -1, 124, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, 257, 258, 257, 258, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 259 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"DIGIT","LETTER","UMINUS","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr '*' expr", +"expr : expr '/' expr", +"expr : expr '%' expr", +"expr : expr '&' expr", +"expr : expr '|' expr", +"expr : '-' expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +#line 76 "calc3.y" + /* start of programs */ + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main (void) +{ + int regs[26]; + int base = 10; + + while(!feof(stdin)) { + yyparse(regs, &base); + } + return 0; +} + +static void +YYERROR_DECL() +{ + fprintf(stderr, "%s\n", s); +} + +int +YYLEX_DECL() +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + *yylval = (c - 'a'); + return ( LETTER ); + } + if( isdigit( c )) { + *yylval = (c - '0') % (*base); + return ( DIGIT ); + } + return( c ); +} +#line 274 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yyerrflag; + int yychar; + YYSTYPE yyval; + YYSTYPE yylval; + + /* variables for the parser stack */ + YYSTACKDATA yystack; + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror(regs, base, "syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 38 "calc3.y" + { yyerrok ; } +break; +case 4: +#line 42 "calc3.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 44 "calc3.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 48 "calc3.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 50 "calc3.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 52 "calc3.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 54 "calc3.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 56 "calc3.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 58 "calc3.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 60 "calc3.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 62 "calc3.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 64 "calc3.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 66 "calc3.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 71 "calc3.y" + { yyval = yystack.l_mark[0]; (*base) = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 73 "calc3.y" + { yyval = (*base) * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 543 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror(regs, base, "yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.04.out b/usr.bin/yacc/tests/regress.04.out new file mode 100644 index 0000000..cd93e86 --- /dev/null +++ b/usr.bin/yacc/tests/regress.04.out @@ -0,0 +1,595 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "code_calc.y" +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +#ifdef YYBISON +int yylex(void); +static void yyerror(const char *s); +#endif + +#line 31 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define DIGIT 257 +#define LETTER 258 +#define UMINUS 259 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 17, 0, 0, 0, 0, 0, 0, 3, + 0, 15, 14, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 9, + 10, 11, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -40, -7, 0, -55, -38, -38, 1, -29, -247, 0, + -38, 0, 0, 22, 0, -38, -38, -38, -38, -38, + -38, -38, 0, -29, 0, 51, 60, -20, -20, 0, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 2, 0, 0, 0, 9, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, -6, 14, 5, 13, 0, + 0, 0, +}; +static const short yygindex[] = { 0, + 0, 65, 0, +}; +#define YYTABLESIZE 220 +static const short yytable[] = { 6, + 16, 6, 10, 13, 5, 11, 5, 22, 17, 23, + 15, 15, 20, 18, 7, 19, 22, 21, 4, 5, + 0, 20, 8, 12, 0, 0, 21, 16, 16, 0, + 0, 16, 16, 16, 13, 16, 0, 16, 15, 15, + 0, 0, 7, 15, 15, 7, 15, 7, 15, 7, + 8, 12, 0, 8, 12, 8, 0, 8, 22, 17, + 0, 0, 25, 20, 18, 0, 19, 0, 21, 13, + 14, 0, 0, 0, 0, 24, 0, 0, 0, 0, + 26, 27, 28, 29, 30, 31, 32, 22, 17, 0, + 0, 0, 20, 18, 16, 19, 22, 21, 0, 0, + 0, 20, 18, 0, 19, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 8, 12, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 3, 4, 3, 12, +}; +static const short yycheck[] = { 40, + 10, 40, 10, 10, 45, 61, 45, 37, 38, 257, + 10, 10, 42, 43, 10, 45, 37, 47, 10, 10, + -1, 42, 10, 10, -1, -1, 47, 37, 38, -1, + -1, 41, 42, 43, 41, 45, -1, 47, 37, 38, + -1, -1, 38, 42, 43, 41, 45, 43, 47, 45, + 38, 38, -1, 41, 41, 43, -1, 45, 37, 38, + -1, -1, 41, 42, 43, -1, 45, -1, 47, 5, + 6, -1, -1, -1, -1, 11, -1, -1, -1, -1, + 16, 17, 18, 19, 20, 21, 22, 37, 38, -1, + -1, -1, 42, 43, 124, 45, 37, 47, -1, -1, + -1, 42, 43, -1, 45, -1, 47, -1, -1, -1, + -1, -1, -1, -1, 124, -1, -1, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, 124, -1, + -1, -1, -1, -1, -1, -1, 124, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, 257, 258, 257, 258, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 259 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"DIGIT","LETTER","UMINUS","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr '*' expr", +"expr : expr '/' expr", +"expr : expr '%' expr", +"expr : expr '&' expr", +"expr : expr '|' expr", +"expr : '-' expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 68 "code_calc.y" + /* start of programs */ + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} +#line 273 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 30 "code_calc.y" + { yyerrok ; } +break; +case 4: +#line 34 "code_calc.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 36 "code_calc.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 40 "code_calc.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 42 "code_calc.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 44 "code_calc.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 46 "code_calc.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 48 "code_calc.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 50 "code_calc.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 52 "code_calc.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 54 "code_calc.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 56 "code_calc.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 58 "code_calc.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 63 "code_calc.y" + { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 65 "code_calc.y" + { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 535 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.05.out b/usr.bin/yacc/tests/regress.05.out new file mode 100644 index 0000000..2fbf0d9 --- /dev/null +++ b/usr.bin/yacc/tests/regress.05.out @@ -0,0 +1,425 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "code_error.y" + +#ifdef YYBISON +int yylex(void); +static void yyerror(const char *); +#endif + +#line 26 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, +}; +static const short yylen[] = { 2, + 1, +}; +static const short yydefred[] = { 0, + 1, 0, +}; +static const short yydgoto[] = { 2, +}; +static const short yysindex[] = { -256, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, +}; +static const short yygindex[] = { 0, +}; +#define YYTABLESIZE 0 +static const short yytable[] = { 1, +}; +static const short yycheck[] = { 256, +}; +#define YYFINAL 2 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 0 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : S", +"S : error", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 12 "code_error.y" + +#include <stdio.h> + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main(void) +{ + printf("yyparse() = %d\n", yyparse()); + return 0; +} + +int +yylex(void) +{ + return -1; +} + +static void +yyerror(const char* s) +{ + printf("%s\n", s); +} +#line 164 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.06.out b/usr.bin/yacc/tests/regress.06.out new file mode 100644 index 0000000..d2305e1 --- /dev/null +++ b/usr.bin/yacc/tests/regress.06.out @@ -0,0 +1,417 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "error.y" +int yylex(void); +static void yyerror(const char *); +#line 22 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, +}; +static const short yylen[] = { 2, + 1, +}; +static const short yydefred[] = { 0, + 1, 0, +}; +static const short yydgoto[] = { 2, +}; +static const short yysindex[] = { -256, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, +}; +static const short yygindex[] = { 0, +}; +#define YYTABLESIZE 0 +static const short yytable[] = { 1, +}; +static const short yycheck[] = { 256, +}; +#define YYFINAL 2 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 0 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : S", +"S : error", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 8 "error.y" + +#include <stdio.h> + +int +main(void) +{ + printf("yyparse() = %d\n", yyparse()); + return 0; +} + +int +yylex(void) +{ + return -1; +} + +static void +yyerror(const char* s) +{ + printf("%s\n", s); +} +#line 156 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.07.out b/usr.bin/yacc/tests/regress.07.out new file mode 100644 index 0000000..ae185a0 --- /dev/null +++ b/usr.bin/yacc/tests/regress.07.out @@ -0,0 +1,1912 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 26 "ftp.y" + +/* sccsid[] = "@(#)ftpcmd.y 5.20.1.1 (Berkeley) 3/2/89"; */ + +#include <sys/param.h> +#include <sys/socket.h> + +#include <netinet/in.h> + +#include <arpa/ftp.h> + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <signal.h> +#include <ctype.h> +#include <pwd.h> +#include <setjmp.h> +#include <syslog.h> +#include <sys/stat.h> +#include <string.h> +#include <time.h> +#include <assert.h> + +#ifdef YYBISON +int yylex(void); +static void yyerror(const char *); +#endif + +extern struct sockaddr_in data_dest; +extern int logged_in; +extern struct passwd *pw; +extern int guest; +extern int logging; +extern int type; +extern int form; +extern int debug; +extern int timeout; +extern int maxtimeout; +extern int pdata; +extern char hostname[], remotehost[]; +extern char proctitle[]; +extern char *globerr; +extern int usedefault; +extern int transflag; +extern char tmpline[]; + +extern char **glob(char *); +extern char *renamefrom(char *); +extern void cwd(const char *); + +extern void dologout(int); +extern void fatal(const char *); +extern void makedir(const char *); +extern void nack(const char *); +extern void pass(const char *); +extern void passive(void); +extern void pwd(void); +extern void removedir(char *); +extern void renamecmd(char *, char *); +extern void retrieve(const char *, const char *); +extern void send_file_list(const char *); +extern void statcmd(void); +extern void statfilecmd(const char *); +extern void store(char *, const char *, int); +extern void user(const char *); + +extern void perror_reply(int, const char *, ...); +extern void reply(int, const char *, ...); +extern void lreply(int, const char *, ...); + +static int cmd_type; +static int cmd_form; +static int cmd_bytesz; +char cbuf[512]; +char *fromname; + +struct tab { + const char *name; + short token; + short state; + short implemented; /* 1 if command is implemented */ + const char *help; +}; + +static char * copy(const char *); + +#ifdef YYBISON +static void sizecmd(char *filename); +static void help(struct tab *ctab, char *s); +struct tab cmdtab[]; +struct tab sitetab[]; +#endif + +static void +yyerror(const char *msg) +{ + perror(msg); +} +#line 118 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define A 257 +#define B 258 +#define C 259 +#define E 260 +#define F 261 +#define I 262 +#define L 263 +#define N 264 +#define P 265 +#define R 266 +#define S 267 +#define T 268 +#define SP 269 +#define CRLF 270 +#define COMMA 271 +#define STRING 272 +#define NUMBER 273 +#define USER 274 +#define PASS 275 +#define ACCT 276 +#define REIN 277 +#define QUIT 278 +#define PORT 279 +#define PASV 280 +#define TYPE 281 +#define STRU 282 +#define MODE 283 +#define RETR 284 +#define STOR 285 +#define APPE 286 +#define MLFL 287 +#define MAIL 288 +#define MSND 289 +#define MSOM 290 +#define MSAM 291 +#define MRSQ 292 +#define MRCP 293 +#define ALLO 294 +#define REST 295 +#define RNFR 296 +#define RNTO 297 +#define ABOR 298 +#define DELE 299 +#define CWD 300 +#define LIST 301 +#define NLST 302 +#define SITE 303 +#define STAT 304 +#define HELP 305 +#define NOOP 306 +#define MKD 307 +#define RMD 308 +#define PWD 309 +#define CDUP 310 +#define STOU 311 +#define SMNT 312 +#define SYST 313 +#define SIZE 314 +#define MDTM 315 +#define UMASK 316 +#define IDLE 317 +#define CHMOD 318 +#define LEXERR 319 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 3, 4, 4, + 12, 5, 13, 13, 13, 6, 6, 6, 6, 6, + 6, 6, 6, 7, 7, 7, 8, 8, 8, 10, + 14, 11, 9, +}; +static const short yylen[] = { 2, + 0, 2, 2, 4, 4, 4, 2, 4, 4, 4, + 4, 8, 5, 5, 5, 3, 5, 3, 5, 5, + 2, 5, 4, 2, 3, 5, 2, 4, 2, 5, + 5, 3, 3, 4, 6, 5, 7, 9, 4, 6, + 5, 2, 5, 5, 2, 2, 5, 1, 0, 1, + 1, 11, 1, 1, 1, 1, 3, 1, 3, 1, + 1, 3, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, +}; +static const short yydefred[] = { 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 73, 73, 73, 0, 73, 0, 0, 73, 73, 73, + 73, 0, 0, 0, 0, 73, 73, 73, 73, 73, + 0, 73, 73, 2, 3, 46, 0, 0, 45, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 24, 0, 0, 0, 0, 0, 21, 0, 0, 27, + 29, 0, 0, 0, 0, 0, 42, 0, 0, 48, + 0, 50, 0, 0, 0, 0, 0, 60, 0, 0, + 64, 66, 65, 0, 68, 69, 67, 0, 0, 0, + 0, 0, 0, 71, 0, 70, 0, 0, 25, 0, + 18, 0, 16, 0, 73, 0, 73, 0, 0, 0, + 0, 32, 33, 0, 0, 0, 4, 5, 0, 6, + 0, 0, 0, 51, 63, 8, 9, 10, 0, 0, + 0, 0, 11, 0, 23, 0, 0, 0, 0, 0, + 34, 0, 0, 39, 0, 0, 28, 0, 0, 0, + 0, 0, 0, 55, 53, 54, 57, 59, 62, 13, + 14, 15, 0, 47, 22, 26, 19, 17, 0, 0, + 36, 0, 0, 20, 30, 31, 41, 43, 44, 0, + 0, 35, 72, 0, 40, 0, 0, 0, 37, 0, + 0, 12, 0, 0, 38, 0, 0, 0, 52, +}; +static const short yydgoto[] = { 1, + 34, 35, 71, 73, 75, 80, 84, 88, 45, 95, + 184, 125, 157, 96, +}; +static const short yysindex[] = { 0, + -224, -247, -239, -236, -232, -222, -204, -200, -181, -177, + 0, 0, 0, -166, 0, -161, -199, 0, 0, 0, + 0, -160, -159, -264, -158, 0, 0, 0, 0, 0, + -157, 0, 0, 0, 0, 0, -167, -162, 0, -156, + 0, -250, -198, -165, -155, -154, -153, -151, -150, -152, + 0, -145, -252, -229, -217, -302, 0, -144, -146, 0, + 0, -142, -141, -140, -139, -137, 0, -136, -135, 0, + -134, 0, -133, -132, -130, -131, -128, 0, -249, -127, + 0, 0, 0, -126, 0, 0, 0, -125, -152, -152, + -152, -205, -152, 0, -124, 0, -152, -152, 0, -152, + 0, -143, 0, -173, 0, -171, 0, -152, -123, -152, + -152, 0, 0, -152, -152, -152, 0, 0, -138, 0, + -164, -164, -122, 0, 0, 0, 0, 0, -121, -120, + -118, -148, 0, -117, 0, -116, -115, -114, -113, -112, + 0, -163, -111, 0, -110, -109, 0, -107, -106, -105, + -104, -103, -129, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -101, 0, 0, 0, 0, 0, -100, -102, + 0, -98, -102, 0, 0, 0, 0, 0, 0, -99, + -97, 0, 0, -95, 0, -96, -94, -92, 0, -152, + -93, 0, -91, -90, 0, -88, -87, -86, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, -83, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -82, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -81, -80, 0, -158, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +static const short yygindex[] = { 0, + 0, 0, 0, 0, 0, 0, 0, 0, 16, -89, + -25, 35, 47, 0, +}; +#define YYTABLESIZE 190 +static const short yytable[] = { 129, + 130, 131, 104, 134, 59, 60, 76, 136, 137, 77, + 138, 78, 79, 105, 106, 107, 98, 99, 146, 123, + 148, 149, 36, 124, 150, 151, 152, 46, 47, 37, + 49, 2, 38, 52, 53, 54, 55, 39, 58, 100, + 101, 62, 63, 64, 65, 66, 40, 68, 69, 3, + 4, 102, 103, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 81, 132, 133, 41, 82, 83, 42, 14, + 51, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 43, 31, 32, + 33, 44, 85, 86, 154, 140, 141, 143, 144, 155, + 193, 87, 48, 156, 70, 170, 171, 50, 56, 72, + 57, 61, 67, 89, 90, 91, 74, 163, 93, 94, + 142, 92, 145, 97, 108, 109, 110, 111, 139, 112, + 113, 114, 115, 116, 153, 117, 118, 121, 119, 120, + 122, 180, 126, 127, 128, 135, 147, 186, 160, 161, + 124, 162, 164, 165, 166, 167, 168, 159, 173, 169, + 174, 172, 175, 176, 177, 178, 179, 181, 158, 182, + 183, 185, 190, 187, 189, 188, 191, 192, 195, 194, + 196, 0, 0, 198, 197, 73, 199, 49, 56, 58, +}; +static const short yycheck[] = { 89, + 90, 91, 305, 93, 269, 270, 257, 97, 98, 260, + 100, 262, 263, 316, 317, 318, 269, 270, 108, 269, + 110, 111, 270, 273, 114, 115, 116, 12, 13, 269, + 15, 256, 269, 18, 19, 20, 21, 270, 23, 269, + 270, 26, 27, 28, 29, 30, 269, 32, 33, 274, + 275, 269, 270, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 261, 269, 270, 270, 265, 266, 269, 294, + 270, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 269, 313, 314, + 315, 269, 258, 259, 259, 269, 270, 269, 270, 264, + 190, 267, 269, 268, 272, 269, 270, 269, 269, 272, + 270, 270, 270, 269, 269, 269, 273, 266, 269, 272, + 105, 273, 107, 269, 269, 272, 269, 269, 272, 270, + 270, 269, 269, 269, 273, 270, 270, 269, 271, 270, + 269, 271, 270, 270, 270, 270, 270, 173, 270, 270, + 273, 270, 270, 270, 270, 270, 270, 123, 269, 272, + 270, 273, 270, 270, 270, 270, 270, 269, 122, 270, + 273, 270, 269, 273, 270, 273, 271, 270, 270, 273, + 271, -1, -1, 271, 273, 269, 273, 270, 270, 270, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 319 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"A","B","C","E","F","I","L","N", +"P","R","S","T","SP","CRLF","COMMA","STRING","NUMBER","USER","PASS","ACCT", +"REIN","QUIT","PORT","PASV","TYPE","STRU","MODE","RETR","STOR","APPE","MLFL", +"MAIL","MSND","MSOM","MSAM","MRSQ","MRCP","ALLO","REST","RNFR","RNTO","ABOR", +"DELE","CWD","LIST","NLST","SITE","STAT","HELP","NOOP","MKD","RMD","PWD","CDUP", +"STOU","SMNT","SYST","SIZE","MDTM","UMASK","IDLE","CHMOD","LEXERR", +"illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : cmd_list", +"cmd_list :", +"cmd_list : cmd_list cmd", +"cmd_list : cmd_list rcmd", +"cmd : USER SP username CRLF", +"cmd : PASS SP password CRLF", +"cmd : PORT SP host_port CRLF", +"cmd : PASV CRLF", +"cmd : TYPE SP type_code CRLF", +"cmd : STRU SP struct_code CRLF", +"cmd : MODE SP mode_code CRLF", +"cmd : ALLO SP NUMBER CRLF", +"cmd : ALLO SP NUMBER SP R SP NUMBER CRLF", +"cmd : RETR check_login SP pathname CRLF", +"cmd : STOR check_login SP pathname CRLF", +"cmd : APPE check_login SP pathname CRLF", +"cmd : NLST check_login CRLF", +"cmd : NLST check_login SP STRING CRLF", +"cmd : LIST check_login CRLF", +"cmd : LIST check_login SP pathname CRLF", +"cmd : STAT check_login SP pathname CRLF", +"cmd : STAT CRLF", +"cmd : DELE check_login SP pathname CRLF", +"cmd : RNTO SP pathname CRLF", +"cmd : ABOR CRLF", +"cmd : CWD check_login CRLF", +"cmd : CWD check_login SP pathname CRLF", +"cmd : HELP CRLF", +"cmd : HELP SP STRING CRLF", +"cmd : NOOP CRLF", +"cmd : MKD check_login SP pathname CRLF", +"cmd : RMD check_login SP pathname CRLF", +"cmd : PWD check_login CRLF", +"cmd : CDUP check_login CRLF", +"cmd : SITE SP HELP CRLF", +"cmd : SITE SP HELP SP STRING CRLF", +"cmd : SITE SP UMASK check_login CRLF", +"cmd : SITE SP UMASK check_login SP octal_number CRLF", +"cmd : SITE SP CHMOD check_login SP octal_number SP pathname CRLF", +"cmd : SITE SP IDLE CRLF", +"cmd : SITE SP IDLE SP NUMBER CRLF", +"cmd : STOU check_login SP pathname CRLF", +"cmd : SYST CRLF", +"cmd : SIZE check_login SP pathname CRLF", +"cmd : MDTM check_login SP pathname CRLF", +"cmd : QUIT CRLF", +"cmd : error CRLF", +"rcmd : RNFR check_login SP pathname CRLF", +"username : STRING", +"password :", +"password : STRING", +"byte_size : NUMBER", +"host_port : NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER", +"form_code : N", +"form_code : T", +"form_code : C", +"type_code : A", +"type_code : A SP form_code", +"type_code : E", +"type_code : E SP form_code", +"type_code : I", +"type_code : L", +"type_code : L SP byte_size", +"type_code : L byte_size", +"struct_code : F", +"struct_code : R", +"struct_code : P", +"mode_code : S", +"mode_code : B", +"mode_code : C", +"pathname : pathstring", +"pathstring : STRING", +"octal_number : NUMBER", +"check_login :", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 707 "ftp.y" + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +extern jmp_buf errcatch; + +static void upper(char *); + +#define CMD 0 /* beginning of command */ +#define ARGS 1 /* expect miscellaneous arguments */ +#define STR1 2 /* expect SP followed by STRING */ +#define STR2 3 /* expect STRING */ +#define OSTR 4 /* optional SP then STRING */ +#define ZSTR1 5 /* SP then optional STRING */ +#define ZSTR2 6 /* optional STRING after SP */ +#define SITECMD 7 /* SITE command */ +#define NSTR 8 /* Number followed by a string */ + +struct tab cmdtab[] = { /* In order defined in RFC 765 */ + { "USER", USER, STR1, 1, "<sp> username" }, + { "PASS", PASS, ZSTR1, 1, "<sp> password" }, + { "ACCT", ACCT, STR1, 0, "(specify account)" }, + { "SMNT", SMNT, ARGS, 0, "(structure mount)" }, + { "REIN", REIN, ARGS, 0, "(reinitialize server state)" }, + { "QUIT", QUIT, ARGS, 1, "(terminate service)", }, + { "PORT", PORT, ARGS, 1, "<sp> b0, b1, b2, b3, b4" }, + { "PASV", PASV, ARGS, 1, "(set server in passive mode)" }, + { "TYPE", TYPE, ARGS, 1, "<sp> [ A | E | I | L ]" }, + { "STRU", STRU, ARGS, 1, "(specify file structure)" }, + { "MODE", MODE, ARGS, 1, "(specify transfer mode)" }, + { "RETR", RETR, STR1, 1, "<sp> file-name" }, + { "STOR", STOR, STR1, 1, "<sp> file-name" }, + { "APPE", APPE, STR1, 1, "<sp> file-name" }, + { "MLFL", MLFL, OSTR, 0, "(mail file)" }, + { "MAIL", MAIL, OSTR, 0, "(mail to user)" }, + { "MSND", MSND, OSTR, 0, "(mail send to terminal)" }, + { "MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)" }, + { "MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)" }, + { "MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)" }, + { "MRCP", MRCP, STR1, 0, "(mail recipient)" }, + { "ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)" }, + { "REST", REST, ARGS, 0, "(restart command)" }, + { "RNFR", RNFR, STR1, 1, "<sp> file-name" }, + { "RNTO", RNTO, STR1, 1, "<sp> file-name" }, + { "ABOR", ABOR, ARGS, 1, "(abort operation)" }, + { "DELE", DELE, STR1, 1, "<sp> file-name" }, + { "CWD", CWD, OSTR, 1, "[ <sp> directory-name ]" }, + { "XCWD", CWD, OSTR, 1, "[ <sp> directory-name ]" }, + { "LIST", LIST, OSTR, 1, "[ <sp> path-name ]" }, + { "NLST", NLST, OSTR, 1, "[ <sp> path-name ]" }, + { "SITE", SITE, SITECMD, 1, "site-cmd [ <sp> arguments ]" }, + { "SYST", SYST, ARGS, 1, "(get type of operating system)" }, + { "STAT", STAT, OSTR, 1, "[ <sp> path-name ]" }, + { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, + { "NOOP", NOOP, ARGS, 1, "" }, + { "MKD", MKD, STR1, 1, "<sp> path-name" }, + { "XMKD", MKD, STR1, 1, "<sp> path-name" }, + { "RMD", RMD, STR1, 1, "<sp> path-name" }, + { "XRMD", RMD, STR1, 1, "<sp> path-name" }, + { "PWD", PWD, ARGS, 1, "(return current directory)" }, + { "XPWD", PWD, ARGS, 1, "(return current directory)" }, + { "CDUP", CDUP, ARGS, 1, "(change to parent directory)" }, + { "XCUP", CDUP, ARGS, 1, "(change to parent directory)" }, + { "STOU", STOU, STR1, 1, "<sp> file-name" }, + { "SIZE", SIZE, OSTR, 1, "<sp> path-name" }, + { "MDTM", MDTM, OSTR, 1, "<sp> path-name" }, + { 0, 0, 0, 0, 0 } +}; + +struct tab sitetab[] = { + { "UMASK", UMASK, ARGS, 1, "[ <sp> umask ]" }, + { "IDLE", IDLE, ARGS, 1, "[ <sp> maximum-idle-time ]" }, + { "CHMOD", CHMOD, NSTR, 1, "<sp> mode <sp> file-name" }, + { "HELP", HELP, OSTR, 1, "[ <sp> <string> ]" }, + { 0, 0, 0, 0, 0 } +}; + +static struct tab * +lookup(struct tab *p, char *cmd) +{ + + for (; p->name != 0; p++) + if (strcmp(cmd, p->name) == 0) + return (p); + return (0); +} + +#include <arpa/telnet.h> + +/* + * get_line - a hacked up version of fgets to ignore TELNET escape codes. + */ +static char * +get_line(char *s, int n, FILE *iop) +{ + register int c; + register char *cs; + + cs = s; +/* tmpline may contain saved command from urgent mode interruption */ + for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) { + *cs++ = tmpline[c]; + if (tmpline[c] == '\n') { + *cs = '\0'; + if (debug) + syslog(LOG_DEBUG, "command: %s", s); + tmpline[0] = '\0'; + return(s); + } + if (c == 0) + tmpline[0] = '\0'; + } + while ((c = getc(iop)) != EOF) { + c &= 0377; + if (c == IAC) { + if ((c = getc(iop)) != EOF) { + c &= 0377; + switch (c) { + case WILL: + case WONT: + c = getc(iop); + printf("%c%c%c", IAC, DONT, 0377&c); + (void) fflush(stdout); + continue; + case DO: + case DONT: + c = getc(iop); + printf("%c%c%c", IAC, WONT, 0377&c); + (void) fflush(stdout); + continue; + case IAC: + break; + default: + continue; /* ignore command */ + } + } + } + *cs++ = c; + if (--n <= 0 || c == '\n') + break; + } + if (c == EOF && cs == s) + return (0); + *cs = '\0'; + if (debug) + syslog(LOG_DEBUG, "command: %s", s); + return (s); +} + +static void +toolong(int sig) +{ + time_t now; + + (void) sig; + reply(421, + "Timeout (%d seconds): closing control connection.", timeout); + (void) time(&now); + if (logging) { + syslog(LOG_INFO, + "User %s timed out after %d seconds at %s", + (pw ? pw -> pw_name : "unknown"), timeout, ctime(&now)); + } + dologout(1); +} + +int +yylex(void) +{ + static int cpos, state; + register char *cp, *cp2; + register struct tab *p; + int n; + char c; + + for (;;) { + switch (state) { + + case CMD: + (void) signal(SIGALRM, toolong); + (void) alarm((unsigned) timeout); + if (get_line(cbuf, sizeof(cbuf)-1, stdin) == 0) { + reply(221, "You could at least say goodbye."); + dologout(0); + } + (void) alarm(0); +#ifdef SETPROCTITLE + if (strncasecmp(cbuf, "PASS", 4) != 0) + setproctitle("%s: %s", proctitle, cbuf); +#endif /* SETPROCTITLE */ + if ((cp = strchr(cbuf, '\r'))) { + *cp++ = '\n'; + *cp = '\0'; + } + if ((cp = strpbrk(cbuf, " \n"))) + cpos = cp - cbuf; + if (cpos == 0) + cpos = 4; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + upper(cbuf); + p = lookup(cmdtab, cbuf); + cbuf[cpos] = c; + if (p != 0) { + if (p->implemented == 0) { + nack(p->name); + longjmp(errcatch,0); + /* NOTREACHED */ + } + state = p->state; + *(const char **)(&yylval) = p->name; + return (p->token); + } + break; + + case SITECMD: + if (cbuf[cpos] == ' ') { + cpos++; + return (SP); + } + cp = &cbuf[cpos]; + if ((cp2 = strpbrk(cp, " \n"))) + cpos = cp2 - cbuf; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + upper(cp); + p = lookup(sitetab, cp); + cbuf[cpos] = c; + if (p != 0) { + if (p->implemented == 0) { + state = CMD; + nack(p->name); + longjmp(errcatch,0); + /* NOTREACHED */ + } + state = p->state; + *(const char **)(&yylval) = p->name; + return (p->token); + } + state = CMD; + break; + + case OSTR: + if (cbuf[cpos] == '\n') { + state = CMD; + return (CRLF); + } + /* FALLTHROUGH */ + + case STR1: + case ZSTR1: + dostr1: + if (cbuf[cpos] == ' ') { + cpos++; + if (state == OSTR) + state = STR2; + else + ++state; + return (SP); + } + break; + + case ZSTR2: + if (cbuf[cpos] == '\n') { + state = CMD; + return (CRLF); + } + /* FALLTHROUGH */ + + case STR2: + cp = &cbuf[cpos]; + n = strlen(cp); + cpos += n - 1; + /* + * Make sure the string is nonempty and \n terminated. + */ + if (n > 1 && cbuf[cpos] == '\n') { + cbuf[cpos] = '\0'; + *(char **)&yylval = copy(cp); + cbuf[cpos] = '\n'; + state = ARGS; + return (STRING); + } + break; + + case NSTR: + if (cbuf[cpos] == ' ') { + cpos++; + return (SP); + } + if (isdigit(cbuf[cpos])) { + cp = &cbuf[cpos]; + while (isdigit(cbuf[++cpos])) + ; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + yylval = atoi(cp); + cbuf[cpos] = c; + state = STR1; + return (NUMBER); + } + state = STR1; + goto dostr1; + + case ARGS: + if (isdigit(cbuf[cpos])) { + cp = &cbuf[cpos]; + while (isdigit(cbuf[++cpos])) + ; + c = cbuf[cpos]; + cbuf[cpos] = '\0'; + yylval = atoi(cp); + cbuf[cpos] = c; + return (NUMBER); + } + switch (cbuf[cpos++]) { + + case '\n': + state = CMD; + return (CRLF); + + case ' ': + return (SP); + + case ',': + return (COMMA); + + case 'A': + case 'a': + return (A); + + case 'B': + case 'b': + return (B); + + case 'C': + case 'c': + return (C); + + case 'E': + case 'e': + return (E); + + case 'F': + case 'f': + return (F); + + case 'I': + case 'i': + return (I); + + case 'L': + case 'l': + return (L); + + case 'N': + case 'n': + return (N); + + case 'P': + case 'p': + return (P); + + case 'R': + case 'r': + return (R); + + case 'S': + case 's': + return (S); + + case 'T': + case 't': + return (T); + + } + break; + + default: + fatal("Unknown state in scanner."); + } + yyerror((char *) 0); + state = CMD; + longjmp(errcatch,0); + } +} + +static void +upper(char *s) +{ + while (*s != '\0') { + if (islower(*s)) + *s = toupper(*s); + s++; + } +} + +static char * +copy(const char *s) +{ + char *p; + + p = (char * )malloc(strlen(s) + 1); + if (p == 0) + fatal("Ran out of memory."); + else + (void) strcpy(p, s); + return (p); +} + +static void +help(struct tab *ctab, char *s) +{ + register struct tab *c; + register int width, NCMDS; + const char *help_type; + + if (ctab == sitetab) + help_type = "SITE "; + else + help_type = ""; + width = 0, NCMDS = 0; + for (c = ctab; c->name != 0; c++) { + int len = strlen(c->name); + + if (len > width) + width = len; + NCMDS++; + } + width = (width + 8) &~ 7; + if (s == 0) { + register int i, j, w; + int columns, lines; + + lreply(214, "The following %scommands are recognized %s.", + help_type, "(* =>'s unimplemented)"); + columns = 76 / width; + if (columns == 0) + columns = 1; + lines = (NCMDS + columns - 1) / columns; + for (i = 0; i < lines; i++) { + printf(" "); + for (j = 0; j < columns; j++) { + c = ctab + j * lines + i; + assert(c->name != 0); + printf("%s%c", c->name, + c->implemented ? ' ' : '*'); + if (c + lines >= &ctab[NCMDS]) + break; + w = strlen(c->name) + 1; + while (w < width) { + putchar(' '); + w++; + } + } + printf("\r\n"); + } + (void) fflush(stdout); + reply(214, "Direct comments to ftp-bugs@%s.", hostname); + return; + } + upper(s); + c = lookup(ctab, s); + if (c == (struct tab *)0) { + reply(502, "Unknown command %s.", s); + return; + } + if (c->implemented) + reply(214, "Syntax: %s%s %s", help_type, c->name, c->help); + else + reply(214, "%s%-*s\t%s; unimplemented.", help_type, width, + c->name, c->help); +} + +static void +sizecmd(char *filename) +{ + switch (type) { + case TYPE_L: + case TYPE_I: { + struct stat stbuf; + if (stat(filename, &stbuf) < 0 || + (stbuf.st_mode&S_IFMT) != S_IFREG) + reply(550, "%s: not a plain file.", filename); + else +#ifdef HAVE_LONG_LONG + reply(213, "%llu", (long long) stbuf.st_size); +#else + reply(213, "%lu", stbuf.st_size); +#endif + break;} + case TYPE_A: { + FILE *fin; + register int c, count; + struct stat stbuf; + fin = fopen(filename, "r"); + if (fin == 0) { + perror_reply(550, filename); + return; + } + if (fstat(fileno(fin), &stbuf) < 0 || + (stbuf.st_mode&S_IFMT) != S_IFREG) { + reply(550, "%s: not a plain file.", filename); + (void) fclose(fin); + return; + } + + count = 0; + while((c=getc(fin)) != EOF) { + if (c == '\n') /* will get expanded to \r\n */ + count++; + count++; + } + (void) fclose(fin); + + reply(213, "%ld", count); + break;} + default: + reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]); + } +} +#line 1013 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 2: +#line 150 "ftp.y" + { + fromname = (char *) 0; + } +break; +case 4: +#line 157 "ftp.y" + { + user((char *) yystack.l_mark[-1]); + free((char *) yystack.l_mark[-1]); + } +break; +case 5: +#line 162 "ftp.y" + { + pass((char *) yystack.l_mark[-1]); + free((char *) yystack.l_mark[-1]); + } +break; +case 6: +#line 167 "ftp.y" + { + usedefault = 0; + if (pdata >= 0) { + (void) close(pdata); + pdata = -1; + } + reply(200, "PORT command successful."); + } +break; +case 7: +#line 176 "ftp.y" + { + passive(); + } +break; +case 8: +#line 180 "ftp.y" + { + switch (cmd_type) { + + case TYPE_A: + if (cmd_form == FORM_N) { + reply(200, "Type set to A."); + type = cmd_type; + form = cmd_form; + } else + reply(504, "Form must be N."); + break; + + case TYPE_E: + reply(504, "Type E not implemented."); + break; + + case TYPE_I: + reply(200, "Type set to I."); + type = cmd_type; + break; + + case TYPE_L: +#if NBBY == 8 + if (cmd_bytesz == 8) { + reply(200, + "Type set to L (byte size 8)."); + type = cmd_type; + } else + reply(504, "Byte size must be 8."); +#else /* NBBY == 8 */ + UNIMPLEMENTED for NBBY != 8 +#endif /* NBBY == 8 */ + } + } +break; +case 9: +#line 215 "ftp.y" + { + switch (yystack.l_mark[-1]) { + + case STRU_F: + reply(200, "STRU F ok."); + break; + + default: + reply(504, "Unimplemented STRU type."); + } + } +break; +case 10: +#line 227 "ftp.y" + { + switch (yystack.l_mark[-1]) { + + case MODE_S: + reply(200, "MODE S ok."); + break; + + default: + reply(502, "Unimplemented MODE type."); + } + } +break; +case 11: +#line 239 "ftp.y" + { + reply(202, "ALLO command ignored."); + } +break; +case 12: +#line 243 "ftp.y" + { + reply(202, "ALLO command ignored."); + } +break; +case 13: +#line 247 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + retrieve((char *) 0, (char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 14: +#line 254 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + store((char *) yystack.l_mark[-1], "w", 0); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 15: +#line 261 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + store((char *) yystack.l_mark[-1], "a", 0); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 16: +#line 268 "ftp.y" + { + if (yystack.l_mark[-1]) + send_file_list("."); + } +break; +case 17: +#line 273 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + send_file_list((char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 18: +#line 280 "ftp.y" + { + if (yystack.l_mark[-1]) + retrieve("/bin/ls -lgA", ""); + } +break; +case 19: +#line 285 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + retrieve("/bin/ls -lgA %s", (char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 20: +#line 292 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + statfilecmd((char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 21: +#line 299 "ftp.y" + { + statcmd(); + } +break; +case 22: +#line 303 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + remove((char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 23: +#line 310 "ftp.y" + { + if (fromname) { + renamecmd(fromname, (char *) yystack.l_mark[-1]); + free(fromname); + fromname = (char *) 0; + } else { + reply(503, "Bad sequence of commands."); + } + free((char *) yystack.l_mark[-1]); + } +break; +case 24: +#line 321 "ftp.y" + { + reply(225, "ABOR command successful."); + } +break; +case 25: +#line 325 "ftp.y" + { + if (yystack.l_mark[-1]) + cwd(pw->pw_dir); + } +break; +case 26: +#line 330 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + cwd((char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 27: +#line 337 "ftp.y" + { + help(cmdtab, (char *) 0); + } +break; +case 28: +#line 341 "ftp.y" + { + register char *cp = (char *)yystack.l_mark[-1]; + + if (strncasecmp(cp, "SITE", 4) == 0) { + cp = (char *)yystack.l_mark[-1] + 4; + if (*cp == ' ') + cp++; + if (*cp) + help(sitetab, cp); + else + help(sitetab, (char *) 0); + } else + help(cmdtab, (char *) yystack.l_mark[-1]); + } +break; +case 29: +#line 356 "ftp.y" + { + reply(200, "NOOP command successful."); + } +break; +case 30: +#line 360 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + makedir((char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 31: +#line 367 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + removedir((char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 32: +#line 374 "ftp.y" + { + if (yystack.l_mark[-1]) + pwd(); + } +break; +case 33: +#line 379 "ftp.y" + { + if (yystack.l_mark[-1]) + cwd(".."); + } +break; +case 34: +#line 384 "ftp.y" + { + help(sitetab, (char *) 0); + } +break; +case 35: +#line 388 "ftp.y" + { + help(sitetab, (char *) yystack.l_mark[-1]); + } +break; +case 36: +#line 392 "ftp.y" + { + int oldmask; + + if (yystack.l_mark[-1]) { + oldmask = umask(0); + (void) umask(oldmask); + reply(200, "Current UMASK is %03o", oldmask); + } + } +break; +case 37: +#line 402 "ftp.y" + { + int oldmask; + + if (yystack.l_mark[-3]) { + if ((yystack.l_mark[-1] == -1) || (yystack.l_mark[-1] > 0777)) { + reply(501, "Bad UMASK value"); + } else { + oldmask = umask(yystack.l_mark[-1]); + reply(200, + "UMASK set to %03o (was %03o)", + yystack.l_mark[-1], oldmask); + } + } + } +break; +case 38: +#line 417 "ftp.y" + { + if (yystack.l_mark[-5] && (yystack.l_mark[-1] != 0)) { + if (yystack.l_mark[-3] > 0777) + reply(501, + "CHMOD: Mode value must be between 0 and 0777"); + else if (chmod((char *) yystack.l_mark[-1], yystack.l_mark[-3]) < 0) + perror_reply(550, (char *) yystack.l_mark[-1]); + else + reply(200, "CHMOD command successful."); + } + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 39: +#line 431 "ftp.y" + { + reply(200, + "Current IDLE time limit is %d seconds; max %d", + timeout, maxtimeout); + } +break; +case 40: +#line 437 "ftp.y" + { + if (yystack.l_mark[-1] < 30 || yystack.l_mark[-1] > maxtimeout) { + reply(501, + "Maximum IDLE time must be between 30 and %d seconds", + maxtimeout); + } else { + timeout = yystack.l_mark[-1]; + (void) alarm((unsigned) timeout); + reply(200, + "Maximum IDLE time set to %d seconds", + timeout); + } + } +break; +case 41: +#line 451 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + store((char *) yystack.l_mark[-1], "w", 1); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 42: +#line 458 "ftp.y" + { +#ifdef unix +#ifdef BSD + reply(215, "UNIX Type: L%d Version: BSD-%d", + NBBY, BSD); +#else /* BSD */ + reply(215, "UNIX Type: L%d", NBBY); +#endif /* BSD */ +#else /* unix */ + reply(215, "UNKNOWN Type: L%d", NBBY); +#endif /* unix */ + } +break; +case 43: +#line 479 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) + sizecmd((char *) yystack.l_mark[-1]); + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 44: +#line 496 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1] != 0) { + struct stat stbuf; + if (stat((char *) yystack.l_mark[-1], &stbuf) < 0) + perror_reply(550, "%s", (char *) yystack.l_mark[-1]); + else if ((stbuf.st_mode&S_IFMT) != S_IFREG) { + reply(550, "%s: not a plain file.", + (char *) yystack.l_mark[-1]); + } else { + register struct tm *t; + t = gmtime(&stbuf.st_mtime); + reply(213, + "%04d%02d%02d%02d%02d%02d", + 1900 + t->tm_year, + t->tm_mon+1, t->tm_mday, + t->tm_hour, t->tm_min, t->tm_sec); + } + } + if (yystack.l_mark[-1] != 0) + free((char *) yystack.l_mark[-1]); + } +break; +case 45: +#line 518 "ftp.y" + { + reply(221, "Goodbye."); + dologout(0); + } +break; +case 46: +#line 523 "ftp.y" + { + yyerrok; + } +break; +case 47: +#line 528 "ftp.y" + { + if (yystack.l_mark[-3] && yystack.l_mark[-1]) { + fromname = renamefrom((char *) yystack.l_mark[-1]); + if (fromname == (char *) 0 && yystack.l_mark[-1]) { + free((char *) yystack.l_mark[-1]); + } + } + } +break; +case 49: +#line 542 "ftp.y" + { + *(const char **)(&(yyval)) = ""; + } +break; +case 52: +#line 553 "ftp.y" + { + register char *a, *p; + + a = (char *)&data_dest.sin_addr; + a[0] = yystack.l_mark[-10]; a[1] = yystack.l_mark[-8]; a[2] = yystack.l_mark[-6]; a[3] = yystack.l_mark[-4]; + p = (char *)&data_dest.sin_port; + p[0] = yystack.l_mark[-2]; p[1] = yystack.l_mark[0]; + data_dest.sin_family = AF_INET; + } +break; +case 53: +#line 565 "ftp.y" + { + yyval = FORM_N; + } +break; +case 54: +#line 569 "ftp.y" + { + yyval = FORM_T; + } +break; +case 55: +#line 573 "ftp.y" + { + yyval = FORM_C; + } +break; +case 56: +#line 579 "ftp.y" + { + cmd_type = TYPE_A; + cmd_form = FORM_N; + } +break; +case 57: +#line 584 "ftp.y" + { + cmd_type = TYPE_A; + cmd_form = yystack.l_mark[0]; + } +break; +case 58: +#line 589 "ftp.y" + { + cmd_type = TYPE_E; + cmd_form = FORM_N; + } +break; +case 59: +#line 594 "ftp.y" + { + cmd_type = TYPE_E; + cmd_form = yystack.l_mark[0]; + } +break; +case 60: +#line 599 "ftp.y" + { + cmd_type = TYPE_I; + } +break; +case 61: +#line 603 "ftp.y" + { + cmd_type = TYPE_L; + cmd_bytesz = NBBY; + } +break; +case 62: +#line 608 "ftp.y" + { + cmd_type = TYPE_L; + cmd_bytesz = yystack.l_mark[0]; + } +break; +case 63: +#line 614 "ftp.y" + { + cmd_type = TYPE_L; + cmd_bytesz = yystack.l_mark[0]; + } +break; +case 64: +#line 621 "ftp.y" + { + yyval = STRU_F; + } +break; +case 65: +#line 625 "ftp.y" + { + yyval = STRU_R; + } +break; +case 66: +#line 629 "ftp.y" + { + yyval = STRU_P; + } +break; +case 67: +#line 635 "ftp.y" + { + yyval = MODE_S; + } +break; +case 68: +#line 639 "ftp.y" + { + yyval = MODE_B; + } +break; +case 69: +#line 643 "ftp.y" + { + yyval = MODE_C; + } +break; +case 70: +#line 649 "ftp.y" + { + /* + * Problem: this production is used for all pathname + * processing, but only gives a 550 error reply. + * This is a valid reply in some cases but not in others. + */ + if (logged_in && yystack.l_mark[0] && strncmp((char *) yystack.l_mark[0], "~", 1) == 0) { + *(char **)&(yyval) = *glob((char *) yystack.l_mark[0]); + if (globerr != 0) { + reply(550, globerr); + yyval = 0; + } + free((char *) yystack.l_mark[0]); + } else + yyval = yystack.l_mark[0]; + } +break; +case 72: +#line 671 "ftp.y" + { + register int ret, dec, multby, digit; + + /* + * Convert a number that was read as decimal number + * to what it would be if it had been read as octal. + */ + dec = yystack.l_mark[0]; + multby = 1; + ret = 0; + while (dec) { + digit = dec%10; + if (digit > 7) { + ret = -1; + break; + } + ret += digit * multby; + multby *= 8; + dec /= 10; + } + yyval = ret; + } +break; +case 73: +#line 696 "ftp.y" + { + if (logged_in) + yyval = 1; + else { + reply(530, "Please login with USER and PASS."); + yyval = 0; + } + } +break; +#line 1852 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.08.out b/usr.bin/yacc/tests/regress.08.out new file mode 100644 index 0000000..d5d3ae0 --- /dev/null +++ b/usr.bin/yacc/tests/regress.08.out @@ -0,0 +1,1942 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 9 "grammar.y" +#ifdef YYBISON +#include <stdlib.h> +#define YYSTYPE_IS_DECLARED +#define yyerror yaccError +#endif + +#if defined(YYBISON) || !defined(YYBYACC) +static void yyerror(const char *s); +#endif +#line 81 "grammar.y" +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +#define OPT_LINTLIBRARY 1 + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +/* #include "cproto.h" */ +#define MAX_TEXT_SIZE 1024 + +/* Prototype styles */ +#if OPT_LINTLIBRARY +#define PROTO_ANSI_LLIB -2 /* form ANSI lint-library source */ +#define PROTO_LINTLIBRARY -1 /* form lint-library source */ +#endif +#define PROTO_NONE 0 /* do not output any prototypes */ +#define PROTO_TRADITIONAL 1 /* comment out parameters */ +#define PROTO_ABSTRACT 2 /* comment out parameter names */ +#define PROTO_ANSI 3 /* ANSI C prototype */ + +typedef int PrototypeStyle; + +typedef char boolean; + +extern boolean types_out; +extern PrototypeStyle proto_style; + +#define ansiLintLibrary() (proto_style == PROTO_ANSI_LLIB) +#define knrLintLibrary() (proto_style == PROTO_LINTLIBRARY) +#define lintLibrary() (knrLintLibrary() || ansiLintLibrary()) + +#if OPT_LINTLIBRARY +#define FUNC_UNKNOWN -1 /* unspecified */ +#else +#define FUNC_UNKNOWN 0 /* unspecified (same as FUNC_NONE) */ +#endif +#define FUNC_NONE 0 /* not a function definition */ +#define FUNC_TRADITIONAL 1 /* traditional style */ +#define FUNC_ANSI 2 /* ANSI style */ +#define FUNC_BOTH 3 /* both styles */ + +typedef int FuncDefStyle; + +/* Source file text */ +typedef struct text { + char text[MAX_TEXT_SIZE]; /* source text */ + long begin; /* offset in temporary file */ +} Text; + +/* Declaration specifier flags */ +#define DS_NONE 0 /* default */ +#define DS_EXTERN 1 /* contains "extern" specifier */ +#define DS_STATIC 2 /* contains "static" specifier */ +#define DS_CHAR 4 /* contains "char" type specifier */ +#define DS_SHORT 8 /* contains "short" type specifier */ +#define DS_FLOAT 16 /* contains "float" type specifier */ +#define DS_INLINE 32 /* contains "inline" specifier */ +#define DS_JUNK 64 /* we're not interested in this declaration */ + +/* This structure stores information about a declaration specifier. */ +typedef struct decl_spec { + unsigned short flags; /* flags defined above */ + char *text; /* source text */ + long begin; /* offset in temporary file */ +} DeclSpec; + +/* This is a list of function parameters. */ +typedef struct _ParameterList { + struct parameter *first; /* pointer to first parameter in list */ + struct parameter *last; /* pointer to last parameter in list */ + long begin_comment; /* begin offset of comment */ + long end_comment; /* end offset of comment */ + char *comment; /* comment at start of parameter list */ +} ParameterList; + +/* This structure stores information about a declarator. */ +typedef struct _Declarator { + char *name; /* name of variable or function */ + char *text; /* source text */ + long begin; /* offset in temporary file */ + long begin_comment; /* begin offset of comment */ + long end_comment; /* end offset of comment */ + FuncDefStyle func_def; /* style of function definition */ + ParameterList params; /* function parameters */ + boolean pointer; /* TRUE if it declares a pointer */ + struct _Declarator *head; /* head function declarator */ + struct _Declarator *func_stack; /* stack of function declarators */ + struct _Declarator *next; /* next declarator in list */ +} Declarator; + +/* This structure stores information about a function parameter. */ +typedef struct parameter { + struct parameter *next; /* next parameter in list */ + DeclSpec decl_spec; + Declarator *declarator; + char *comment; /* comment following the parameter */ +} Parameter; + +/* This is a list of declarators. */ +typedef struct declarator_list { + Declarator *first; /* pointer to first declarator in list */ + Declarator *last; /* pointer to last declarator in list */ +} DeclaratorList; + +/* #include "symbol.h" */ +typedef struct symbol { + struct symbol *next; /* next symbol in list */ + char *name; /* name of symbol */ + char *value; /* value of symbol (for defines) */ + short flags; /* symbol attributes */ +} Symbol; + +/* parser stack entry type */ +typedef union { + Text text; + DeclSpec decl_spec; + Parameter *parameter; + ParameterList param_list; + Declarator *declarator; + DeclaratorList decl_list; +} YYSTYPE; + +/* The hash table length should be a prime number. */ +#define SYM_MAX_HASH 251 + +typedef struct symbol_table { + Symbol *bucket[SYM_MAX_HASH]; /* hash buckets */ +} SymbolTable; + +extern SymbolTable *new_symbol_table /* Create symbol table */ + (void); +extern void free_symbol_table /* Destroy symbol table */ + (SymbolTable *s); +extern Symbol *find_symbol /* Lookup symbol name */ + (SymbolTable *s, const char *n); +extern Symbol *new_symbol /* Define new symbol */ + (SymbolTable *s, const char *n, const char *v, int f); + +/* #include "semantic.h" */ +extern void new_decl_spec (DeclSpec *, const char *, long, int); +extern void free_decl_spec (DeclSpec *); +extern void join_decl_specs (DeclSpec *, DeclSpec *, DeclSpec *); +extern void check_untagged (DeclSpec *); +extern Declarator *new_declarator (const char *, const char *, long); +extern void free_declarator (Declarator *); +extern void new_decl_list (DeclaratorList *, Declarator *); +extern void free_decl_list (DeclaratorList *); +extern void add_decl_list (DeclaratorList *, DeclaratorList *, Declarator *); +extern Parameter *new_parameter (DeclSpec *, Declarator *); +extern void free_parameter (Parameter *); +extern void new_param_list (ParameterList *, Parameter *); +extern void free_param_list (ParameterList *); +extern void add_param_list (ParameterList *, ParameterList *, Parameter *); +extern void new_ident_list (ParameterList *); +extern void add_ident_list (ParameterList *, ParameterList *, const char *); +extern void set_param_types (ParameterList *, DeclSpec *, DeclaratorList *); +extern void gen_declarations (DeclSpec *, DeclaratorList *); +extern void gen_prototype (DeclSpec *, Declarator *); +extern void gen_func_declarator (Declarator *); +extern void gen_func_definition (DeclSpec *, Declarator *); + +extern void init_parser (void); +extern void process_file (FILE *infile, char *name); +extern char *cur_text (void); +extern char *cur_file_name (void); +extern char *implied_typedef (void); +extern void include_file (char *name, int convert); +extern char *supply_parm (int count); +extern char *xstrdup (const char *); +extern int already_declared (char *name); +extern int is_actual_func (Declarator *d); +extern int lint_ellipsis (Parameter *p); +extern int want_typedef (void); +extern void begin_tracking (void); +extern void begin_typedef (void); +extern void copy_typedef (char *s); +extern void ellipsis_varargs (Declarator *d); +extern void end_typedef (void); +extern void flush_varargs (void); +extern void fmt_library (int code); +extern void imply_typedef (const char *s); +extern void indent (FILE *outf); +extern void put_blankline (FILE *outf); +extern void put_body (FILE *outf, DeclSpec *decl_spec, Declarator *declarator); +extern void put_char (FILE *outf, int c); +extern void put_error (void); +extern void put_newline (FILE *outf); +extern void put_padded (FILE *outf, const char *s); +extern void put_string (FILE *outf, const char *s); +extern void track_in (void); + +extern boolean file_comments; +extern FuncDefStyle func_style; +extern char base_file[]; + +extern int yylex (void); + +/* declaration specifier attributes for the typedef statement currently being + * scanned + */ +static int cur_decl_spec_flags; + +/* pointer to parameter list for the current function definition */ +static ParameterList *func_params; + +/* A parser semantic action sets this pointer to the current declarator in + * a function parameter declaration in order to catch any comments following + * the parameter declaration on the same line. If the lexer scans a comment + * and <cur_declarator> is not NULL, then the comment is attached to the + * declarator. To ignore subsequent comments, the lexer sets this to NULL + * after scanning a comment or end of line. + */ +static Declarator *cur_declarator; + +/* temporary string buffer */ +static char buf[MAX_TEXT_SIZE]; + +/* table of typedef names */ +static SymbolTable *typedef_names; + +/* table of define names */ +static SymbolTable *define_names; + +/* table of type qualifiers */ +static SymbolTable *type_qualifiers; + +/* information about the current input file */ +typedef struct { + char *base_name; /* base input file name */ + char *file_name; /* current file name */ + FILE *file; /* input file */ + unsigned line_num; /* current line number in input file */ + FILE *tmp_file; /* temporary file */ + long begin_comment; /* tmp file offset after last written ) or ; */ + long end_comment; /* tmp file offset after last comment */ + boolean convert; /* if TRUE, convert function definitions */ + boolean changed; /* TRUE if conversion done in this file */ +} IncludeStack; + +static IncludeStack *cur_file; /* current input file */ + +/* #include "yyerror.c" */ + +static int haveAnsiParam (void); + + +/* Flags to enable us to find if a procedure returns a value. + */ +static int return_val; /* nonzero on BRACES iff return-expression found */ + +static const char * +dft_decl_spec (void) +{ + return (lintLibrary() && !return_val) ? "void" : "int"; +} + +static int +haveAnsiParam (void) +{ + Parameter *p; + if (func_params != 0) { + for (p = func_params->first; p != 0; p = p->next) { + if (p->declarator->func_def == FUNC_ANSI) { + return TRUE; + } + } + } + return FALSE; +} +#line 306 "/dev/stdout" + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define T_IDENTIFIER 257 +#define T_TYPEDEF_NAME 258 +#define T_DEFINE_NAME 259 +#define T_AUTO 260 +#define T_EXTERN 261 +#define T_REGISTER 262 +#define T_STATIC 263 +#define T_TYPEDEF 264 +#define T_INLINE 265 +#define T_EXTENSION 266 +#define T_CHAR 267 +#define T_DOUBLE 268 +#define T_FLOAT 269 +#define T_INT 270 +#define T_VOID 271 +#define T_LONG 272 +#define T_SHORT 273 +#define T_SIGNED 274 +#define T_UNSIGNED 275 +#define T_ENUM 276 +#define T_STRUCT 277 +#define T_UNION 278 +#define T_Bool 279 +#define T_Complex 280 +#define T_Imaginary 281 +#define T_TYPE_QUALIFIER 282 +#define T_BRACKETS 283 +#define T_LBRACE 284 +#define T_MATCHRBRACE 285 +#define T_ELLIPSIS 286 +#define T_INITIALIZER 287 +#define T_STRING_LITERAL 288 +#define T_ASM 289 +#define T_ASMARG 290 +#define T_VA_DCL 291 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 26, 26, 27, 27, 27, 27, 27, 27, + 27, 31, 30, 30, 28, 28, 34, 28, 32, 32, + 33, 33, 35, 35, 37, 38, 29, 39, 29, 36, + 36, 36, 40, 40, 1, 1, 2, 2, 2, 3, + 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 6, 6, 6, 19, 19, 8, 8, 9, + 41, 9, 7, 7, 7, 25, 23, 23, 10, 10, + 11, 11, 11, 11, 11, 20, 20, 21, 21, 22, + 22, 14, 14, 15, 15, 16, 16, 16, 17, 17, + 18, 18, 24, 24, 12, 12, 12, 13, 13, 13, + 13, 13, 13, 13, +}; +static const short yylen[] = { 2, + 0, 1, 1, 2, 1, 1, 1, 1, 3, 2, + 2, 2, 3, 3, 2, 3, 0, 5, 2, 1, + 0, 1, 1, 3, 0, 0, 7, 0, 5, 0, + 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 3, 2, 2, 1, 1, 1, 3, 1, + 0, 4, 3, 2, 2, 1, 1, 1, 2, 1, + 1, 3, 2, 4, 4, 2, 3, 0, 1, 1, + 2, 1, 3, 1, 3, 2, 2, 1, 0, 1, + 1, 3, 1, 2, 1, 2, 1, 3, 2, 1, + 4, 3, 3, 2, +}; +static const short yydefred[] = { 0, + 0, 0, 0, 0, 77, 0, 62, 40, 0, 42, + 43, 20, 44, 0, 46, 47, 48, 49, 54, 50, + 51, 52, 53, 76, 66, 67, 55, 56, 57, 61, + 0, 7, 0, 0, 35, 37, 38, 39, 59, 60, + 28, 0, 0, 0, 103, 81, 0, 0, 3, 5, + 6, 8, 0, 10, 11, 78, 0, 90, 0, 0, + 104, 0, 19, 0, 41, 45, 15, 36, 0, 68, + 0, 0, 0, 83, 0, 0, 64, 0, 0, 74, + 4, 58, 0, 82, 87, 91, 0, 14, 13, 9, + 16, 0, 71, 0, 31, 33, 0, 0, 0, 0, + 0, 94, 0, 0, 101, 12, 63, 73, 0, 0, + 69, 0, 0, 0, 34, 0, 110, 96, 97, 0, + 0, 84, 0, 85, 0, 23, 0, 0, 72, 26, + 29, 114, 0, 0, 0, 109, 0, 93, 95, 102, + 18, 0, 0, 108, 113, 112, 0, 24, 27, 111, +}; +static const short yydgoto[] = { 33, + 87, 35, 36, 37, 38, 39, 40, 69, 70, 41, + 42, 119, 120, 100, 101, 102, 103, 104, 43, 44, + 59, 60, 45, 46, 47, 48, 49, 50, 51, 52, + 77, 53, 127, 109, 128, 97, 94, 143, 72, 98, + 112, +}; +static const short yysindex[] = { -2, + -3, 27, -239, -177, 0, 0, 0, 0, -274, 0, + 0, 0, 0, -246, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -266, 0, 0, 455, 0, 0, 0, 0, 0, 0, + 0, -35, -245, 128, 0, 0, -245, -2, 0, 0, + 0, 0, 642, 0, 0, 0, -15, 0, -12, -239, + 0, 590, 0, -27, 0, 0, 0, 0, -10, 0, + -11, 534, -72, 0, -237, -232, 0, -35, -232, 0, + 0, 0, 642, 0, 0, 0, 455, 0, 0, 0, + 0, 27, 0, 534, 0, 0, -222, 617, 209, 34, + 39, 0, 44, 42, 0, 0, 0, 0, 27, -11, + 0, -200, -196, -195, 0, 174, 0, 0, 0, -33, + 243, 0, 561, 0, -177, 0, 33, 49, 0, 0, + 0, 0, 53, 55, 417, 0, -33, 0, 0, 0, + 0, 27, -188, 0, 0, 0, 57, 0, 0, 0, +}; +static const short yyrindex[] = { 99, + 0, 0, 275, 0, 0, -38, 0, 0, 481, 0, + 0, 0, 0, 509, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 30, 0, 0, 0, 0, 0, 101, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 343, 309, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 98, -182, 62, 0, 0, 133, 0, 64, 379, 0, + 0, 0, -5, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -182, 0, 0, 0, -180, -19, 0, + 65, 0, 0, 68, 0, 0, 0, 0, 51, 9, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -13, + 19, 0, 0, 0, 0, 0, 0, 52, 0, 0, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +}; +static const short yygindex[] = { 0, + 11, -17, 0, 0, 13, 0, 0, 0, 20, 8, + -43, -1, -8, -89, 0, -9, 0, 0, 0, -44, + 0, 0, 4, 0, 0, 0, 70, -53, 0, 0, + -18, 0, 0, 0, 0, 22, 0, 0, 0, 0, + 0, +}; +#define YYTABLESIZE 924 +static const short yytable[] = { 58, + 78, 58, 58, 58, 73, 58, 135, 61, 88, 57, + 34, 5, 56, 62, 85, 58, 68, 63, 96, 7, + 58, 98, 78, 64, 98, 84, 134, 107, 80, 3, + 107, 90, 17, 92, 17, 4, 17, 2, 75, 3, + 96, 71, 30, 89, 115, 147, 76, 106, 91, 93, + 79, 75, 70, 17, 121, 55, 32, 107, 34, 105, + 108, 114, 105, 83, 4, 68, 2, 70, 3, 68, + 80, 121, 86, 80, 122, 106, 105, 78, 106, 5, + 56, 68, 123, 99, 124, 125, 129, 130, 80, 131, + 80, 141, 142, 144, 110, 145, 149, 150, 1, 110, + 2, 30, 99, 32, 79, 92, 118, 79, 100, 21, + 22, 111, 137, 139, 133, 113, 126, 81, 0, 0, + 0, 0, 79, 57, 79, 0, 99, 0, 140, 0, + 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, + 0, 70, 0, 0, 0, 99, 0, 0, 0, 148, + 0, 0, 0, 0, 0, 0, 70, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 2, 0, 0, + 65, 0, 65, 65, 65, 0, 65, 0, 0, 0, + 0, 0, 0, 0, 5, 6, 7, 8, 65, 10, + 11, 65, 13, 66, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 0, 4, 0, 116, 132, 3, 0, 0, 58, 58, + 58, 58, 58, 58, 58, 78, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 58, 58, 78, 4, 74, 116, 136, + 3, 17, 78, 1, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 4, 54, 116, 5, 56, 0, 31, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 88, 80, 88, 88, 88, 0, 88, 0, + 80, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 79, 79, 79, 79, 89, 79, 89, 89, + 89, 0, 89, 0, 79, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 86, 25, 86, 86, 5, 56, 86, 0, 25, 65, + 65, 65, 65, 65, 65, 65, 0, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 75, 0, 75, 75, + 75, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 5, 6, 7, 8, 65, 10, 11, 75, 13, 66, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 117, 146, 0, 0, + 0, 0, 0, 0, 0, 5, 6, 7, 8, 65, + 10, 11, 0, 13, 66, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 117, 4, 0, 2, 0, 3, 0, 0, 5, + 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 67, 0, 0, 0, 0, 41, 0, + 41, 0, 41, 0, 0, 117, 0, 0, 0, 0, + 0, 88, 88, 0, 0, 0, 0, 0, 0, 41, + 0, 0, 0, 0, 0, 0, 45, 0, 45, 0, + 45, 0, 0, 0, 0, 0, 0, 88, 0, 0, + 0, 0, 0, 0, 0, 89, 89, 45, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 89, 0, 0, 0, 0, 0, 0, 0, 86, + 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 86, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 75, 75, 75, 75, 75, + 75, 75, 0, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 82, 7, 8, 65, 10, 11, + 0, 13, 66, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 5, 6, 7, 8, 65, 10, 11, 0, 13, + 66, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 41, 41, 41, + 41, 41, 41, 41, 0, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, + 41, 41, 41, 0, 0, 45, 45, 45, 45, 45, + 45, 45, 0, 45, 45, 45, 45, 45, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, + 45, 82, 7, 8, 65, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 82, 7, + 8, 65, 10, 11, 95, 13, 66, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 0, 0, 0, 138, 82, 7, 8, + 65, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 0, 75, 82, 7, 8, 65, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 82, + 7, 8, 65, 10, 11, 0, 13, 66, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, +}; +static const short yycheck[] = { 38, + 44, 40, 41, 42, 40, 44, 40, 4, 62, 2, + 0, 257, 258, 288, 59, 3, 34, 264, 72, 259, + 59, 41, 61, 290, 44, 41, 116, 41, 47, 42, + 44, 59, 38, 44, 40, 38, 42, 40, 284, 42, + 94, 34, 282, 62, 98, 135, 43, 285, 59, 61, + 47, 284, 44, 59, 99, 59, 59, 76, 48, 41, + 79, 284, 44, 53, 38, 83, 40, 59, 42, 87, + 41, 116, 60, 44, 41, 41, 73, 121, 44, 257, + 258, 99, 44, 73, 41, 44, 287, 284, 59, 285, + 61, 59, 44, 41, 87, 41, 285, 41, 0, 92, + 0, 284, 41, 284, 41, 41, 99, 44, 41, 59, + 59, 92, 121, 123, 116, 94, 109, 48, -1, -1, + -1, -1, 59, 116, 61, -1, 116, -1, 125, -1, + -1, -1, -1, 123, -1, -1, -1, -1, -1, -1, + -1, 44, -1, -1, -1, 135, -1, -1, -1, 142, + -1, -1, -1, -1, -1, -1, 59, -1, -1, -1, + -1, -1, -1, -1, -1, 38, -1, 40, -1, -1, + 38, -1, 40, 41, 42, -1, 44, -1, -1, -1, + -1, -1, -1, -1, 257, 258, 259, 260, 261, 262, + 263, 59, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + -1, 38, -1, 40, 41, 42, -1, -1, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 38, 283, 40, 283, + 42, 257, 291, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 38, 285, 40, 257, 258, -1, 289, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 38, 284, 40, 41, 42, -1, 44, -1, + 291, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 38, 284, 40, 41, + 42, -1, 44, -1, 291, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 38, 284, 40, 41, 257, 258, 44, -1, 291, 257, + 258, 259, 260, 261, 262, 263, -1, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, 38, -1, 40, 41, + 42, -1, 44, -1, -1, -1, -1, -1, -1, -1, + 257, 258, 259, 260, 261, 262, 263, 59, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 41, -1, -1, + -1, -1, -1, -1, -1, 257, 258, 259, 260, 261, + 262, 263, -1, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 38, -1, 40, -1, 42, -1, -1, 257, + 258, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 59, -1, -1, -1, -1, 38, -1, + 40, -1, 42, -1, -1, 283, -1, -1, -1, -1, + -1, 257, 258, -1, -1, -1, -1, -1, -1, 59, + -1, -1, -1, -1, -1, -1, 38, -1, 40, -1, + 42, -1, -1, -1, -1, -1, -1, 283, -1, -1, + -1, -1, -1, -1, -1, 257, 258, 59, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 283, -1, -1, -1, -1, -1, -1, -1, 257, + 258, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 283, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 257, 258, 259, 260, 261, + 262, 263, -1, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 258, 259, 260, 261, 262, 263, + -1, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 257, 258, 259, 260, 261, 262, 263, -1, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 257, 258, 259, + 260, 261, 262, 263, -1, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, -1, -1, 257, 258, 259, 260, 261, + 262, 263, -1, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, -1, -1, 258, 259, + 260, 261, 262, 263, 291, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, -1, -1, -1, 286, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, -1, 284, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 258, + 259, 260, 261, 262, 263, -1, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, +}; +#define YYFINAL 33 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 291 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,"'&'",0,"'('","')'","'*'",0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,0,"';'",0, +"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +"T_IDENTIFIER","T_TYPEDEF_NAME","T_DEFINE_NAME","T_AUTO","T_EXTERN", +"T_REGISTER","T_STATIC","T_TYPEDEF","T_INLINE","T_EXTENSION","T_CHAR", +"T_DOUBLE","T_FLOAT","T_INT","T_VOID","T_LONG","T_SHORT","T_SIGNED", +"T_UNSIGNED","T_ENUM","T_STRUCT","T_UNION","T_Bool","T_Complex","T_Imaginary", +"T_TYPE_QUALIFIER","T_BRACKETS","T_LBRACE","T_MATCHRBRACE","T_ELLIPSIS", +"T_INITIALIZER","T_STRING_LITERAL","T_ASM","T_ASMARG","T_VA_DCL", +"illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : program", +"program :", +"program : translation_unit", +"translation_unit : external_declaration", +"translation_unit : translation_unit external_declaration", +"external_declaration : declaration", +"external_declaration : function_definition", +"external_declaration : ';'", +"external_declaration : linkage_specification", +"external_declaration : T_ASM T_ASMARG ';'", +"external_declaration : error T_MATCHRBRACE", +"external_declaration : error ';'", +"braces : T_LBRACE T_MATCHRBRACE", +"linkage_specification : T_EXTERN T_STRING_LITERAL braces", +"linkage_specification : T_EXTERN T_STRING_LITERAL declaration", +"declaration : decl_specifiers ';'", +"declaration : decl_specifiers init_declarator_list ';'", +"$$1 :", +"declaration : any_typedef decl_specifiers $$1 opt_declarator_list ';'", +"any_typedef : T_EXTENSION T_TYPEDEF", +"any_typedef : T_TYPEDEF", +"opt_declarator_list :", +"opt_declarator_list : declarator_list", +"declarator_list : declarator", +"declarator_list : declarator_list ',' declarator", +"$$2 :", +"$$3 :", +"function_definition : decl_specifiers declarator $$2 opt_declaration_list T_LBRACE $$3 T_MATCHRBRACE", +"$$4 :", +"function_definition : declarator $$4 opt_declaration_list T_LBRACE T_MATCHRBRACE", +"opt_declaration_list :", +"opt_declaration_list : T_VA_DCL", +"opt_declaration_list : declaration_list", +"declaration_list : declaration", +"declaration_list : declaration_list declaration", +"decl_specifiers : decl_specifier", +"decl_specifiers : decl_specifiers decl_specifier", +"decl_specifier : storage_class", +"decl_specifier : type_specifier", +"decl_specifier : type_qualifier", +"storage_class : T_AUTO", +"storage_class : T_EXTERN", +"storage_class : T_REGISTER", +"storage_class : T_STATIC", +"storage_class : T_INLINE", +"storage_class : T_EXTENSION", +"type_specifier : T_CHAR", +"type_specifier : T_DOUBLE", +"type_specifier : T_FLOAT", +"type_specifier : T_INT", +"type_specifier : T_LONG", +"type_specifier : T_SHORT", +"type_specifier : T_SIGNED", +"type_specifier : T_UNSIGNED", +"type_specifier : T_VOID", +"type_specifier : T_Bool", +"type_specifier : T_Complex", +"type_specifier : T_Imaginary", +"type_specifier : T_TYPEDEF_NAME", +"type_specifier : struct_or_union_specifier", +"type_specifier : enum_specifier", +"type_qualifier : T_TYPE_QUALIFIER", +"type_qualifier : T_DEFINE_NAME", +"struct_or_union_specifier : struct_or_union any_id braces", +"struct_or_union_specifier : struct_or_union braces", +"struct_or_union_specifier : struct_or_union any_id", +"struct_or_union : T_STRUCT", +"struct_or_union : T_UNION", +"init_declarator_list : init_declarator", +"init_declarator_list : init_declarator_list ',' init_declarator", +"init_declarator : declarator", +"$$5 :", +"init_declarator : declarator '=' $$5 T_INITIALIZER", +"enum_specifier : enumeration any_id braces", +"enum_specifier : enumeration braces", +"enum_specifier : enumeration any_id", +"enumeration : T_ENUM", +"any_id : T_IDENTIFIER", +"any_id : T_TYPEDEF_NAME", +"declarator : pointer direct_declarator", +"declarator : direct_declarator", +"direct_declarator : identifier_or_ref", +"direct_declarator : '(' declarator ')'", +"direct_declarator : direct_declarator T_BRACKETS", +"direct_declarator : direct_declarator '(' parameter_type_list ')'", +"direct_declarator : direct_declarator '(' opt_identifier_list ')'", +"pointer : '*' opt_type_qualifiers", +"pointer : '*' opt_type_qualifiers pointer", +"opt_type_qualifiers :", +"opt_type_qualifiers : type_qualifier_list", +"type_qualifier_list : type_qualifier", +"type_qualifier_list : type_qualifier_list type_qualifier", +"parameter_type_list : parameter_list", +"parameter_type_list : parameter_list ',' T_ELLIPSIS", +"parameter_list : parameter_declaration", +"parameter_list : parameter_list ',' parameter_declaration", +"parameter_declaration : decl_specifiers declarator", +"parameter_declaration : decl_specifiers abs_declarator", +"parameter_declaration : decl_specifiers", +"opt_identifier_list :", +"opt_identifier_list : identifier_list", +"identifier_list : any_id", +"identifier_list : identifier_list ',' any_id", +"identifier_or_ref : any_id", +"identifier_or_ref : '&' any_id", +"abs_declarator : pointer", +"abs_declarator : pointer direct_abs_declarator", +"abs_declarator : direct_abs_declarator", +"direct_abs_declarator : '(' abs_declarator ')'", +"direct_abs_declarator : direct_abs_declarator T_BRACKETS", +"direct_abs_declarator : T_BRACKETS", +"direct_abs_declarator : direct_abs_declarator '(' parameter_type_list ')'", +"direct_abs_declarator : direct_abs_declarator '(' ')'", +"direct_abs_declarator : '(' parameter_type_list ')'", +"direct_abs_declarator : '(' ')'", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 1014 "grammar.y" + +/* lex.yy.c */ +#define BEGIN yy_start = 1 + 2 * + +#define CPP1 1 +#define INIT1 2 +#define INIT2 3 +#define CURLY 4 +#define LEXYACC 5 +#define ASM 6 +#define CPP_INLINE 7 + +extern char *yytext; +extern FILE *yyin, *yyout; + +static int curly; /* number of curly brace nesting levels */ +static int ly_count; /* number of occurrences of %% */ +static int inc_depth; /* include nesting level */ +static SymbolTable *included_files; /* files already included */ +static int yy_start = 0; /* start state number */ + +#define grammar_error(s) yaccError(s) + +static void +yaccError (const char *msg) +{ + func_params = NULL; + put_error(); /* tell what line we're on, and what file */ + fprintf(stderr, "%s at token '%s'\n", msg, yytext); +} + +/* Initialize the table of type qualifier keywords recognized by the lexical + * analyzer. + */ +void +init_parser (void) +{ + static const char *keywords[] = { + "const", + "restrict", + "volatile", + "interrupt", +#ifdef vms + "noshare", + "readonly", +#endif +#if defined(MSDOS) || defined(OS2) + "__cdecl", + "__export", + "__far", + "__fastcall", + "__fortran", + "__huge", + "__inline", + "__interrupt", + "__loadds", + "__near", + "__pascal", + "__saveregs", + "__segment", + "__stdcall", + "__syscall", + "_cdecl", + "_cs", + "_ds", + "_es", + "_export", + "_far", + "_fastcall", + "_fortran", + "_huge", + "_interrupt", + "_loadds", + "_near", + "_pascal", + "_saveregs", + "_seg", + "_segment", + "_ss", + "cdecl", + "far", + "huge", + "near", + "pascal", +#ifdef OS2 + "__far16", +#endif +#endif +#ifdef __GNUC__ + /* gcc aliases */ + "__builtin_va_arg", + "__builtin_va_list", + "__const", + "__const__", + "__inline", + "__inline__", + "__restrict", + "__restrict__", + "__volatile", + "__volatile__", +#endif + }; + unsigned i; + + /* Initialize type qualifier table. */ + type_qualifiers = new_symbol_table(); + for (i = 0; i < sizeof(keywords)/sizeof(keywords[0]); ++i) { + new_symbol(type_qualifiers, keywords[i], NULL, DS_NONE); + } +} + +/* Process the C source file. Write function prototypes to the standard + * output. Convert function definitions and write the converted source + * code to a temporary file. + */ +void +process_file (FILE *infile, char *name) +{ + char *s; + + if (strlen(name) > 2) { + s = name + strlen(name) - 2; + if (*s == '.') { + ++s; + if (*s == 'l' || *s == 'y') + BEGIN LEXYACC; +#if defined(MSDOS) || defined(OS2) + if (*s == 'L' || *s == 'Y') + BEGIN LEXYACC; +#endif + } + } + + included_files = new_symbol_table(); + typedef_names = new_symbol_table(); + define_names = new_symbol_table(); + inc_depth = -1; + curly = 0; + ly_count = 0; + func_params = NULL; + yyin = infile; + include_file(strcpy(base_file, name), func_style != FUNC_NONE); + if (file_comments) { +#if OPT_LINTLIBRARY + if (lintLibrary()) { + put_blankline(stdout); + begin_tracking(); + } +#endif + put_string(stdout, "/* "); + put_string(stdout, cur_file_name()); + put_string(stdout, " */\n"); + } + yyparse(); + free_symbol_table(define_names); + free_symbol_table(typedef_names); + free_symbol_table(included_files); +} + +#ifdef NO_LEAKS +void +free_parser(void) +{ + free_symbol_table (type_qualifiers); +#ifdef FLEX_SCANNER + if (yy_current_buffer != 0) + yy_delete_buffer(yy_current_buffer); +#endif +} +#endif +#line 1006 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 10: +#line 377 "grammar.y" + { + yyerrok; + } +break; +case 11: +#line 381 "grammar.y" + { + yyerrok; + } +break; +case 13: +#line 392 "grammar.y" + { + /* Provide an empty action here so bison will not complain about + * incompatible types in the default action it normally would + * have generated. + */ + } +break; +case 14: +#line 399 "grammar.y" + { + /* empty */ + } +break; +case 15: +#line 406 "grammar.y" + { +#if OPT_LINTLIBRARY + if (types_out && want_typedef()) { + gen_declarations(&yystack.l_mark[-1].decl_spec, (DeclaratorList *)0); + flush_varargs(); + } +#endif + free_decl_spec(&yystack.l_mark[-1].decl_spec); + end_typedef(); + } +break; +case 16: +#line 417 "grammar.y" + { + if (func_params != NULL) { + set_param_types(func_params, &yystack.l_mark[-2].decl_spec, &yystack.l_mark[-1].decl_list); + } else { + gen_declarations(&yystack.l_mark[-2].decl_spec, &yystack.l_mark[-1].decl_list); +#if OPT_LINTLIBRARY + flush_varargs(); +#endif + free_decl_list(&yystack.l_mark[-1].decl_list); + } + free_decl_spec(&yystack.l_mark[-2].decl_spec); + end_typedef(); + } +break; +case 17: +#line 431 "grammar.y" + { + cur_decl_spec_flags = yystack.l_mark[0].decl_spec.flags; + free_decl_spec(&yystack.l_mark[0].decl_spec); + } +break; +case 18: +#line 436 "grammar.y" + { + end_typedef(); + } +break; +case 19: +#line 443 "grammar.y" + { + begin_typedef(); + } +break; +case 20: +#line 447 "grammar.y" + { + begin_typedef(); + } +break; +case 23: +#line 459 "grammar.y" + { + int flags = cur_decl_spec_flags; + + /* If the typedef is a pointer type, then reset the short type + * flags so it does not get promoted. + */ + if (strcmp(yystack.l_mark[0].declarator->text, yystack.l_mark[0].declarator->name) != 0) + flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT); + new_symbol(typedef_names, yystack.l_mark[0].declarator->name, NULL, flags); + free_declarator(yystack.l_mark[0].declarator); + } +break; +case 24: +#line 471 "grammar.y" + { + int flags = cur_decl_spec_flags; + + if (strcmp(yystack.l_mark[0].declarator->text, yystack.l_mark[0].declarator->name) != 0) + flags &= ~(DS_CHAR | DS_SHORT | DS_FLOAT); + new_symbol(typedef_names, yystack.l_mark[0].declarator->name, NULL, flags); + free_declarator(yystack.l_mark[0].declarator); + } +break; +case 25: +#line 483 "grammar.y" + { + check_untagged(&yystack.l_mark[-1].decl_spec); + if (yystack.l_mark[0].declarator->func_def == FUNC_NONE) { + yyerror("syntax error"); + YYERROR; + } + func_params = &(yystack.l_mark[0].declarator->head->params); + func_params->begin_comment = cur_file->begin_comment; + func_params->end_comment = cur_file->end_comment; + } +break; +case 26: +#line 494 "grammar.y" + { + /* If we're converting to K&R and we've got a nominally K&R + * function which has a parameter which is ANSI (i.e., a prototyped + * function pointer), then we must override the deciphered value of + * 'func_def' so that the parameter will be converted. + */ + if (func_style == FUNC_TRADITIONAL + && haveAnsiParam() + && yystack.l_mark[-3].declarator->head->func_def == func_style) { + yystack.l_mark[-3].declarator->head->func_def = FUNC_BOTH; + } + + func_params = NULL; + + if (cur_file->convert) + gen_func_definition(&yystack.l_mark[-4].decl_spec, yystack.l_mark[-3].declarator); + gen_prototype(&yystack.l_mark[-4].decl_spec, yystack.l_mark[-3].declarator); +#if OPT_LINTLIBRARY + flush_varargs(); +#endif + free_decl_spec(&yystack.l_mark[-4].decl_spec); + free_declarator(yystack.l_mark[-3].declarator); + } +break; +case 28: +#line 519 "grammar.y" + { + if (yystack.l_mark[0].declarator->func_def == FUNC_NONE) { + yyerror("syntax error"); + YYERROR; + } + func_params = &(yystack.l_mark[0].declarator->head->params); + func_params->begin_comment = cur_file->begin_comment; + func_params->end_comment = cur_file->end_comment; + } +break; +case 29: +#line 529 "grammar.y" + { + DeclSpec decl_spec; + + func_params = NULL; + + new_decl_spec(&decl_spec, dft_decl_spec(), yystack.l_mark[-4].declarator->begin, DS_NONE); + if (cur_file->convert) + gen_func_definition(&decl_spec, yystack.l_mark[-4].declarator); + gen_prototype(&decl_spec, yystack.l_mark[-4].declarator); +#if OPT_LINTLIBRARY + flush_varargs(); +#endif + free_decl_spec(&decl_spec); + free_declarator(yystack.l_mark[-4].declarator); + } +break; +case 36: +#line 560 "grammar.y" + { + join_decl_specs(&yyval.decl_spec, &yystack.l_mark[-1].decl_spec, &yystack.l_mark[0].decl_spec); + free(yystack.l_mark[-1].decl_spec.text); + free(yystack.l_mark[0].decl_spec.text); + } +break; +case 40: +#line 575 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 41: +#line 579 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_EXTERN); + } +break; +case 42: +#line 583 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 43: +#line 587 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_STATIC); + } +break; +case 44: +#line 591 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_INLINE); + } +break; +case 45: +#line 595 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_JUNK); + } +break; +case 46: +#line 602 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_CHAR); + } +break; +case 47: +#line 606 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 48: +#line 610 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_FLOAT); + } +break; +case 49: +#line 614 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 50: +#line 618 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 51: +#line 622 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_SHORT); + } +break; +case 52: +#line 626 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 53: +#line 630 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 54: +#line 634 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 55: +#line 638 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_CHAR); + } +break; +case 56: +#line 642 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 57: +#line 646 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 58: +#line 650 "grammar.y" + { + Symbol *s; + s = find_symbol(typedef_names, yystack.l_mark[0].text.text); + if (s != NULL) + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, s->flags); + } +break; +case 61: +#line 662 "grammar.y" + { + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, DS_NONE); + } +break; +case 62: +#line 666 "grammar.y" + { + /* This rule allows the <pointer> nonterminal to scan #define + * names as if they were type modifiers. + */ + Symbol *s; + s = find_symbol(define_names, yystack.l_mark[0].text.text); + if (s != NULL) + new_decl_spec(&yyval.decl_spec, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin, s->flags); + } +break; +case 63: +#line 679 "grammar.y" + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "%s %s", yystack.l_mark[-2].text.text, yystack.l_mark[-1].text.text); + new_decl_spec(&yyval.decl_spec, s, yystack.l_mark[-2].text.begin, DS_NONE); + } +break; +case 64: +#line 686 "grammar.y" + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "%s {}", yystack.l_mark[-1].text.text); + new_decl_spec(&yyval.decl_spec, s, yystack.l_mark[-1].text.begin, DS_NONE); + } +break; +case 65: +#line 693 "grammar.y" + { + (void)sprintf(buf, "%s %s", yystack.l_mark[-1].text.text, yystack.l_mark[0].text.text); + new_decl_spec(&yyval.decl_spec, buf, yystack.l_mark[-1].text.begin, DS_NONE); + } +break; +case 66: +#line 701 "grammar.y" + { + imply_typedef(yyval.text.text); + } +break; +case 67: +#line 705 "grammar.y" + { + imply_typedef(yyval.text.text); + } +break; +case 68: +#line 712 "grammar.y" + { + new_decl_list(&yyval.decl_list, yystack.l_mark[0].declarator); + } +break; +case 69: +#line 716 "grammar.y" + { + add_decl_list(&yyval.decl_list, &yystack.l_mark[-2].decl_list, yystack.l_mark[0].declarator); + } +break; +case 70: +#line 723 "grammar.y" + { + if (yystack.l_mark[0].declarator->func_def != FUNC_NONE && func_params == NULL && + func_style == FUNC_TRADITIONAL && cur_file->convert) { + gen_func_declarator(yystack.l_mark[0].declarator); + fputs(cur_text(), cur_file->tmp_file); + } + cur_declarator = yyval.declarator; + } +break; +case 71: +#line 732 "grammar.y" + { + if (yystack.l_mark[-1].declarator->func_def != FUNC_NONE && func_params == NULL && + func_style == FUNC_TRADITIONAL && cur_file->convert) { + gen_func_declarator(yystack.l_mark[-1].declarator); + fputs(" =", cur_file->tmp_file); + } + } +break; +case 73: +#line 744 "grammar.y" + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "enum %s", yystack.l_mark[-1].text.text); + new_decl_spec(&yyval.decl_spec, s, yystack.l_mark[-2].text.begin, DS_NONE); + } +break; +case 74: +#line 751 "grammar.y" + { + char *s; + if ((s = implied_typedef()) == 0) + (void)sprintf(s = buf, "%s {}", yystack.l_mark[-1].text.text); + new_decl_spec(&yyval.decl_spec, s, yystack.l_mark[-1].text.begin, DS_NONE); + } +break; +case 75: +#line 758 "grammar.y" + { + (void)sprintf(buf, "enum %s", yystack.l_mark[0].text.text); + new_decl_spec(&yyval.decl_spec, buf, yystack.l_mark[-1].text.begin, DS_NONE); + } +break; +case 76: +#line 766 "grammar.y" + { + imply_typedef("enum"); + yyval.text = yystack.l_mark[0].text; + } +break; +case 79: +#line 779 "grammar.y" + { + yyval.declarator = yystack.l_mark[0].declarator; + (void)sprintf(buf, "%s%s", yystack.l_mark[-1].text.text, yyval.declarator->text); + free(yyval.declarator->text); + yyval.declarator->text = xstrdup(buf); + yyval.declarator->begin = yystack.l_mark[-1].text.begin; + yyval.declarator->pointer = TRUE; + } +break; +case 81: +#line 792 "grammar.y" + { + yyval.declarator = new_declarator(yystack.l_mark[0].text.text, yystack.l_mark[0].text.text, yystack.l_mark[0].text.begin); + } +break; +case 82: +#line 796 "grammar.y" + { + yyval.declarator = yystack.l_mark[-1].declarator; + (void)sprintf(buf, "(%s)", yyval.declarator->text); + free(yyval.declarator->text); + yyval.declarator->text = xstrdup(buf); + yyval.declarator->begin = yystack.l_mark[-2].text.begin; + } +break; +case 83: +#line 804 "grammar.y" + { + yyval.declarator = yystack.l_mark[-1].declarator; + (void)sprintf(buf, "%s%s", yyval.declarator->text, yystack.l_mark[0].text.text); + free(yyval.declarator->text); + yyval.declarator->text = xstrdup(buf); + } +break; +case 84: +#line 811 "grammar.y" + { + yyval.declarator = new_declarator("%s()", yystack.l_mark[-3].declarator->name, yystack.l_mark[-3].declarator->begin); + yyval.declarator->params = yystack.l_mark[-1].param_list; + yyval.declarator->func_stack = yystack.l_mark[-3].declarator; + yyval.declarator->head = (yystack.l_mark[-3].declarator->func_stack == NULL) ? yyval.declarator : yystack.l_mark[-3].declarator->head; + yyval.declarator->func_def = FUNC_ANSI; + } +break; +case 85: +#line 819 "grammar.y" + { + yyval.declarator = new_declarator("%s()", yystack.l_mark[-3].declarator->name, yystack.l_mark[-3].declarator->begin); + yyval.declarator->params = yystack.l_mark[-1].param_list; + yyval.declarator->func_stack = yystack.l_mark[-3].declarator; + yyval.declarator->head = (yystack.l_mark[-3].declarator->func_stack == NULL) ? yyval.declarator : yystack.l_mark[-3].declarator->head; + yyval.declarator->func_def = FUNC_TRADITIONAL; + } +break; +case 86: +#line 830 "grammar.y" + { + (void)sprintf(yyval.text.text, "*%s", yystack.l_mark[0].text.text); + yyval.text.begin = yystack.l_mark[-1].text.begin; + } +break; +case 87: +#line 835 "grammar.y" + { + (void)sprintf(yyval.text.text, "*%s%s", yystack.l_mark[-1].text.text, yystack.l_mark[0].text.text); + yyval.text.begin = yystack.l_mark[-2].text.begin; + } +break; +case 88: +#line 843 "grammar.y" + { + strcpy(yyval.text.text, ""); + yyval.text.begin = 0L; + } +break; +case 90: +#line 852 "grammar.y" + { + (void)sprintf(yyval.text.text, "%s ", yystack.l_mark[0].decl_spec.text); + yyval.text.begin = yystack.l_mark[0].decl_spec.begin; + free(yystack.l_mark[0].decl_spec.text); + } +break; +case 91: +#line 858 "grammar.y" + { + (void)sprintf(yyval.text.text, "%s%s ", yystack.l_mark[-1].text.text, yystack.l_mark[0].decl_spec.text); + yyval.text.begin = yystack.l_mark[-1].text.begin; + free(yystack.l_mark[0].decl_spec.text); + } +break; +case 93: +#line 868 "grammar.y" + { + add_ident_list(&yyval.param_list, &yystack.l_mark[-2].param_list, "..."); + } +break; +case 94: +#line 875 "grammar.y" + { + new_param_list(&yyval.param_list, yystack.l_mark[0].parameter); + } +break; +case 95: +#line 879 "grammar.y" + { + add_param_list(&yyval.param_list, &yystack.l_mark[-2].param_list, yystack.l_mark[0].parameter); + } +break; +case 96: +#line 886 "grammar.y" + { + check_untagged(&yystack.l_mark[-1].decl_spec); + yyval.parameter = new_parameter(&yystack.l_mark[-1].decl_spec, yystack.l_mark[0].declarator); + } +break; +case 97: +#line 891 "grammar.y" + { + check_untagged(&yystack.l_mark[-1].decl_spec); + yyval.parameter = new_parameter(&yystack.l_mark[-1].decl_spec, yystack.l_mark[0].declarator); + } +break; +case 98: +#line 896 "grammar.y" + { + check_untagged(&yystack.l_mark[0].decl_spec); + yyval.parameter = new_parameter(&yystack.l_mark[0].decl_spec, (Declarator *)0); + } +break; +case 99: +#line 904 "grammar.y" + { + new_ident_list(&yyval.param_list); + } +break; +case 101: +#line 912 "grammar.y" + { + new_ident_list(&yyval.param_list); + add_ident_list(&yyval.param_list, &yyval.param_list, yystack.l_mark[0].text.text); + } +break; +case 102: +#line 917 "grammar.y" + { + add_ident_list(&yyval.param_list, &yystack.l_mark[-2].param_list, yystack.l_mark[0].text.text); + } +break; +case 103: +#line 924 "grammar.y" + { + yyval.text = yystack.l_mark[0].text; + } +break; +case 104: +#line 928 "grammar.y" + { +#if OPT_LINTLIBRARY + if (lintLibrary()) { /* Lint doesn't grok C++ ref variables */ + yyval.text = yystack.l_mark[0].text; + } else +#endif + (void)sprintf(yyval.text.text, "&%s", yystack.l_mark[0].text.text); + yyval.text.begin = yystack.l_mark[-1].text.begin; + } +break; +case 105: +#line 941 "grammar.y" + { + yyval.declarator = new_declarator(yystack.l_mark[0].text.text, "", yystack.l_mark[0].text.begin); + } +break; +case 106: +#line 945 "grammar.y" + { + yyval.declarator = yystack.l_mark[0].declarator; + (void)sprintf(buf, "%s%s", yystack.l_mark[-1].text.text, yyval.declarator->text); + free(yyval.declarator->text); + yyval.declarator->text = xstrdup(buf); + yyval.declarator->begin = yystack.l_mark[-1].text.begin; + } +break; +case 108: +#line 957 "grammar.y" + { + yyval.declarator = yystack.l_mark[-1].declarator; + (void)sprintf(buf, "(%s)", yyval.declarator->text); + free(yyval.declarator->text); + yyval.declarator->text = xstrdup(buf); + yyval.declarator->begin = yystack.l_mark[-2].text.begin; + } +break; +case 109: +#line 965 "grammar.y" + { + yyval.declarator = yystack.l_mark[-1].declarator; + (void)sprintf(buf, "%s%s", yyval.declarator->text, yystack.l_mark[0].text.text); + free(yyval.declarator->text); + yyval.declarator->text = xstrdup(buf); + } +break; +case 110: +#line 972 "grammar.y" + { + yyval.declarator = new_declarator(yystack.l_mark[0].text.text, "", yystack.l_mark[0].text.begin); + } +break; +case 111: +#line 976 "grammar.y" + { + yyval.declarator = new_declarator("%s()", "", yystack.l_mark[-3].declarator->begin); + yyval.declarator->params = yystack.l_mark[-1].param_list; + yyval.declarator->func_stack = yystack.l_mark[-3].declarator; + yyval.declarator->head = (yystack.l_mark[-3].declarator->func_stack == NULL) ? yyval.declarator : yystack.l_mark[-3].declarator->head; + yyval.declarator->func_def = FUNC_ANSI; + } +break; +case 112: +#line 984 "grammar.y" + { + yyval.declarator = new_declarator("%s()", "", yystack.l_mark[-2].declarator->begin); + yyval.declarator->func_stack = yystack.l_mark[-2].declarator; + yyval.declarator->head = (yystack.l_mark[-2].declarator->func_stack == NULL) ? yyval.declarator : yystack.l_mark[-2].declarator->head; + yyval.declarator->func_def = FUNC_ANSI; + } +break; +case 113: +#line 991 "grammar.y" + { + Declarator *d; + + d = new_declarator("", "", yystack.l_mark[-2].text.begin); + yyval.declarator = new_declarator("%s()", "", yystack.l_mark[-2].text.begin); + yyval.declarator->params = yystack.l_mark[-1].param_list; + yyval.declarator->func_stack = d; + yyval.declarator->head = yyval.declarator; + yyval.declarator->func_def = FUNC_ANSI; + } +break; +case 114: +#line 1002 "grammar.y" + { + Declarator *d; + + d = new_declarator("", "", yystack.l_mark[-1].text.begin); + yyval.declarator = new_declarator("%s()", "", yystack.l_mark[-1].text.begin); + yyval.declarator->func_stack = d; + yyval.declarator->head = yyval.declarator; + yyval.declarator->func_def = FUNC_ANSI; + } +break; +#line 1882 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.09.out b/usr.bin/yacc/tests/regress.09.out new file mode 100644 index 0000000..b6c13e2 --- /dev/null +++ b/usr.bin/yacc/tests/regress.09.out @@ -0,0 +1,599 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "pure_calc.y" +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +#ifdef YYBISON +#define YYSTYPE int +#define YYLEX_PARAM &yylval +#define YYLEX_DECL() yylex(YYSTYPE *yylval) +#define YYERROR_DECL() yyerror(const char *s) +int YYLEX_DECL(); +static void YYERROR_DECL(); +#endif + +#line 35 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define DIGIT 257 +#define LETTER 258 +#define UMINUS 259 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 17, 0, 0, 0, 0, 0, 0, 3, + 0, 15, 14, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 9, + 10, 11, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -40, -7, 0, -55, -38, -38, 1, -29, -247, 0, + -38, 0, 0, 22, 0, -38, -38, -38, -38, -38, + -38, -38, 0, -29, 0, 51, 60, -20, -20, 0, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 2, 0, 0, 0, 9, -9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, -6, 14, 5, 13, 0, + 0, 0, +}; +static const short yygindex[] = { 0, + 0, 65, 0, +}; +#define YYTABLESIZE 220 +static const short yytable[] = { 6, + 16, 6, 10, 13, 5, 11, 5, 22, 17, 23, + 15, 15, 20, 18, 7, 19, 22, 21, 4, 5, + 0, 20, 8, 12, 0, 0, 21, 16, 16, 0, + 0, 16, 16, 16, 13, 16, 0, 16, 15, 15, + 0, 0, 7, 15, 15, 7, 15, 7, 15, 7, + 8, 12, 0, 8, 12, 8, 0, 8, 22, 17, + 0, 0, 25, 20, 18, 0, 19, 0, 21, 13, + 14, 0, 0, 0, 0, 24, 0, 0, 0, 0, + 26, 27, 28, 29, 30, 31, 32, 22, 17, 0, + 0, 0, 20, 18, 16, 19, 22, 21, 0, 0, + 0, 20, 18, 0, 19, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 16, 0, 0, 13, 0, 0, + 0, 0, 0, 0, 0, 15, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 8, 12, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 3, 4, 3, 12, +}; +static const short yycheck[] = { 40, + 10, 40, 10, 10, 45, 61, 45, 37, 38, 257, + 10, 10, 42, 43, 10, 45, 37, 47, 10, 10, + -1, 42, 10, 10, -1, -1, 47, 37, 38, -1, + -1, 41, 42, 43, 41, 45, -1, 47, 37, 38, + -1, -1, 38, 42, 43, 41, 45, 43, 47, 45, + 38, 38, -1, 41, 41, 43, -1, 45, 37, 38, + -1, -1, 41, 42, 43, -1, 45, -1, 47, 5, + 6, -1, -1, -1, -1, 11, -1, -1, -1, -1, + 16, 17, 18, 19, 20, 21, 22, 37, 38, -1, + -1, -1, 42, 43, 124, 45, 37, 47, -1, -1, + -1, 42, 43, -1, 45, -1, 47, -1, -1, -1, + -1, -1, -1, -1, 124, -1, -1, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, 124, -1, + -1, -1, -1, -1, -1, -1, 124, 124, -1, -1, + -1, -1, -1, -1, -1, 124, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 256, 257, 258, 257, 258, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 259 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"DIGIT","LETTER","UMINUS","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr '+' expr", +"expr : expr '-' expr", +"expr : expr '*' expr", +"expr : expr '/' expr", +"expr : expr '%' expr", +"expr : expr '&' expr", +"expr : expr '|' expr", +"expr : '-' expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 72 "pure_calc.y" + /* start of programs */ + +#ifdef YYBYACC +static int YYLEX_DECL(); +#endif + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +YYERROR_DECL() +{ + fprintf(stderr, "%s\n", s); +} + +int +YYLEX_DECL() +{ + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + *yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + *yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} +#line 277 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 34 "pure_calc.y" + { yyerrok ; } +break; +case 4: +#line 38 "pure_calc.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 40 "pure_calc.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 44 "pure_calc.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 46 "pure_calc.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 48 "pure_calc.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 50 "pure_calc.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 52 "pure_calc.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 54 "pure_calc.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 56 "pure_calc.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 58 "pure_calc.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 60 "pure_calc.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 62 "pure_calc.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 67 "pure_calc.y" + { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 69 "pure_calc.y" + { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 539 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.10.out b/usr.bin/yacc/tests/regress.10.out new file mode 100644 index 0000000..f4a5ba4 --- /dev/null +++ b/usr.bin/yacc/tests/regress.10.out @@ -0,0 +1,429 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "pure_error.y" + +#ifdef YYBISON +#define YYSTYPE int +#define YYLEX_PARAM &yylval +#define YYLEX_DECL() yylex(YYSTYPE *yylval) +#define YYERROR_DECL() yyerror(const char *s) +int YYLEX_DECL(); +static void YYERROR_DECL(); +#endif + +#line 30 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, +}; +static const short yylen[] = { 2, + 1, +}; +static const short yydefred[] = { 0, + 1, 0, +}; +static const short yydgoto[] = { 2, +}; +static const short yysindex[] = { -256, + 0, 0, +}; +static const short yyrindex[] = { 0, + 0, 0, +}; +static const short yygindex[] = { 0, +}; +#define YYTABLESIZE 0 +static const short yytable[] = { 1, +}; +static const short yycheck[] = { 256, +}; +#define YYFINAL 2 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 0 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : S", +"S : error", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 17 "pure_error.y" + +#include <stdio.h> + +#ifdef YYBYACC +extern int YYLEX_DECL(); +#endif + +int +main(void) +{ + printf("yyparse() = %d\n", yyparse()); + return 0; +} + +int +yylex(YYSTYPE *value) +{ + return value ? 0 : -1; +} + +static void +yyerror(const char* s) +{ + printf("%s\n", s); +} +#line 168 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.11.out b/usr.bin/yacc/tests/regress.11.out new file mode 100644 index 0000000..8668971 --- /dev/null +++ b/usr.bin/yacc/tests/regress.11.out @@ -0,0 +1,610 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "quote_calc.y" +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +#line 29 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define OP_ADD 257 +#define ADD 258 +#define OP_SUB 259 +#define SUB 260 +#define OP_MUL 261 +#define MUL 262 +#define OP_DIV 263 +#define DIV 264 +#define OP_MOD 265 +#define MOD 266 +#define OP_AND 267 +#define AND 268 +#define DIGIT 269 +#define LETTER 270 +#define UMINUS 271 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 0, 17, 0, 0, 0, 0, 0, 3, + 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 0, + 0, 0, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -38, 5, -36, 0, -51, -36, 7, -121, -248, 0, + 0, -243, -36, -22, 0, -36, -36, -36, -36, -36, + -36, -36, 0, -121, 0, -121, -121, -121, -121, -121, + -121, -243, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 0, -9, 0, 0, 13, -10, 0, + 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 0, -3, -2, -1, 1, 2, + 3, -4, +}; +static const short yygindex[] = { 0, + 0, 42, 0, +}; +#define YYTABLESIZE 258 +static const short yytable[] = { 16, + 15, 6, 22, 6, 14, 13, 7, 8, 9, 13, + 10, 11, 12, 16, 10, 17, 15, 18, 25, 19, + 23, 20, 4, 21, 5, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 14, 13, 7, 8, 9, + 0, 10, 11, 12, 12, 0, 0, 14, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 26, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 15, 0, 0, 0, 14, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 17, 0, 18, + 0, 19, 0, 20, 0, 21, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 4, 5, 4, 11, 16, 0, 17, 0, 18, 0, + 19, 0, 20, 0, 21, 0, 16, 15, 16, 15, + 16, 15, 16, 15, 16, 15, 16, 15, +}; +static const short yycheck[] = { 10, + 10, 40, 124, 40, 10, 10, 10, 10, 10, 61, + 10, 10, 10, 257, 10, 259, 10, 261, 41, 263, + 269, 265, 10, 267, 10, -1, -1, -1, -1, -1, + 41, -1, -1, -1, -1, 41, 41, 41, 41, 41, + -1, 41, 41, 41, 3, -1, -1, 6, -1, -1, + -1, -1, -1, -1, 13, -1, -1, 16, 17, 18, + 19, 20, 21, 22, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 124, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 124, 124, -1, -1, -1, 124, 124, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 257, -1, 259, -1, 261, + -1, 263, -1, 265, -1, 267, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, + 259, -1, 259, -1, -1, -1, -1, -1, -1, -1, + 269, 270, 269, 270, 257, -1, 259, -1, 261, -1, + 263, -1, 265, -1, 267, -1, 257, 257, 259, 259, + 261, 261, 263, 263, 265, 265, 267, 267, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 271 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"OP_ADD","\"ADD\"","OP_SUB","\"SUB\"","OP_MUL","\"MUL\"","OP_DIV", +"\"DIV\"","OP_MOD","\"MOD\"","OP_AND","\"AND\"","DIGIT","LETTER","UMINUS", +"illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr OP_ADD expr", +"expr : expr OP_SUB expr", +"expr : expr OP_MUL expr", +"expr : expr OP_DIV expr", +"expr : expr OP_MOD expr", +"expr : expr OP_AND expr", +"expr : expr '|' expr", +"expr : OP_SUB expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 73 "quote_calc.y" + /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} +#line 288 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 35 "quote_calc.y" + { yyerrok ; } +break; +case 4: +#line 39 "quote_calc.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 41 "quote_calc.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 45 "quote_calc.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 47 "quote_calc.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 49 "quote_calc.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 51 "quote_calc.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 53 "quote_calc.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 55 "quote_calc.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 57 "quote_calc.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 59 "quote_calc.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 61 "quote_calc.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 63 "quote_calc.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 68 "quote_calc.y" + { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 70 "quote_calc.y" + { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 550 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.12.out b/usr.bin/yacc/tests/regress.12.out new file mode 100644 index 0000000..757c977 --- /dev/null +++ b/usr.bin/yacc/tests/regress.12.out @@ -0,0 +1,610 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "quote_calc2.y" +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +#line 29 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define OP_ADD 257 +#define ADD 258 +#define OP_SUB 259 +#define SUB 260 +#define OP_MUL 261 +#define MUL 262 +#define OP_DIV 263 +#define DIV 264 +#define OP_MOD 265 +#define MOD 266 +#define OP_AND 267 +#define AND 268 +#define DIGIT 269 +#define LETTER 270 +#define UMINUS 271 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 0, 17, 0, 0, 0, 0, 0, 3, + 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 0, + 0, 0, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -38, 4, -36, 0, -51, -36, 6, -121, -249, 0, + 0, -243, -36, -23, 0, -36, -36, -36, -36, -36, + -36, -36, 0, -121, 0, -121, -121, -121, -121, -121, + -121, -243, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 0, -9, 0, 0, 12, -10, 0, + 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 0, -3, -2, -1, 1, 2, + 3, -4, +}; +static const short yygindex[] = { 0, + 0, 42, 0, +}; +#define YYTABLESIZE 259 +static const short yytable[] = { 16, + 15, 6, 22, 6, 14, 13, 7, 8, 9, 13, + 10, 11, 12, 10, 16, 15, 17, 25, 18, 23, + 19, 4, 20, 5, 21, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 14, 13, 7, 8, 9, + 0, 10, 11, 12, 12, 0, 0, 14, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 26, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 15, 0, 0, 0, 14, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 17, 0, + 18, 0, 19, 0, 20, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, + 4, 5, 4, 11, 16, 0, 17, 0, 18, 0, + 19, 0, 20, 0, 21, 0, 0, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, 15, +}; +static const short yycheck[] = { 10, + 10, 40, 124, 40, 10, 10, 10, 10, 10, 61, + 10, 10, 10, 10, 258, 10, 260, 41, 262, 269, + 264, 10, 266, 10, 268, -1, -1, -1, -1, -1, + 41, -1, -1, -1, -1, 41, 41, 41, 41, 41, + -1, 41, 41, 41, 3, -1, -1, 6, -1, -1, + -1, -1, -1, -1, 13, -1, -1, 16, 17, 18, + 19, 20, 21, 22, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 124, 124, -1, -1, -1, 124, 124, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 258, -1, 260, -1, + 262, -1, 264, -1, 266, -1, 268, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, + -1, 260, -1, 260, -1, -1, -1, -1, -1, -1, + 269, 270, 269, 270, 258, -1, 260, -1, 262, -1, + 264, -1, 266, -1, 268, -1, -1, 258, 258, 260, + 260, 262, 262, 264, 264, 266, 266, 268, 268, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 271 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"OP_ADD","\"ADD\"","OP_SUB","\"SUB\"","OP_MUL","\"MUL\"","OP_DIV", +"\"DIV\"","OP_MOD","\"MOD\"","OP_AND","\"AND\"","DIGIT","LETTER","UMINUS", +"illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr \"ADD\" expr", +"expr : expr \"SUB\" expr", +"expr : expr \"MUL\" expr", +"expr : expr \"DIV\" expr", +"expr : expr \"MOD\" expr", +"expr : expr \"AND\" expr", +"expr : expr '|' expr", +"expr : \"SUB\" expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 73 "quote_calc2.y" + /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} +#line 288 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 35 "quote_calc2.y" + { yyerrok ; } +break; +case 4: +#line 39 "quote_calc2.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 41 "quote_calc2.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 45 "quote_calc2.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 47 "quote_calc2.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 49 "quote_calc2.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 51 "quote_calc2.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 53 "quote_calc2.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 55 "quote_calc2.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 57 "quote_calc2.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 59 "quote_calc2.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 61 "quote_calc2.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 63 "quote_calc2.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 68 "quote_calc2.y" + { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 70 "quote_calc2.y" + { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 550 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.13.out b/usr.bin/yacc/tests/regress.13.out new file mode 100644 index 0000000..94b717e --- /dev/null +++ b/usr.bin/yacc/tests/regress.13.out @@ -0,0 +1,604 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "quote_calc3.y" +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +#line 29 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define OP_ADD 257 +#define OP_SUB 259 +#define OP_MUL 261 +#define OP_DIV 263 +#define OP_MOD 265 +#define OP_AND 267 +#define DIGIT 269 +#define LETTER 270 +#define UMINUS 271 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 0, 17, 0, 0, 0, 0, 0, 3, + 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 0, + 0, 0, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -38, 5, -36, 0, -51, -36, 7, -121, -248, 0, + 0, -243, -36, -22, 0, -36, -36, -36, -36, -36, + -36, -36, 0, -121, 0, -121, -121, -121, -121, -121, + -121, -243, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 0, -9, 0, 0, 13, -10, 0, + 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 15, 0, -3, -2, -1, 1, 2, + 3, -4, +}; +static const short yygindex[] = { 0, + 0, 42, 0, +}; +#define YYTABLESIZE 258 +static const short yytable[] = { 16, + 15, 6, 22, 6, 14, 13, 7, 8, 9, 13, + 10, 11, 12, 16, 10, 17, 15, 18, 25, 19, + 23, 20, 4, 21, 5, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 14, 13, 7, 8, 9, + 0, 10, 11, 12, 12, 0, 0, 14, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 26, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 15, 0, 0, 0, 14, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 16, 0, 17, 0, 18, + 0, 19, 0, 20, 0, 21, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, + 4, 5, 4, 11, 16, 0, 17, 0, 18, 0, + 19, 0, 20, 0, 21, 0, 16, 15, 16, 15, + 16, 15, 16, 15, 16, 15, 16, 15, +}; +static const short yycheck[] = { 10, + 10, 40, 124, 40, 10, 10, 10, 10, 10, 61, + 10, 10, 10, 257, 10, 259, 10, 261, 41, 263, + 269, 265, 10, 267, 10, -1, -1, -1, -1, -1, + 41, -1, -1, -1, -1, 41, 41, 41, 41, 41, + -1, 41, 41, 41, 3, -1, -1, 6, -1, -1, + -1, -1, -1, -1, 13, -1, -1, 16, 17, 18, + 19, 20, 21, 22, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 124, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 124, 124, -1, -1, -1, 124, 124, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 257, -1, 259, -1, 261, + -1, 263, -1, 265, -1, 267, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, + 259, -1, 259, -1, -1, -1, -1, -1, -1, -1, + 269, 270, 269, 270, 257, -1, 259, -1, 261, -1, + 263, -1, 265, -1, 267, -1, 257, 257, 259, 259, + 261, 261, 263, 263, 265, 265, 267, 267, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 271 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"OP_ADD","\"ADD-operator\"","OP_SUB","\"SUB-operator\"","OP_MUL", +"\"MUL-operator\"","OP_DIV","\"DIV-operator\"","OP_MOD","\"MOD-operator\"", +"OP_AND","\"AND-operator\"","DIGIT","LETTER","UMINUS","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr OP_ADD expr", +"expr : expr OP_SUB expr", +"expr : expr OP_MUL expr", +"expr : expr OP_DIV expr", +"expr : expr OP_MOD expr", +"expr : expr OP_AND expr", +"expr : expr '|' expr", +"expr : OP_SUB expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 73 "quote_calc3.y" + /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} +#line 282 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 35 "quote_calc3.y" + { yyerrok ; } +break; +case 4: +#line 39 "quote_calc3.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 41 "quote_calc3.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 45 "quote_calc3.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 47 "quote_calc3.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 49 "quote_calc3.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 51 "quote_calc3.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 53 "quote_calc3.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 55 "quote_calc3.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 57 "quote_calc3.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 59 "quote_calc3.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 61 "quote_calc3.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 63 "quote_calc3.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 68 "quote_calc3.y" + { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 70 "quote_calc3.y" + { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 544 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.14.out b/usr.bin/yacc/tests/regress.14.out new file mode 100644 index 0000000..aecfb49 --- /dev/null +++ b/usr.bin/yacc/tests/regress.14.out @@ -0,0 +1,604 @@ +#ifndef lint +static const char yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93"; +#endif + +#define YYBYACC 1 +#define YYMAJOR 1 +#define YYMINOR 9 +#define YYPATCH 20140101 + +#define YYEMPTY (-1) +#define yyclearin (yychar = YYEMPTY) +#define yyerrok (yyerrflag = 0) +#define YYRECOVERING() (yyerrflag != 0) + +#define YYPREFIX "yy" + +#define YYPURE 0 + +#line 2 "quote_calc4.y" +# include <stdio.h> +# include <ctype.h> + +int regs[26]; +int base; + +int yylex(void); +static void yyerror(const char *s); + +#line 29 "/dev/stdout" + +#ifndef YYSTYPE +typedef int YYSTYPE; +#endif + +/* compatibility with bison */ +#ifdef YYPARSE_PARAM +/* compatibility with FreeBSD */ +# ifdef YYPARSE_PARAM_TYPE +# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM) +# else +# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM) +# endif +#else +# define YYPARSE_DECL() yyparse(void) +#endif + +/* Parameters sent to lex. */ +#ifdef YYLEX_PARAM +# define YYLEX_DECL() yylex(void *YYLEX_PARAM) +# define YYLEX yylex(YYLEX_PARAM) +#else +# define YYLEX_DECL() yylex(void) +# define YYLEX yylex() +#endif + +/* Parameters sent to yyerror. */ +#ifndef YYERROR_DECL +#define YYERROR_DECL() yyerror(const char *s) +#endif +#ifndef YYERROR_CALL +#define YYERROR_CALL(msg) yyerror(msg) +#endif + +extern int YYPARSE_DECL(); + +#define OP_ADD 257 +#define OP_SUB 259 +#define OP_MUL 261 +#define OP_DIV 263 +#define OP_MOD 265 +#define OP_AND 267 +#define DIGIT 269 +#define LETTER 270 +#define UMINUS 271 +#define YYERRCODE 256 +static const short yylhs[] = { -1, + 0, 0, 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 3, 3, +}; +static const short yylen[] = { 2, + 0, 3, 3, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 2, 1, 1, 1, 2, +}; +static const short yydefred[] = { 1, + 0, 0, 0, 17, 0, 0, 0, 0, 0, 3, + 15, 0, 0, 0, 2, 0, 0, 0, 0, 0, + 0, 0, 18, 0, 6, 0, 0, 0, 0, 0, + 0, 0, +}; +static const short yydgoto[] = { 1, + 7, 8, 9, +}; +static const short yysindex[] = { 0, + -38, 4, -36, 0, -51, -36, 6, -121, -249, 0, + 0, -243, -36, -23, 0, -36, -36, -36, -36, -36, + -36, -36, 0, -121, 0, -121, -121, -121, -121, -121, + -121, -243, +}; +static const short yyrindex[] = { 0, + 0, 0, 0, 0, -9, 0, 0, 12, -10, 0, + 0, -5, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 14, 0, -3, -2, -1, 1, 2, + 3, -4, +}; +static const short yygindex[] = { 0, + 0, 42, 0, +}; +#define YYTABLESIZE 259 +static const short yytable[] = { 16, + 15, 6, 22, 6, 14, 13, 7, 8, 9, 13, + 10, 11, 12, 10, 16, 15, 17, 25, 18, 23, + 19, 4, 20, 5, 21, 0, 0, 0, 0, 0, + 16, 0, 0, 0, 0, 14, 13, 7, 8, 9, + 0, 10, 11, 12, 12, 0, 0, 14, 0, 0, + 0, 0, 0, 0, 24, 0, 0, 26, 27, 28, + 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 15, 0, 0, 0, 14, 13, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 16, 0, 17, 0, + 18, 0, 19, 0, 20, 0, 21, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, + 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, + 4, 5, 4, 11, 16, 0, 17, 0, 18, 0, + 19, 0, 20, 0, 21, 0, 0, 16, 15, 16, + 15, 16, 15, 16, 15, 16, 15, 16, 15, +}; +static const short yycheck[] = { 10, + 10, 40, 124, 40, 10, 10, 10, 10, 10, 61, + 10, 10, 10, 10, 258, 10, 260, 41, 262, 269, + 264, 10, 266, 10, 268, -1, -1, -1, -1, -1, + 41, -1, -1, -1, -1, 41, 41, 41, 41, 41, + -1, 41, 41, 41, 3, -1, -1, 6, -1, -1, + -1, -1, -1, -1, 13, -1, -1, 16, 17, 18, + 19, 20, 21, 22, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 124, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 124, 124, -1, -1, -1, 124, 124, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 258, -1, 260, -1, + 262, -1, 264, -1, 266, -1, 268, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 256, -1, -1, + -1, 260, -1, 260, -1, -1, -1, -1, -1, -1, + 269, 270, 269, 270, 258, -1, 260, -1, 262, -1, + 264, -1, 266, -1, 268, -1, -1, 258, 258, 260, + 260, 262, 262, 264, 264, 266, 266, 268, 268, +}; +#define YYFINAL 1 +#ifndef YYDEBUG +#define YYDEBUG 0 +#endif +#define YYMAXTOKEN 271 +#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? (YYMAXTOKEN + 1) : (a)) +#if YYDEBUG +static const char *yyname[] = { + +"end-of-file",0,0,0,0,0,0,0,0,0,"'\\n'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"'%'","'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0, +0,0,0,0,0,0,"'='",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'|'",0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,"OP_ADD","\"ADD-operator\"","OP_SUB","\"SUB-operator\"","OP_MUL", +"\"MUL-operator\"","OP_DIV","\"DIV-operator\"","OP_MOD","\"MOD-operator\"", +"OP_AND","\"AND-operator\"","DIGIT","LETTER","UMINUS","illegal-symbol", +}; +static const char *yyrule[] = { +"$accept : list", +"list :", +"list : list stat '\\n'", +"list : list error '\\n'", +"stat : expr", +"stat : LETTER '=' expr", +"expr : '(' expr ')'", +"expr : expr \"ADD-operator\" expr", +"expr : expr \"SUB-operator\" expr", +"expr : expr \"MUL-operator\" expr", +"expr : expr \"DIV-operator\" expr", +"expr : expr \"MOD-operator\" expr", +"expr : expr \"AND-operator\" expr", +"expr : expr '|' expr", +"expr : \"SUB-operator\" expr", +"expr : LETTER", +"expr : number", +"number : DIGIT", +"number : number DIGIT", + +}; +#endif + +int yydebug; +int yynerrs; + +int yyerrflag; +int yychar; +YYSTYPE yyval; +YYSTYPE yylval; + +/* define the initial stack-sizes */ +#ifdef YYSTACKSIZE +#undef YYMAXDEPTH +#define YYMAXDEPTH YYSTACKSIZE +#else +#ifdef YYMAXDEPTH +#define YYSTACKSIZE YYMAXDEPTH +#else +#define YYSTACKSIZE 10000 +#define YYMAXDEPTH 10000 +#endif +#endif + +#define YYINITSTACKSIZE 200 + +typedef struct { + unsigned stacksize; + short *s_base; + short *s_mark; + short *s_last; + YYSTYPE *l_base; + YYSTYPE *l_mark; +} YYSTACKDATA; +/* variables for the parser stack */ +static YYSTACKDATA yystack; +#line 73 "quote_calc4.y" + /* start of programs */ + +int +main (void) +{ + while(!feof(stdin)) { + yyparse(); + } + return 0; +} + +static void +yyerror(const char *s) +{ + fprintf(stderr, "%s\n", s); +} + +int +yylex(void) { + /* lexical analysis routine */ + /* returns LETTER for a lower case letter, yylval = 0 through 25 */ + /* return DIGIT for a digit, yylval = 0 through 9 */ + /* all other characters are returned immediately */ + + int c; + + while( (c=getchar()) == ' ' ) { /* skip blanks */ } + + /* c is now nonblank */ + + if( islower( c )) { + yylval = c - 'a'; + return ( LETTER ); + } + if( isdigit( c )) { + yylval = c - '0'; + return ( DIGIT ); + } + return( c ); +} +#line 282 "/dev/stdout" + +#if YYDEBUG +#include <stdio.h> /* needed for printf */ +#endif + +#include <stdlib.h> /* needed for malloc, etc */ +#include <string.h> /* needed for memset */ + +/* allocate initial stack or double stack size, up to YYMAXDEPTH */ +static int yygrowstack(YYSTACKDATA *data) +{ + int i; + unsigned newsize; + short *newss; + YYSTYPE *newvs; + + if ((newsize = data->stacksize) == 0) + newsize = YYINITSTACKSIZE; + else if (newsize >= YYMAXDEPTH) + return -1; + else if ((newsize *= 2) > YYMAXDEPTH) + newsize = YYMAXDEPTH; + + i = (int) (data->s_mark - data->s_base); + newss = (short *)realloc(data->s_base, newsize * sizeof(*newss)); + if (newss == 0) + return -1; + + data->s_base = newss; + data->s_mark = newss + i; + + newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs)); + if (newvs == 0) + return -1; + + data->l_base = newvs; + data->l_mark = newvs + i; + + data->stacksize = newsize; + data->s_last = data->s_base + newsize - 1; + return 0; +} + +#if YYPURE || defined(YY_NO_LEAKS) +static void yyfreestack(YYSTACKDATA *data) +{ + free(data->s_base); + free(data->l_base); + memset(data, 0, sizeof(*data)); +} +#else +#define yyfreestack(data) /* nothing */ +#endif + +#define YYABORT goto yyabort +#define YYREJECT goto yyabort +#define YYACCEPT goto yyaccept +#define YYERROR goto yyerrlab + +int +YYPARSE_DECL() +{ + int yym, yyn, yystate; +#if YYDEBUG + const char *yys; + + if ((yys = getenv("YYDEBUG")) != 0) + { + yyn = *yys; + if (yyn >= '0' && yyn <= '9') + yydebug = yyn - '0'; + } +#endif + + yynerrs = 0; + yyerrflag = 0; + yychar = YYEMPTY; + yystate = 0; + +#if YYPURE + memset(&yystack, 0, sizeof(yystack)); +#endif + + if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow; + yystack.s_mark = yystack.s_base; + yystack.l_mark = yystack.l_base; + yystate = 0; + *yystack.s_mark = 0; + +yyloop: + if ((yyn = yydefred[yystate]) != 0) goto yyreduce; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + } + if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, shifting to state %d\n", + YYPREFIX, yystate, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + yychar = YYEMPTY; + if (yyerrflag > 0) --yyerrflag; + goto yyloop; + } + if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yychar) + { + yyn = yytable[yyn]; + goto yyreduce; + } + if (yyerrflag) goto yyinrecovery; + + yyerror("syntax error"); + + goto yyerrlab; + +yyerrlab: + ++yynerrs; + +yyinrecovery: + if (yyerrflag < 3) + { + yyerrflag = 3; + for (;;) + { + if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, error recovery shifting\ + to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + yystate = yytable[yyn]; + *++yystack.s_mark = yytable[yyn]; + *++yystack.l_mark = yylval; + goto yyloop; + } + else + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: error recovery discarding state %d\n", + YYPREFIX, *yystack.s_mark); +#endif + if (yystack.s_mark <= yystack.s_base) goto yyabort; + --yystack.s_mark; + --yystack.l_mark; + } + } + } + else + { + if (yychar == 0) goto yyabort; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, error recovery discards token %d (%s)\n", + YYPREFIX, yystate, yychar, yys); + } +#endif + yychar = YYEMPTY; + goto yyloop; + } + +yyreduce: +#if YYDEBUG + if (yydebug) + printf("%sdebug: state %d, reducing by rule %d (%s)\n", + YYPREFIX, yystate, yyn, yyrule[yyn]); +#endif + yym = yylen[yyn]; + if (yym) + yyval = yystack.l_mark[1-yym]; + else + memset(&yyval, 0, sizeof yyval); + switch (yyn) + { +case 3: +#line 35 "quote_calc4.y" + { yyerrok ; } +break; +case 4: +#line 39 "quote_calc4.y" + { printf("%d\n",yystack.l_mark[0]);} +break; +case 5: +#line 41 "quote_calc4.y" + { regs[yystack.l_mark[-2]] = yystack.l_mark[0]; } +break; +case 6: +#line 45 "quote_calc4.y" + { yyval = yystack.l_mark[-1]; } +break; +case 7: +#line 47 "quote_calc4.y" + { yyval = yystack.l_mark[-2] + yystack.l_mark[0]; } +break; +case 8: +#line 49 "quote_calc4.y" + { yyval = yystack.l_mark[-2] - yystack.l_mark[0]; } +break; +case 9: +#line 51 "quote_calc4.y" + { yyval = yystack.l_mark[-2] * yystack.l_mark[0]; } +break; +case 10: +#line 53 "quote_calc4.y" + { yyval = yystack.l_mark[-2] / yystack.l_mark[0]; } +break; +case 11: +#line 55 "quote_calc4.y" + { yyval = yystack.l_mark[-2] % yystack.l_mark[0]; } +break; +case 12: +#line 57 "quote_calc4.y" + { yyval = yystack.l_mark[-2] & yystack.l_mark[0]; } +break; +case 13: +#line 59 "quote_calc4.y" + { yyval = yystack.l_mark[-2] | yystack.l_mark[0]; } +break; +case 14: +#line 61 "quote_calc4.y" + { yyval = - yystack.l_mark[0]; } +break; +case 15: +#line 63 "quote_calc4.y" + { yyval = regs[yystack.l_mark[0]]; } +break; +case 17: +#line 68 "quote_calc4.y" + { yyval = yystack.l_mark[0]; base = (yystack.l_mark[0]==0) ? 8 : 10; } +break; +case 18: +#line 70 "quote_calc4.y" + { yyval = base * yystack.l_mark[-1] + yystack.l_mark[0]; } +break; +#line 544 "/dev/stdout" + } + yystack.s_mark -= yym; + yystate = *yystack.s_mark; + yystack.l_mark -= yym; + yym = yylhs[yyn]; + if (yystate == 0 && yym == 0) + { +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state 0 to\ + state %d\n", YYPREFIX, YYFINAL); +#endif + yystate = YYFINAL; + *++yystack.s_mark = YYFINAL; + *++yystack.l_mark = yyval; + if (yychar < 0) + { + if ((yychar = YYLEX) < 0) yychar = 0; +#if YYDEBUG + if (yydebug) + { + yys = yyname[YYTRANSLATE(yychar)]; + printf("%sdebug: state %d, reading %d (%s)\n", + YYPREFIX, YYFINAL, yychar, yys); + } +#endif + } + if (yychar == 0) goto yyaccept; + goto yyloop; + } + if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 && + yyn <= YYTABLESIZE && yycheck[yyn] == yystate) + yystate = yytable[yyn]; + else + yystate = yydgoto[yym]; +#if YYDEBUG + if (yydebug) + printf("%sdebug: after reduction, shifting from state %d \ +to state %d\n", YYPREFIX, *yystack.s_mark, yystate); +#endif + if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack)) + { + goto yyoverflow; + } + *++yystack.s_mark = (short) yystate; + *++yystack.l_mark = yyval; + goto yyloop; + +yyoverflow: + yyerror("yacc stack overflow"); + +yyabort: + yyfreestack(&yystack); + return (1); + +yyaccept: + yyfreestack(&yystack); + return (0); +} diff --git a/usr.bin/yacc/tests/regress.sh b/usr.bin/yacc/tests/regress.sh new file mode 100644 index 0000000..fb3b5a5 --- /dev/null +++ b/usr.bin/yacc/tests/regress.sh @@ -0,0 +1,28 @@ +# $FreeBSD$ + +echo 1..15 + +test_yacc() { + yacc "${@}" | sed -e "s,${SRCDIR}/,,g" +} + +REGRESSION_START($1) + +REGRESSION_TEST(`00', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/undefined.y') +REGRESSION_TEST(`01', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/calc.y') +REGRESSION_TEST(`02', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/calc1.y') +REGRESSION_TEST(`03', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/calc3.y') +REGRESSION_TEST(`04', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/code_calc.y') +REGRESSION_TEST(`05', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/code_error.y') +REGRESSION_TEST(`06', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/error.y') +REGRESSION_TEST(`07', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/ftp.y') +REGRESSION_TEST(`08', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/grammar.y') +REGRESSION_TEST(`09', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/pure_calc.y') +REGRESSION_TEST(`10', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/pure_error.y') +REGRESSION_TEST(`11', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/quote_calc.y') +REGRESSION_TEST(`12', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/quote_calc2.y') +REGRESSION_TEST(`13', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/quote_calc3.y') +REGRESSION_TEST(`14', `test_yacc -b regress -o /dev/stdout ${SRCDIR}/quote_calc4.y') + +REGRESSION_END() + diff --git a/usr.bin/yacc/tests/undefined.y b/usr.bin/yacc/tests/undefined.y new file mode 100644 index 0000000..33ba005 --- /dev/null +++ b/usr.bin/yacc/tests/undefined.y @@ -0,0 +1,5 @@ +%type <int> rule +%% +rule: + ; +%% |