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 %token OCT1 '\177' 28 %token HEX1 '\xff' 29 %token HEX2 '\xFF' 30 %token HEX3 '\x7f' 31 %token STR1 "\x7f\177\\\n" 32 %token STR2 "\x7f\ 33 \177\\\n" 34 35 %token BELL '\a' 36 %token BS '\b' 37 %token NL '\n' 38 %token LF '\f' 39 %token CR '\r' 40 %token TAB '\t' 41 %token VT '\v' 42 43 %union CalcData 44 { 45 char * cval; 46 int ival; 47 double dval; 48 } 49 50 %0 '@' 51 %2 '~' 52 %> '^' 53 %< '#' 54 55 %left '|' 56 %left '&' 57 %left '+' '-' 58 %left '*' '/' '%' 59 %left UMINUS /* supplies precedence for unary minus */ 60 61 %% /* beginning of rules section */ 62 63 list : /* empty */ 64 | list stat '\n' 65 | list error '\n' 66 { yyerrok ; } 67 ; 68 69 stat : expr 70 { printf("%d\n",$<ival>1);} 71 | LETTER '=' expr 72 { regs[$<ival>1] = $<ival>3; } 73 ; 74 75 expr : '(' expr ')' 76 { $<ival>$ = $<ival>2; } 77 | expr '+' expr 78 { $<ival>$ = $<ival>1 + $<ival>3; } 79 | expr '-' expr 80 { $<ival>$ = $<ival>1 - $<ival>3; } 81 | expr '*' expr 82 { $<ival>$ = $<ival>1 * $<ival>3; } 83 | expr '/' expr 84 { $<ival>$ = $<ival>1 / $<ival>3; } 85 | expr '%' expr 86 { $<ival>$ = $<ival>1 % $<ival>3; } 87 | expr '&' expr 88 { $<ival>$ = $<ival>1 & $<ival>3; } 89 | expr '|' expr 90 { $<ival>$ = $<ival>1 | $<ival>3; } 91 | '-' expr %prec UMINUS 92 { $<ival>$ = - $<ival>2; } 93 | LETTER 94 { $<ival>$ = regs[$<ival>1]; } 95 | number 96 ; 97 98 number: DIGIT 99 { $<ival>$ = $<ival>1; (*base) = ($<ival>1==0) ? 8 : 10; } 100 | number DIGIT 101 { $<ival>$ = (*base) * $<ival>1 + $<ival>2; } 102 ; 103 104 %% /* start of programs */ 105 106 #ifdef YYBYACC 107 extern int YYLEX_DECL(); 108 #endif 109 110 int 111 main (void) 112 { 113 int regs[26]; 114 int base = 10; 115 116 while(!feof(stdin)) { 117 yyparse(regs, &base); 118 } 119 return 0; 120 } 121 122 #define UNUSED(x) ((void)(x)) 123 124 static void 125 YYERROR_DECL() 126 { 127 UNUSED(regs); /* %parse-param regs is not actually used here */ 128 UNUSED(base); /* %parse-param base is not actually used here */ 129 fprintf(stderr, "%s\n", s); 130 } 131 132 int 133 YYLEX_DECL() 134 { 135 /* lexical analysis routine */ 136 /* returns LETTER for a lower case letter, yylval = 0 through 25 */ 137 /* return DIGIT for a digit, yylval = 0 through 9 */ 138 /* all other characters are returned immediately */ 139 140 int c; 141 142 while( (c=getchar()) == ' ' ) { /* skip blanks */ } 143 144 /* c is now nonblank */ 145 146 if( islower( c )) { 147 yylval->ival = (c - 'a'); 148 return ( LETTER ); 149 } 150 if( isdigit( c )) { 151 yylval->ival = (c - '0') % (*base); 152 return ( DIGIT ); 153 } 154 return( c ); 155 } 156