Blob


1 %{
2 #include <stdio.h>
3 #include <math.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "grap.h"
8 /*#define RAND_MAX 32767 /* if your rand() returns bigger, change this too */
10 extern int yylex(void);
11 extern int yyparse(void);
13 %}
15 %token <i> FRAME TICKS GRID LABEL COORD
16 %token <i> LINE ARROW CIRCLE DRAW NEW PLOT NEXT
17 %token <p> PIC
18 %token <i> COPY THRU UNTIL
19 %token <i> FOR FROM TO BY AT WITH
20 %token <i> IF
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
27 %token <f> NUMBER
28 %token <op> NAME VARNAME DEFNAME
29 %token <p> STRING
30 %token <i> ST '(' ')' ','
32 %right <f> '='
33 %left <f> OR
34 %left <f> AND
35 %nonassoc <f> GT LT LE GE EQ NE
36 %left <f> '+' '-'
37 %left <f> '*' '/' '%'
38 %right <f> UMINUS NOT
39 %right <f> '^'
41 %type <f> expr optexpr if_expr number assign
42 %type <i> optop
43 %type <p> optstring if
44 %type <op> optname iterator name
45 %type <pt> point
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
49 %type <f> string_expr
51 %%
53 top:
54 graphseq { if (codegen && !synerr) graph((char *) 0); }
55 | /* empty */ { codegen = 0; }
56 | error { codegen = 0; ERROR "syntax error" WARNING; }
57 ;
59 graphseq:
60 statlist
61 | graph statlist
62 | graphseq graph statlist
63 ;
64 graph:
65 GRAPH { graph($1); endstat(); }
66 ;
68 statlist:
69 ST
70 | stat ST { endstat(); }
71 | statlist stat ST { endstat(); }
72 ;
74 stat:
75 FRAME framelist { codegen = 1; }
76 | ticks { codegen = 1; }
77 | grid { codegen = 1; }
78 | label { codegen = 1; }
79 | coord
80 | plot { codegen = 1; }
81 | line { codegen = 1; }
82 | circle { codegen = 1; }
83 | draw
84 | next { codegen = 1; }
85 | PIC { codegen = 1; pic($1); }
86 | for
87 | if
88 | copy
89 | numlist { codegen = 1; numlist(); }
90 | assign
91 | PRINT expr { fprintf(stderr, "\t%g\n", $2); }
92 | PRINT string { fprintf(stderr, "\t%s\n", $2->sval); freeattr($2); }
93 | /* empty */
94 ;
96 numlist:
97 number { savenum(0, $1); $$ = 1; }
98 | numlist number { savenum($1, $2); $$ = $1+1; }
99 | numlist comma number { savenum($1, $3); $$ = $1+1; }
101 number:
102 NUMBER
103 | '-' NUMBER %prec UMINUS { $$ = -$2; }
104 | '+' NUMBER %prec UMINUS { $$ = $2; }
107 label:
108 LABEL optside stringlist lablist { label($2, $3); }
110 lablist:
111 labattr
112 | lablist labattr
113 | /* empty */
115 labattr:
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); }
122 framelist:
123 framelist frameitem
124 | /* empty */ { $$ = 0; }
126 frameitem:
127 HEIGHT expr { frameht($2); }
128 | WIDTH expr { framewid($2); }
129 | side linedesc { frameside($1, $2); }
130 | linedesc { frameside(0, $1); }
132 side:
133 SIDE
135 optside:
136 side
137 | /* empty */ { $$ = 0; }
140 linedesc:
141 linetype optexpr { $$ = makeattr($1, $2, (char *) 0, 0, 0); }
143 linetype:
144 DOT | DASH | SOLID | INVIS
146 optdesc:
147 linedesc
148 | /* empty */ { $$ = makeattr(0, 0.0, (char *) 0, 0, 0); }
151 ticks:
152 TICKS tickdesc { ticks(); }
154 tickdesc:
155 tickattr
156 | tickdesc tickattr
158 tickattr:
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); }
168 | labattr
170 ticklist:
171 tickpoint
172 | ticklist comma tickpoint
174 tickpoint:
175 expr { savetick($1, (char *) 0); }
176 | expr string { savetick($1, $2->sval); }
178 iterator:
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; }
184 optop:
185 '+' { $$ = '+'; }
186 | '-' { $$ = '-'; }
187 | '*' { $$ = '*'; }
188 | '/' { $$ = '/'; }
189 | /* empty */ { $$ = ' '; }
191 optstring:
192 string { $$ = $1->sval; }
193 | /* empty */ { $$ = (char *) 0; }
196 grid:
197 GRID griddesc { ticks(); }
199 griddesc:
200 gridattr
201 | griddesc gridattr
203 gridattr:
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(); }
212 | labattr
215 line:
216 LINE FROM point TO point optdesc { line($1, $3, $5, $6); }
217 | LINE optdesc FROM point TO point { line($1, $4, $6, $2); }
219 circle:
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); }
225 stringlist:
226 string
227 | stringlist string { $$ = addattr($1, $2); }
229 string:
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)); }
236 exprlist:
237 expr { $$ = makefattr(NUMBER, $1); }
238 | exprlist ',' expr { $$ = addattr($1, makefattr(NUMBER, $3)); }
240 sattrlist:
241 stringattr
242 | sattrlist stringattr
243 | /* empty */ { $$ = (Attr *) 0; }
245 stringattr:
246 JUST { setjust($1); }
247 | SIZE optop expr { setsize($2, $3); }
250 coord:
251 COORD optname coordlist { coord($2); }
252 | COORD optname { resetcoord($2); }
254 coordlist:
255 coorditem
256 | coordlist coorditem
258 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)); }
267 coordlog:
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; }
275 plot:
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); }
281 draw:
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); }
286 drawtype:
287 DRAW
288 | NEW
291 next:
292 NEXT optname AT point optdesc { next($2, $4, $5); }
294 copy:
295 COPY copylist { copy(); }
297 copylist:
298 copyattr
299 | copylist copyattr
301 copyattr:
302 string { copyfile($1->sval); }
303 | THRU DEFNAME { copydef($2); }
304 | UNTIL string { copyuntil($2->sval); }
307 for:
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); }
318 if:
319 IF if_expr THEN ELSE { $$ = ifstat($2, $3, $4); }
320 | IF if_expr THEN { $$ = ifstat($2, $3, (char *) 0); }
322 if_expr:
323 expr
324 | string_expr
325 | if_expr AND string_expr { $$ = $1 && $3; }
326 | if_expr OR string_expr { $$ = $1 || $3; }
328 string_expr:
329 STRING EQ STRING { $$ = strcmp($1,$3) == 0; free($1); free($3); }
330 | STRING NE STRING { $$ = strcmp($1,$3) != 0; free($1); free($3); }
333 point:
334 optname expr comma expr { $$ = makepoint($1, $2, $4); }
335 | optname '(' expr comma expr ')' { $$ = makepoint($1, $3, $5); }
337 comma:
338 ',' { $$ = ','; }
341 optname:
342 NAME { $$ = $1; }
343 | /* empty */ { $$ = lookup(curr_coord, 1); }
346 expr:
347 NUMBER
348 | assign
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; }
356 $$ = $1 / $3; }
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); }
384 assign:
385 name '=' expr { $$ = setvar($1, $3); }
388 name:
389 NAME
390 | VARNAME
393 optexpr:
394 expr
395 | /* empty */ { $$ = 0.0; }