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