1235723Sbapt%pure-parser 2235723Sbapt 3235723Sbapt%parse-param { int regs[26] } 4235723Sbapt%parse-param { int *base } 5235723Sbapt 6235723Sbapt%lex-param { int *base } 7235723Sbapt 8235723Sbapt%{ 9235723Sbapt# include <stdio.h> 10235723Sbapt# include <ctype.h> 11235723Sbapt 12235723Sbapt#ifdef YYBISON 13235723Sbapt#define YYSTYPE int 14235723Sbapt#define YYLEX_PARAM base 15235723Sbapt#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM) 16235723Sbapt#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s) 17235723Sbaptint YYLEX_DECL(); 18235723Sbaptstatic void YYERROR_DECL(); 19235723Sbapt#endif 20235723Sbapt 21235723Sbapt%} 22235723Sbapt 23235723Sbapt%start list 24235723Sbapt 25235723Sbapt%token DIGIT LETTER 26235723Sbapt 27235723Sbapt%left '|' 28235723Sbapt%left '&' 29235723Sbapt%left '+' '-' 30235723Sbapt%left '*' '/' '%' 31235723Sbapt%left UMINUS /* supplies precedence for unary minus */ 32235723Sbapt 33235723Sbapt%% /* beginning of rules section */ 34235723Sbapt 35235723Sbaptlist : /* empty */ 36235723Sbapt | list stat '\n' 37235723Sbapt | list error '\n' 38235723Sbapt { yyerrok ; } 39235723Sbapt ; 40235723Sbapt 41235723Sbaptstat : expr 42235723Sbapt { printf("%d\n",$1);} 43235723Sbapt | LETTER '=' expr 44235723Sbapt { regs[$1] = $3; } 45235723Sbapt ; 46235723Sbapt 47235723Sbaptexpr : '(' expr ')' 48235723Sbapt { $$ = $2; } 49235723Sbapt | expr '+' expr 50235723Sbapt { $$ = $1 + $3; } 51235723Sbapt | expr '-' expr 52235723Sbapt { $$ = $1 - $3; } 53235723Sbapt | expr '*' expr 54235723Sbapt { $$ = $1 * $3; } 55235723Sbapt | expr '/' expr 56235723Sbapt { $$ = $1 / $3; } 57235723Sbapt | expr '%' expr 58235723Sbapt { $$ = $1 % $3; } 59235723Sbapt | expr '&' expr 60235723Sbapt { $$ = $1 & $3; } 61235723Sbapt | expr '|' expr 62235723Sbapt { $$ = $1 | $3; } 63235723Sbapt | '-' expr %prec UMINUS 64235723Sbapt { $$ = - $2; } 65235723Sbapt | LETTER 66235723Sbapt { $$ = regs[$1]; } 67235723Sbapt | number 68235723Sbapt ; 69235723Sbapt 70235723Sbaptnumber: DIGIT 71235723Sbapt { $$ = $1; (*base) = ($1==0) ? 8 : 10; } 72235723Sbapt | number DIGIT 73235723Sbapt { $$ = (*base) * $1 + $2; } 74235723Sbapt ; 75235723Sbapt 76235723Sbapt%% /* start of programs */ 77235723Sbapt 78235723Sbapt#ifdef YYBYACC 79235723Sbaptextern int YYLEX_DECL(); 80235723Sbapt#endif 81235723Sbapt 82235723Sbaptint 83235723Sbaptmain (void) 84235723Sbapt{ 85235723Sbapt int regs[26]; 86235723Sbapt int base = 10; 87235723Sbapt 88235723Sbapt while(!feof(stdin)) { 89235723Sbapt yyparse(regs, &base); 90235723Sbapt } 91235723Sbapt return 0; 92235723Sbapt} 93235723Sbapt 94235723Sbaptstatic void 95235723SbaptYYERROR_DECL() 96235723Sbapt{ 97235723Sbapt fprintf(stderr, "%s\n", s); 98235723Sbapt} 99235723Sbapt 100235723Sbaptint 101235723SbaptYYLEX_DECL() 102235723Sbapt{ 103235723Sbapt /* lexical analysis routine */ 104235723Sbapt /* returns LETTER for a lower case letter, yylval = 0 through 25 */ 105235723Sbapt /* return DIGIT for a digit, yylval = 0 through 9 */ 106235723Sbapt /* all other characters are returned immediately */ 107235723Sbapt 108235723Sbapt int c; 109235723Sbapt 110235723Sbapt while( (c=getchar()) == ' ' ) { /* skip blanks */ } 111235723Sbapt 112235723Sbapt /* c is now nonblank */ 113235723Sbapt 114235723Sbapt if( islower( c )) { 115235723Sbapt *yylval = (c - 'a'); 116235723Sbapt return ( LETTER ); 117235723Sbapt } 118235723Sbapt if( isdigit( c )) { 119235723Sbapt *yylval = (c - '0') % (*base); 120235723Sbapt return ( DIGIT ); 121235723Sbapt } 122235723Sbapt return( c ); 123235723Sbapt} 124