1234949Sbapt%pure-parser 2234949Sbapt 3234949Sbapt%parse-param { int regs[26] } 4234949Sbapt%parse-param { int *base } 5234949Sbapt 6234949Sbapt%lex-param { int *base } 7234949Sbapt 8234949Sbapt%{ 9234949Sbapt# include <stdio.h> 10234949Sbapt# include <ctype.h> 11234949Sbapt 12234949Sbapt#ifdef YYBISON 13234949Sbapt#define YYSTYPE int 14234949Sbapt#define YYLEX_PARAM base 15234949Sbapt#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM) 16234949Sbapt#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s) 17234949Sbaptint YYLEX_DECL(); 18234949Sbaptstatic void YYERROR_DECL(); 19234949Sbapt#endif 20234949Sbapt 21234949Sbapt%} 22234949Sbapt 23234949Sbapt%start list 24234949Sbapt 25234949Sbapt%token DIGIT LETTER 26234949Sbapt 27234949Sbapt%left '|' 28234949Sbapt%left '&' 29234949Sbapt%left '+' '-' 30234949Sbapt%left '*' '/' '%' 31234949Sbapt%left UMINUS /* supplies precedence for unary minus */ 32234949Sbapt 33234949Sbapt%% /* beginning of rules section */ 34234949Sbapt 35234949Sbaptlist : /* empty */ 36234949Sbapt | list stat '\n' 37234949Sbapt | list error '\n' 38234949Sbapt { yyerrok ; } 39234949Sbapt ; 40234949Sbapt 41234949Sbaptstat : expr 42234949Sbapt { printf("%d\n",$1);} 43234949Sbapt | LETTER '=' expr 44234949Sbapt { regs[$1] = $3; } 45234949Sbapt ; 46234949Sbapt 47234949Sbaptexpr : '(' expr ')' 48234949Sbapt { $$ = $2; } 49234949Sbapt | expr '+' expr 50234949Sbapt { $$ = $1 + $3; } 51234949Sbapt | expr '-' expr 52234949Sbapt { $$ = $1 - $3; } 53234949Sbapt | expr '*' expr 54234949Sbapt { $$ = $1 * $3; } 55234949Sbapt | expr '/' expr 56234949Sbapt { $$ = $1 / $3; } 57234949Sbapt | expr '%' expr 58234949Sbapt { $$ = $1 % $3; } 59234949Sbapt | expr '&' expr 60234949Sbapt { $$ = $1 & $3; } 61234949Sbapt | expr '|' expr 62234949Sbapt { $$ = $1 | $3; } 63234949Sbapt | '-' expr %prec UMINUS 64234949Sbapt { $$ = - $2; } 65234949Sbapt | LETTER 66234949Sbapt { $$ = regs[$1]; } 67234949Sbapt | number 68234949Sbapt ; 69234949Sbapt 70234949Sbaptnumber: DIGIT 71234949Sbapt { $$ = $1; (*base) = ($1==0) ? 8 : 10; } 72234949Sbapt | number DIGIT 73234949Sbapt { $$ = (*base) * $1 + $2; } 74234949Sbapt ; 75234949Sbapt 76234949Sbapt%% /* start of programs */ 77234949Sbapt 78234949Sbapt#ifdef YYBYACC 79234949Sbaptextern int YYLEX_DECL(); 80234949Sbapt#endif 81234949Sbapt 82234949Sbaptint 83234949Sbaptmain (void) 84234949Sbapt{ 85234949Sbapt int regs[26]; 86234949Sbapt int base = 10; 87234949Sbapt 88234949Sbapt while(!feof(stdin)) { 89234949Sbapt yyparse(regs, &base); 90234949Sbapt } 91234949Sbapt return 0; 92234949Sbapt} 93234949Sbapt 94264803Sbapt#define UNUSED(x) ((void)(x)) 95264803Sbapt 96234949Sbaptstatic void 97234949SbaptYYERROR_DECL() 98234949Sbapt{ 99264803Sbapt UNUSED(regs); /* %parse-param regs is not actually used here */ 100264803Sbapt UNUSED(base); /* %parse-param base is not actually used here */ 101234949Sbapt fprintf(stderr, "%s\n", s); 102234949Sbapt} 103234949Sbapt 104234949Sbaptint 105234949SbaptYYLEX_DECL() 106234949Sbapt{ 107234949Sbapt /* lexical analysis routine */ 108234949Sbapt /* returns LETTER for a lower case letter, yylval = 0 through 25 */ 109234949Sbapt /* return DIGIT for a digit, yylval = 0 through 9 */ 110234949Sbapt /* all other characters are returned immediately */ 111234949Sbapt 112234949Sbapt int c; 113234949Sbapt 114234949Sbapt while( (c=getchar()) == ' ' ) { /* skip blanks */ } 115234949Sbapt 116234949Sbapt /* c is now nonblank */ 117234949Sbapt 118234949Sbapt if( islower( c )) { 119234949Sbapt *yylval = (c - 'a'); 120234949Sbapt return ( LETTER ); 121234949Sbapt } 122234949Sbapt if( isdigit( c )) { 123234949Sbapt *yylval = (c - '0') % (*base); 124234949Sbapt return ( DIGIT ); 125234949Sbapt } 126234949Sbapt return( c ); 127234949Sbapt} 128