1 %{ 2 # include <stdio.h> 3 # include <ctype.h> 4 5 int regs[26]; 6 int base; 7 8 int yylex(void); 9 static void yyerror(const char *s); 10 11 %} 12 13 %start list 14 15 %token OP_ADD "ADD" 16 %token OP_SUB "SUB" 17 %token OP_MUL "MUL" 18 %token OP_DIV "DIV" 19 %token OP_MOD "MOD" 20 %token OP_AND "AND" 21 22 %token DIGIT LETTER 23 24 %left '|' 25 %left '&' 26 %left '+' '-' 27 %left '*' '/' '%' 28 %left UMINUS /* supplies precedence for unary minus */ 29 30 %% /* beginning of rules section */ 31 32 list : /* empty */ 33 | list stat '\n' 34 | list error '\n' 35 { yyerrok ; } 36 ; 37 38 stat : expr 39 { printf("%d\n",$1);} 40 | LETTER '=' expr 41 { regs[$1] = $3; } 42 ; 43 44 expr : '(' expr ')' 45 { $$ = $2; } 46 | expr OP_ADD expr 47 { $$ = $1 + $3; } 48 | expr OP_SUB expr 49 { $$ = $1 - $3; } 50 | expr OP_MUL expr 51 { $$ = $1 * $3; } 52 | expr OP_DIV expr 53 { $$ = $1 / $3; } 54 | expr OP_MOD expr 55 { $$ = $1 % $3; } 56 | expr OP_AND expr 57 { $$ = $1 & $3; } 58 | expr '|' expr 59 { $$ = $1 | $3; } 60 | OP_SUB expr %prec UMINUS 61 { $$ = - $2; } 62 | LETTER 63 { $$ = regs[$1]; } 64 | number 65 ; 66 67 number: DIGIT 68 { $$ = $1; base = ($1==0) ? 8 : 10; } 69 | number DIGIT 70 { $$ = base * $1 + $2; } 71 ; 72 73 %% /* start of programs */ 74 75 int 76 main (void) 77 { 78 while(!feof(stdin)) { 79 yyparse(); 80 } 81 return 0; 82 } 83 84 static void 85 yyerror(const char *s) 86 { 87 fprintf(stderr, "%s\n", s); 88 } 89 90 int 91 yylex(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