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