8 /*#define RAND_MAX 32767 /* if your rand() returns bigger, change this too */
10 extern int yylex(void);
11 extern int yyparse(void);
15 %token <i> FRAME TICKS GRID LABEL COORD
16 %token <i> LINE ARROW CIRCLE DRAW NEW PLOT NEXT
18 %token <i> COPY THRU UNTIL
19 %token <i> FOR FROM TO BY AT WITH
21 %token <p> GRAPH THEN ELSE DOSTR
22 %token <i> DOT DASH INVIS SOLID
23 %token <i> TEXT JUST SIZE
24 %token <i> LOG EXP SIN COS ATAN2 SQRT RAND MAX MIN INT PRINT SPRINTF
25 %token <i> X Y SIDE IN OUT OFF UP DOWN ACROSS
26 %token <i> HEIGHT WIDTH RADIUS
28 %token <op> NAME VARNAME DEFNAME
30 %token <i> ST '(' ')' ','
35 %nonassoc <f> GT LT LE GE EQ NE
41 %type <f> expr optexpr if_expr number assign
43 %type <p> optstring if
44 %type <op> optname iterator name
46 %type <i> side optside numlist comma linetype drawtype
47 %type <ap> linedesc optdesc stringlist string stringattr sattrlist exprlist
48 %type <i> frameitem framelist coordlog
54 graphseq { if (codegen && !synerr) graph((char *) 0); }
55 | /* empty */ { codegen = 0; }
56 | error { codegen = 0; ERROR "syntax error" WARNING; }
62 | graphseq graph statlist
65 GRAPH { graph($1); endstat(); }
70 | stat ST { endstat(); }
71 | statlist stat ST { endstat(); }
75 FRAME framelist { codegen = 1; }
76 | ticks { codegen = 1; }
77 | grid { codegen = 1; }
78 | label { codegen = 1; }
80 | plot { codegen = 1; }
81 | line { codegen = 1; }
82 | circle { codegen = 1; }
84 | next { codegen = 1; }
85 | PIC { codegen = 1; pic($1); }
89 | numlist { codegen = 1; numlist(); }
91 | PRINT expr { fprintf(stderr, "\t%g\n", $2); }
92 | PRINT string { fprintf(stderr, "\t%s\n", $2->sval); freeattr($2); }
97 number { savenum(0, $1); $$ = 1; }
98 | numlist number { savenum($1, $2); $$ = $1+1; }
99 | numlist comma number { savenum($1, $3); $$ = $1+1; }
103 | '-' NUMBER %prec UMINUS { $$ = -$2; }
104 | '+' NUMBER %prec UMINUS { $$ = $2; }
108 LABEL optside stringlist lablist { label($2, $3); }
116 UP expr { labelmove($1, $2); }
117 | DOWN expr { labelmove($1, $2); }
118 | SIDE expr { labelmove($1, $2); /* LEFT or RIGHT only */ }
119 | WIDTH expr { labelwid($2); }
124 | /* empty */ { $$ = 0; }
127 HEIGHT expr { frameht($2); }
128 | WIDTH expr { framewid($2); }
129 | side linedesc { frameside($1, $2); }
130 | linedesc { frameside(0, $1); }
137 | /* empty */ { $$ = 0; }
141 linetype optexpr { $$ = makeattr($1, $2, (char *) 0, 0, 0); }
144 DOT | DASH | SOLID | INVIS
148 | /* empty */ { $$ = makeattr(0, 0.0, (char *) 0, 0, 0); }
152 TICKS tickdesc { ticks(); }
159 side { tickside($1); }
160 | IN expr { tickdir(IN, $2, 1); }
161 | OUT expr { tickdir(OUT, $2, 1); }
162 | IN { tickdir(IN, 0.0, 0); }
163 | OUT { tickdir(OUT, 0.0, 0); }
164 | AT optname ticklist { setlist(); ticklist($2, AT); }
165 | iterator { setlist(); ticklist($1, AT); }
166 | side OFF { tickoff($1); }
167 | OFF { tickoff(LEFT|RIGHT|TOP|BOT); }
172 | ticklist comma tickpoint
175 expr { savetick($1, (char *) 0); }
176 | expr string { savetick($1, $2->sval); }
179 FROM optname expr TO optname expr BY optop expr optstring
180 { iterator($3, $6, $8, $9, $10); $$ = $2; }
181 | FROM optname expr TO optname expr optstring
182 { iterator($3, $6, '+', 1.0, $7); $$ = $2; }
189 | /* empty */ { $$ = ' '; }
192 string { $$ = $1->sval; }
193 | /* empty */ { $$ = (char *) 0; }
197 GRID griddesc { ticks(); }
204 side { tickside($1); }
205 | X { tickside(BOT); }
206 | Y { tickside(LEFT); }
207 | linedesc { griddesc($1); }
208 | AT optname ticklist { setlist(); gridlist($2); }
209 | iterator { setlist(); gridlist($1); }
210 | TICKS OFF { gridtickoff(); }
211 | OFF { gridtickoff(); }
216 LINE FROM point TO point optdesc { line($1, $3, $5, $6); }
217 | LINE optdesc FROM point TO point { line($1, $4, $6, $2); }
220 CIRCLE RADIUS expr AT point { circle($3, $5); }
221 | CIRCLE AT point RADIUS expr { circle($5, $3); }
222 | CIRCLE AT point { circle(0.0, $3); }
227 | stringlist string { $$ = addattr($1, $2); }
230 STRING sattrlist { $$ = makesattr($1); }
231 | SPRINTF '(' STRING ')' sattrlist
232 { $$ = makesattr(sprntf($3, (Attr*) 0)); }
233 | SPRINTF '(' STRING ',' exprlist ')' sattrlist
234 { $$ = makesattr(sprntf($3, $5)); }
237 expr { $$ = makefattr(NUMBER, $1); }
238 | exprlist ',' expr { $$ = addattr($1, makefattr(NUMBER, $3)); }
242 | sattrlist stringattr
243 | /* empty */ { $$ = (Attr *) 0; }
246 JUST { setjust($1); }
247 | SIZE optop expr { setsize($2, $3); }
251 COORD optname coordlist { coord($2); }
252 | COORD optname { resetcoord($2); }
256 | coordlist coorditem
259 coordlog { coordlog($1); }
260 | X point { coord_x($2); }
261 | Y point { coord_y($2); }
262 | X optname expr TO expr { coord_x(makepoint($2, $3, $5)); }
263 | Y optname expr TO expr { coord_y(makepoint($2, $3, $5)); }
264 | X FROM optname expr TO expr { coord_x(makepoint($3, $4, $6)); }
265 | Y FROM optname expr TO expr { coord_y(makepoint($3, $4, $6)); }
268 LOG X { $$ = XFLAG; }
269 | LOG Y { $$ = YFLAG; }
270 | LOG X LOG Y { $$ = XFLAG|YFLAG; }
271 | LOG Y LOG X { $$ = XFLAG|YFLAG; }
272 | LOG LOG { $$ = XFLAG|YFLAG; }
276 stringlist AT point { plot($1, $3); }
277 | PLOT stringlist AT point { plot($2, $4); }
278 | PLOT expr optstring AT point { plotnum($2, $3, $5); }
282 drawtype optname linedesc { drawdesc($1, $2, $3, (char *) 0); }
283 | drawtype optname optdesc string { drawdesc($1, $2, $3, $4->sval); }
284 | drawtype optname string optdesc { drawdesc($1, $2, $4, $3->sval); }
292 NEXT optname AT point optdesc { next($2, $4, $5); }
295 COPY copylist { copy(); }
302 string { copyfile($1->sval); }
303 | THRU DEFNAME { copydef($2); }
304 | UNTIL string { copyuntil($2->sval); }
308 FOR name FROM expr TO expr BY optop expr DOSTR
309 { forloop($2, $4, $6, $8, $9, $10); }
310 | FOR name FROM expr TO expr DOSTR
311 { forloop($2, $4, $6, '+', 1.0, $7); }
312 | FOR name '=' expr TO expr BY optop expr DOSTR
313 { forloop($2, $4, $6, $8, $9, $10); }
314 | FOR name '=' expr TO expr DOSTR
315 { forloop($2, $4, $6, '+', 1.0, $7); }
319 IF if_expr THEN ELSE { $$ = ifstat($2, $3, $4); }
320 | IF if_expr THEN { $$ = ifstat($2, $3, (char *) 0); }
325 | if_expr AND string_expr { $$ = $1 && $3; }
326 | if_expr OR string_expr { $$ = $1 || $3; }
329 STRING EQ STRING { $$ = strcmp($1,$3) == 0; free($1); free($3); }
330 | STRING NE STRING { $$ = strcmp($1,$3) != 0; free($1); free($3); }
334 optname expr comma expr { $$ = makepoint($1, $2, $4); }
335 | optname '(' expr comma expr ')' { $$ = makepoint($1, $3, $5); }
343 | /* empty */ { $$ = lookup(curr_coord, 1); }
349 | '(' string_expr ')' { $$ = $2; }
350 | VARNAME { $$ = getvar($1); }
351 | expr '+' expr { $$ = $1 + $3; }
352 | expr '-' expr { $$ = $1 - $3; }
353 | expr '*' expr { $$ = $1 * $3; }
354 | expr '/' expr { if ($3 == 0.0) {
355 ERROR "division by 0" WARNING; $3 = 1; }
357 | expr '%' expr { if ((long)$3 == 0) {
358 ERROR "mod division by 0" WARNING; $3 = 1; }
359 $$ = (long)$1 % (long)$3; }
360 | '-' expr %prec UMINUS { $$ = -$2; }
361 | '+' expr %prec UMINUS { $$ = $2; }
362 | '(' expr ')' { $$ = $2; }
363 | LOG '(' expr ')' { $$ = Log10($3); }
364 | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); }
365 | expr '^' expr { $$ = pow($1, $3); }
366 | SIN '(' expr ')' { $$ = sin($3); }
367 | COS '(' expr ')' { $$ = cos($3); }
368 | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); }
369 | SQRT '(' expr ')' { $$ = Sqrt($3); }
370 | RAND '(' ')' { $$ = (double)rand() / (double)RAND_MAX; }
371 | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; }
372 | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; }
373 | INT '(' expr ')' { $$ = (long) $3; }
374 | expr GT expr { $$ = $1 > $3; }
375 | expr LT expr { $$ = $1 < $3; }
376 | expr LE expr { $$ = $1 <= $3; }
377 | expr GE expr { $$ = $1 >= $3; }
378 | expr EQ expr { $$ = $1 == $3; }
379 | expr NE expr { $$ = $1 != $3; }
380 | expr AND expr { $$ = $1 && $3; }
381 | expr OR expr { $$ = $1 || $3; }
382 | NOT expr { $$ = !($2); }
385 name '=' expr { $$ = setvar($1, $3); }
395 | /* empty */ { $$ = 0.0; }