1 %token ARITH_OR ARITH_AND ARITH_ADD ARITH_SUBT ARITH_MULT ARITH_DIV ARITH_REM ARITH_EQ ARITH_GT ARITH_GEQ ARITH_LT ARITH_LEQ ARITH_NEQ 2 %token ARITH_NUM ARITH_LPAREN ARITH_RPAREN ARITH_NOT ARITH_UNARYMINUS 3 4 %left ARITH_OR 5 %left ARITH_AND 6 %left ARITH_EQ ARITH_NEQ 7 %left ARITH_LT ARITH_GT ARITH_GEQ ARITH_LEQ 8 %left ARITH_ADD ARITH_SUBT 9 %left ARITH_MULT ARITH_DIV ARITH_REM 10 %left ARITH_UNARYMINUS ARITH_NOT 11 %% 12 13 exp: expr = { 14 return ($1); 15 } 16 ; 17 18 19 expr: ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; } 20 | expr ARITH_OR expr = { $$ = $1 ? $1 : $3 ? $3 : 0; } 21 | expr ARITH_AND expr = { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } 22 | expr ARITH_EQ expr = { $$ = $1 == $3; } 23 | expr ARITH_GT expr = { $$ = $1 > $3; } 24 | expr ARITH_GEQ expr = { $$ = $1 >= $3; } 25 | expr ARITH_LT expr = { $$ = $1 < $3; } 26 | expr ARITH_LEQ expr = { $$ = $1 <= $3; } 27 | expr ARITH_NEQ expr = { $$ = $1 != $3; } 28 | expr ARITH_ADD expr = { $$ = $1 + $3; } 29 | expr ARITH_SUBT expr = { $$ = $1 - $3; } 30 | expr ARITH_MULT expr = { $$ = $1 * $3; } 31 | expr ARITH_DIV expr = { 32 if ($3 == 0) 33 yyerror("division by zero"); 34 $$ = $1 / $3; 35 } 36 | expr ARITH_REM expr = { $$ = $1 % $3; } 37 | ARITH_NOT expr = { $$ = !($2); } 38 | ARITH_UNARYMINUS expr = { $$ = -($2); } 39 | ARITH_NUM 40 ; 41 %% 42 /*- 43 * Copyright (c) 1993 44 * The Regents of the University of California. All rights reserved. 45 * 46 * This code is derived from software contributed to Berkeley by 47 * Kenneth Almquist. 48 * 49 * %sccs.include.redist.c% 50 */ 51 52 #ifndef lint 53 static char sccsid[] = "@(#)arith.y 8.1 (Berkeley) 05/31/93"; 54 #endif /* not lint */ 55 56 #include "shell.h" 57 #include "error.h" 58 #include "output.h" 59 #include "memalloc.h" 60 61 char *arith_buf, *arith_startbuf; 62 63 arith(s) 64 char *s; 65 { 66 extern arith_wasoper; 67 long result; 68 69 arith_wasoper = 1; 70 arith_buf = arith_startbuf = s; 71 72 INTOFF; 73 result = yyparse(); 74 arith_lex_reset(); /* reprime lex */ 75 INTON; 76 77 return (result); 78 } 79 80 yyerror(s) 81 char *s; 82 { 83 extern yytext, yylval; 84 85 yyerrok; 86 yyclearin; 87 arith_lex_reset(); /* reprime lex */ 88 error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); 89 } 90 91 /* 92 * The exp(1) builtin. 93 */ 94 expcmd(argc, argv) 95 char **argv; 96 { 97 char *p; 98 char *concat; 99 char **ap; 100 long i; 101 102 if (argc > 1) { 103 p = argv[1]; 104 if (argc > 2) { 105 /* 106 * concatenate arguments 107 */ 108 STARTSTACKSTR(concat); 109 ap = argv + 2; 110 for (;;) { 111 while (*p) 112 STPUTC(*p++, concat); 113 if ((p = *ap++) == NULL) 114 break; 115 STPUTC(' ', concat); 116 } 117 STPUTC('\0', concat); 118 p = grabstackstr(concat); 119 } 120 } else 121 p = ""; 122 123 i = arith(p); 124 125 out1fmt("%d\n", i); 126 return (! i); 127 } 128 129 /*************************/ 130 #ifdef TEST_ARITH 131 #include <stdio.h> 132 main(argc, argv) 133 char *argv[]; 134 { 135 printf("%d\n", exp(argv[1])); 136 } 137 error(s) 138 char *s; 139 { 140 fprintf(stderr, "exp: %s\n", s); 141 exit(1); 142 } 143 #endif 144