1335640Shselasky%{ 2335640Shselasky# include <stdio.h> 3335640Shselasky# include <ctype.h> 4335640Shselasky 5335640Shselaskyint regs[26]; 6335640Shselaskyint base; 7335640Shselasky 8335640Shselaskyint yylex(void); 9335640Shselaskystatic void yyerror(const char *s); 10335640Shselasky 11335640Shselasky%} 12335640Shselasky 13335640Shselasky%start list 14335640Shselasky 15335640Shselasky%token OP_ADD "ADD" 16335640Shselasky%token OP_SUB "SUB" 17335640Shselasky%token OP_MUL "MUL" 18335640Shselasky%token OP_DIV "DIV" 19335640Shselasky%token OP_MOD "MOD" 20356341Scy%token OP_AND "AND" 21335640Shselasky 22335640Shselasky%token DIGIT LETTER 23335640Shselasky 24335640Shselasky%left '|' 25335640Shselasky%left '&' 26335640Shselasky%left '+' '-' 27335640Shselasky%left '*' '/' '%' 28335640Shselasky%left UMINUS /* supplies precedence for unary minus */ 29335640Shselasky 30335640Shselasky%% /* beginning of rules section */ 31335640Shselasky 32335640Shselaskylist : /* empty */ 33335640Shselasky | list stat '\n' 34335640Shselasky | list error '\n' 35335640Shselasky { yyerrok ; } 36335640Shselasky ; 37335640Shselasky 38335640Shselaskystat : expr 39335640Shselasky { printf("%d\n",$1);} 40335640Shselasky | LETTER '=' expr 41335640Shselasky { regs[$1] = $3; } 42335640Shselasky ; 43335640Shselasky 44335640Shselaskyexpr : '(' expr ')' 45335640Shselasky { $$ = $2; } 46335640Shselasky | expr "ADD" expr 47335640Shselasky { $$ = $1 + $3; } 48335640Shselasky | expr "SUB" expr 49335640Shselasky { $$ = $1 - $3; } 50335640Shselasky | expr "MUL" expr 51335640Shselasky { $$ = $1 * $3; } 52335640Shselasky | expr "DIV" expr 53335640Shselasky { $$ = $1 / $3; } 54335640Shselasky | expr "MOD" expr 55335640Shselasky { $$ = $1 % $3; } 56335640Shselasky | expr "AND" expr 57335640Shselasky { $$ = $1 & $3; } 58335640Shselasky | expr '|' expr 59335640Shselasky { $$ = $1 | $3; } 60356341Scy | "SUB" expr %prec UMINUS 61356341Scy { $$ = - $2; } 62356341Scy | LETTER 63356341Scy { $$ = regs[$1]; } 64356341Scy | number 65356341Scy ; 66335640Shselasky 67356341Scynumber: DIGIT 68335640Shselasky { $$ = $1; base = ($1==0) ? 8 : 10; } 69335640Shselasky | number DIGIT 70335640Shselasky { $$ = base * $1 + $2; } 71335640Shselasky ; 72356341Scy 73%% /* start of programs */ 74 75int 76main (void) 77{ 78 while(!feof(stdin)) { 79 yyparse(); 80 } 81 return 0; 82} 83 84static void 85yyerror(const char *s) 86{ 87 fprintf(stderr, "%s\n", s); 88} 89 90int 91yylex(void) { 92 /* lexical analysis routine */ 93 /* returns LETTER for a lower case letter, yylval = 0 through 25 */ 94 /* return DIGIT for a digit, yylval = 0 through 9 */ 95 /* all other characters are returned immediately */ 96 97 int c; 98 99 while( (c=getchar()) == ' ' ) { /* skip blanks */ } 100 101 /* c is now nonblank */ 102 103 if( islower( c )) { 104 yylval = c - 'a'; 105 return ( LETTER ); 106 } 107 if( isdigit( c )) { 108 yylval = c - '0'; 109 return ( DIGIT ); 110 } 111 return( c ); 112} 113