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