1 /* @(#)m4y.y 1.2 (Berkeley) 07/22/88 */ 2 %{ 3 extern long evalval; 4 #define YYSTYPE long 5 %} 6 7 %term DIGITS 8 %left '|' 9 %left '&' 10 %right '!' 11 %nonassoc GT GE LT LE NE EQ 12 %left '+' '-' 13 %left '*' '/' '%' 14 %right POWER 15 %right UMINUS 16 %% 17 18 s : e ={ evalval = $1; } 19 | ={ evalval = 0; } 20 ; 21 22 e : e '|' e ={ $$ = ($1!=0 || $3!=0) ? 1 : 0; } 23 | e '&' e ={ $$ = ($1!=0 && $3!=0) ? 1 : 0; } 24 | '!' e ={ $$ = $2 == 0; } 25 | e EQ e ={ $$ = $1 == $3; } 26 | e NE e ={ $$ = $1 != $3; } 27 | e GT e ={ $$ = $1 > $3; } 28 | e GE e ={ $$ = $1 >= $3; } 29 | e LT e ={ $$ = $1 < $3; } 30 | e LE e ={ $$ = $1 <= $3; } 31 | e '+' e ={ $$ = ($1+$3); } 32 | e '-' e ={ $$ = ($1-$3); } 33 | e '*' e ={ $$ = ($1*$3); } 34 | e '/' e ={ $$ = ($1/$3); } 35 | e '%' e ={ $$ = ($1%$3); } 36 | '(' e ')' ={ $$ = ($2); } 37 | e POWER e ={ for ($$=1; $3-->0; $$ *= $1); } 38 | '-' e %prec UMINUS ={ $$ = $2-1; $$ = -$2; } 39 | '+' e %prec UMINUS ={ $$ = $2-1; $$ = $2; } 40 | DIGITS ={ $$ = evalval; } 41 ; 42 43 %% 44 45 extern char *pe; 46 yylex() { 47 48 while (*pe==' ' || *pe=='\t' || *pe=='\n') 49 pe++; 50 switch(*pe) { 51 case '\0': 52 case '+': 53 case '-': 54 case '/': 55 case '%': 56 case '(': 57 case ')': 58 return(*pe++); 59 case '^': 60 pe++; 61 return(POWER); 62 case '*': 63 return(peek('*', POWER, '*')); 64 case '>': 65 return(peek('=', GE, GT)); 66 case '<': 67 return(peek('=', LE, LT)); 68 case '=': 69 return(peek('=', EQ, EQ)); 70 case '|': 71 return(peek('|', '|', '|')); 72 case '&': 73 return(peek('&', '&', '&')); 74 case '!': 75 return(peek('=', NE, '!')); 76 default: 77 evalval = 0; 78 while (*pe >= '0' && *pe <= '9') 79 evalval = evalval*10 + *pe++ - '0'; 80 return(DIGITS); 81 } 82 } 83 84 peek(c, r1, r2) 85 { 86 if (*++pe != c) 87 return(r2); 88 ++pe; 89 return(r1); 90 } 91 92 yyerror(s) 93 char *s; 94 { 95 } 96