1 /* $NetBSD: code_calc.y,v 1.1.1.3 2011/09/10 21:22:04 christos Exp $ */ 2 3 %{ 4 # include <stdio.h> 5 # include <ctype.h> 6 7 int regs[26]; 8 int base; 9 10 %} 11 12 %start list 13 14 %token DIGIT LETTER 15 16 %left '|' 17 %left '&' 18 %left '+' '-' 19 %left '*' '/' '%' 20 %left UMINUS /* supplies precedence for unary minus */ 21 22 %% /* beginning of rules section */ 23 24 list : /* empty */ 25 | list stat '\n' 26 | list error '\n' 27 { yyerrok ; } 28 ; 29 30 stat : expr 31 { printf("%d\n",$1);} 32 | LETTER '=' expr 33 { regs[$1] = $3; } 34 ; 35 36 expr : '(' expr ')' 37 { $$ = $2; } 38 | expr '+' expr 39 { $$ = $1 + $3; } 40 | expr '-' expr 41 { $$ = $1 - $3; } 42 | expr '*' expr 43 { $$ = $1 * $3; } 44 | expr '/' expr 45 { $$ = $1 / $3; } 46 | expr '%' expr 47 { $$ = $1 % $3; } 48 | expr '&' expr 49 { $$ = $1 & $3; } 50 | expr '|' expr 51 { $$ = $1 | $3; } 52 | '-' expr %prec UMINUS 53 { $$ = - $2; } 54 | LETTER 55 { $$ = regs[$1]; } 56 | number 57 ; 58 59 number: DIGIT 60 { $$ = $1; base = ($1==0) ? 8 : 10; } 61 | number DIGIT 62 { $$ = base * $1 + $2; } 63 ; 64 65 %% /* start of programs */ 66 67 #ifdef YYBYACC 68 extern int YYLEX_DECL(); 69 static void YYERROR_DECL(); 70 #endif 71 72 int 73 main (void) 74 { 75 while(!feof(stdin)) { 76 yyparse(); 77 } 78 return 0; 79 } 80 81 static void 82 yyerror(const char *s) 83 { 84 fprintf(stderr, "%s\n", s); 85 } 86 87 int 88 yylex(void) { 89 /* lexical analysis routine */ 90 /* returns LETTER for a lower case letter, yylval = 0 through 25 */ 91 /* return DIGIT for a digit, yylval = 0 through 9 */ 92 /* all other characters are returned immediately */ 93 94 int c; 95 96 while( (c=getchar()) == ' ' ) { /* skip blanks */ } 97 98 /* c is now nonblank */ 99 100 if( islower( c )) { 101 yylval = c - 'a'; 102 return ( LETTER ); 103 } 104 if( isdigit( c )) { 105 yylval = c - '0'; 106 return ( DIGIT ); 107 } 108 return( c ); 109 } 110