High-level changes:
[xuni.git] / src / calc.y
blobdbe9e57de1fbf24a208d740bb47fe818bf82a1e2
1 %{
2 #include <stdio.h> /* for printf() */
3 #include <stdlib.h> /* for strtod() */
4 #include <ctype.h>
5 #include <math.h> /* for pow() */
7 #define YYSTYPE double
9 int yylex(void);
10 void yyerror(const char *);
12 YYSTYPE yyreturn;
15 %token NUM
16 %left '-' '+'
17 %left '*' '/'
18 %left NEG /* negation: unary minus */
19 %right '^' /* exponentation */
23 line: exp { yyreturn = $1; }
26 exp: NUM { $$ = $1; }
27 | exp '+' exp { $$ = $1 + $3; }
28 | exp '-' exp { $$ = $1 - $3; }
29 | exp '*' exp { $$ = $1 * $3; }
30 | exp '/' exp { $$ = $1 / $3; }
31 | '-' exp %prec NEG { $$ = -$2; }
32 | exp '^' exp { $$ = pow($1, $3); }
33 | '(' exp ')' { $$ = $2; }
38 /*#define EXPRESSION_VERBOSE*/
40 static const char *yydata;
42 int parse_expression(const char *data, double *d) {
43 int r;
45 #ifdef EXPRESSION_VERBOSE
46 printf("%s = ", data);
47 #endif
49 if(!data) {
50 #ifdef EXPRESSION_VERBOSE
51 printf(" [NULL]\n");
52 #endif
53 return 1;
56 yydata = data;
57 r = yyparse();
59 *d = yyreturn;
60 #ifdef EXPRESSION_VERBOSE
61 printf("%f\n", yyreturn);
62 #endif
64 return r;
67 int yylex(void) {
68 char *p;
70 while(isspace(*yydata)) yydata ++;
72 if(!*yydata) return 0;
74 if(isdigit(*yydata) || *yydata == '.') {
75 yylval = strtod(yydata, &p);
76 if(p == yydata) return 0;
77 yydata = p;
79 while(isspace(*yydata)) yydata ++;
81 return NUM;
84 return *yydata++;
87 void yyerror(const char *s) {
88 fprintf(stderr, "%s: \"%s\"\n", s, yydata);