1264790Sbapt%pure-parser 2264790Sbapt 3264790Sbapt%parse-param { int regs[26] 4264790Sbapt%parse-param { int *base 5264790Sbapt 6264790Sbapt%lex-param { int *base 7264790Sbapt 8264790Sbapt%{ 9264790Sbapt# include <stdio.h> 10264790Sbapt# include <ctype.h> 11264790Sbapt 12264790Sbapt#ifdef YYBISON 13264790Sbapt#define YYSTYPE int 14264790Sbapt#define YYLEX_PARAM base 15264790Sbapt#define YYLEX_DECL() yylex(YYSTYPE *yylval, int *YYLEX_PARAM) 16264790Sbapt#define YYERROR_DECL() yyerror(int regs[26], int *base, const char *s) 17264790Sbaptint YYLEX_DECL(); 18264790Sbaptstatic void YYERROR_DECL(); 19264790Sbapt#endif 20264790Sbapt 21264790Sbapt%} 22264790Sbapt 23264790Sbapt%start list 24264790Sbapt 25264790Sbapt%token DIGIT LETTER 26264790Sbapt 27264790Sbapt%left '|' 28264790Sbapt%left '&' 29264790Sbapt%left '+' '-' 30264790Sbapt%left '*' '/' '%' 31264790Sbapt%left UMINUS /* supplies precedence for unary minus */ 32264790Sbapt 33264790Sbapt%% /* beginning of rules section */ 34264790Sbapt 35264790Sbaptlist : /* empty */ 36264790Sbapt | list stat '\n' 37264790Sbapt | list error '\n' 38264790Sbapt { yyerrok ; } 39264790Sbapt ; 40264790Sbapt 41264790Sbaptstat : expr 42264790Sbapt { printf("%d\n",$1);} 43264790Sbapt | LETTER '=' expr 44264790Sbapt { regs[$1] = $3; } 45264790Sbapt ; 46264790Sbapt 47264790Sbaptexpr : '(' expr ')' 48264790Sbapt { $$ = $2; } 49264790Sbapt | expr '+' expr 50264790Sbapt { $$ = $1 + $3; } 51264790Sbapt | expr '-' expr 52264790Sbapt { $$ = $1 - $3; } 53264790Sbapt | expr '*' expr 54264790Sbapt { $$ = $1 * $3; } 55264790Sbapt | expr '/' expr 56264790Sbapt { $$ = $1 / $3; } 57264790Sbapt | expr '%' expr 58264790Sbapt { $$ = $1 % $3; } 59264790Sbapt | expr '&' expr 60264790Sbapt { $$ = $1 & $3; } 61264790Sbapt | expr '|' expr 62264790Sbapt { $$ = $1 | $3; } 63264790Sbapt | '-' expr %prec UMINUS 64264790Sbapt { $$ = - $2; } 65264790Sbapt | LETTER 66264790Sbapt { $$ = regs[$1]; } 67264790Sbapt | number 68264790Sbapt ; 69264790Sbapt 70264790Sbaptnumber: DIGIT 71264790Sbapt { $$ = $1; (*base) = ($1==0) ? 8 : 10; } 72264790Sbapt | number DIGIT 73264790Sbapt { $$ = (*base) * $1 + $2; } 74264790Sbapt ; 75264790Sbapt 76264790Sbapt%% /* start of programs */ 77264790Sbapt 78264790Sbapt#ifdef YYBYACC 79264790Sbaptextern int YYLEX_DECL(); 80264790Sbapt#endif 81264790Sbapt 82264790Sbaptint 83264790Sbaptmain (void) 84264790Sbapt{ 85264790Sbapt int regs[26]; 86264790Sbapt int base = 10; 87264790Sbapt 88264790Sbapt while(!feof(stdin)) { 89264790Sbapt yyparse(regs, &base); 90264790Sbapt } 91264790Sbapt return 0; 92264790Sbapt} 93264790Sbapt 94264790Sbapt#define UNUSED(x) ((void)(x)) 95264790Sbapt 96264790Sbaptstatic void 97264790SbaptYYERROR_DECL() 98264790Sbapt{ 99264790Sbapt UNUSED(regs); /* %parse-param regs is not actually used here */ 100264790Sbapt UNUSED(base); /* %parse-param base is not actually used here */ 101264790Sbapt fprintf(stderr, "%s\n", s); 102264790Sbapt} 103264790Sbapt 104264790Sbaptint 105264790SbaptYYLEX_DECL() 106264790Sbapt{ 107264790Sbapt /* lexical analysis routine */ 108264790Sbapt /* returns LETTER for a lower case letter, yylval = 0 through 25 */ 109264790Sbapt /* return DIGIT for a digit, yylval = 0 through 9 */ 110264790Sbapt /* all other characters are returned immediately */ 111264790Sbapt 112264790Sbapt int c; 113264790Sbapt 114264790Sbapt while( (c=getchar()) == ' ' ) { /* skip blanks */ } 115264790Sbapt 116264790Sbapt /* c is now nonblank */ 117264790Sbapt 118264790Sbapt if( islower( c )) { 119264790Sbapt *yylval = (c - 'a'); 120264790Sbapt return ( LETTER ); 121264790Sbapt } 122264790Sbapt if( isdigit( c )) { 123264790Sbapt *yylval = (c - '0') % (*base); 124264790Sbapt return ( DIGIT ); 125264790Sbapt } 126264790Sbapt return( c ); 127264790Sbapt} 128