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