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