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