tgrap.y - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tgrap.y (9294B)
---
1 %{
2 #include <stdio.h>
3 #include <math.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include "grap.h"
7
8 /*#define RAND_MAX 32767 /* if your rand() returns bigger, change this too */
9
10 extern int yylex(void);
11 extern int yyparse(void);
12
13 %}
14
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 '(' ')' ','
31
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> '^'
40
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
50
51 %%
52
53 top:
54 graphseq { if (codegen && !synerr) graph((char *) 0); }
55 | /* empty */ { codegen = 0; }
56 | error { codegen = 0; ERROR "syntax error" WARNING; }
57 ;
58
59 graphseq:
60 statlist
61 | graph statlist
62 | graphseq graph statlist
63 ;
64 graph:
65 GRAPH { graph($1); endstat(); }
66 ;
67
68 statlist:
69 ST
70 | stat ST { endstat(); }
71 | statlist stat ST { endstat(); }
72 ;
73
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 ;
95
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; }
100 ;
101 number:
102 NUMBER
103 | '-' NUMBER %prec UMINUS { $$ = -$2; }
104 | '+' NUMBER %prec UMINUS { $$ = $2; }
105 ;
106
107 label:
108 LABEL optside stringlist lablist { label($2, $3); }
109 ;
110 lablist:
111 labattr
112 | lablist labattr
113 | /* empty */
114 ;
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); }
120 ;
121
122 framelist:
123 framelist frameitem
124 | /* empty */ { $$ = 0; }
125 ;
126 frameitem:
127 HEIGHT expr { frameht($2); }
128 | WIDTH expr { framewid($2); }
129 | side linedesc { frameside($1, $2); }
130 | linedesc { frameside(0, $1); }
131 ;
132 side:
133 SIDE
134 ;
135 optside:
136 side
137 | /* empty */ { $$ = 0; }
138 ;
139
140 linedesc:
141 linetype optexpr { $$ = makeattr($1, $2, (char *) 0, 0, 0); }
142 ;
143 linetype:
144 DOT | DASH | SOLID | INVIS
145 ;
146 optdesc:
147 linedesc
148 | /* empty */ { $$ = makeattr(0, 0.0, (char *) 0, 0, 0); }
149 ;
150
151 ticks:
152 TICKS tickdesc { ticks(); }
153 ;
154 tickdesc:
155 tickattr
156 | tickdesc tickattr
157 ;
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
169 ;
170 ticklist:
171 tickpoint
172 | ticklist comma tickpoint
173 ;
174 tickpoint:
175 expr { savetick($1, (char *) 0); }
176 | expr string { savetick($1, $2->sval); }
177 ;
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; }
183 ;
184 optop:
185 '+' { $$ = '+'; }
186 | '-' { $$ = '-'; }
187 | '*' { $$ = '*'; }
188 | '/' { $$ = '/'; }
189 | /* empty */ { $$ = ' '; }
190 ;
191 optstring:
192 string { $$ = $1->sval; }
193 | /* empty */ { $$ = (char *) 0; }
194 ;
195
196 grid:
197 GRID griddesc { ticks(); }
198 ;
199 griddesc:
200 gridattr
201 | griddesc gridattr
202 ;
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
213 ;
214
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); }
218 ;
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); }
223 ;
224
225 stringlist:
226 string
227 | stringlist string { $$ = addattr($1, $2); }
228 ;
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)); }
235 ;
236 exprlist:
237 expr { $$ = makefattr(NUMBER, $1); }
238 | exprlist ',' expr { $$ = addattr($1, makefattr(NUMBER, $3)); }
239 ;
240 sattrlist:
241 stringattr
242 | sattrlist stringattr
243 | /* empty */ { $$ = (Attr *) 0; }
244 ;
245 stringattr:
246 JUST { setjust($1); }
247 | SIZE optop expr { setsize($2, $3); }
248 ;
249
250 coord:
251 COORD optname coordlist { coord($2); }
252 | COORD optname { resetcoord($2); }
253 ;
254 coordlist:
255 coorditem
256 | coordlist coorditem
257 ;
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)); }
266 ;
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; }
273 ;
274
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); }
279 ;
280
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); }
285 ;
286 drawtype:
287 DRAW
288 | NEW
289 ;
290
291 next:
292 NEXT optname AT point optdesc { next($2, $4, $5); }
293
294 copy:
295 COPY copylist { copy(); }
296 ;
297 copylist:
298 copyattr
299 | copylist copyattr
300 ;
301 copyattr:
302 string { copyfile($1->sval); }
303 | THRU DEFNAME { copydef($2); }
304 | UNTIL string { copyuntil($2->sval); }
305 ;
306
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); }
316 ;
317
318 if:
319 IF if_expr THEN ELSE { $$ = ifstat($2, $3, $4); }
320 | IF if_expr THEN { $$ = ifstat($2, $3, (char *) 0); }
321 ;
322 if_expr:
323 expr
324 | string_expr
325 | if_expr AND string_expr { $$ = $1 && $3; }
326 | if_expr OR string_expr { $$ = $1 || $3; }
327 ;
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); }
331 ;
332
333 point:
334 optname expr comma expr { $$ = makepoint($1, $2, $4); }
335 | optname '(' expr comma expr ')' { $$ = makepoint($1, $3, $5); }
336 ;
337 comma:
338 ',' { $$ = ','; }
339 ;
340
341 optname:
342 NAME { $$ = $1; }
343 | /* empty */ { $$ = lookup(curr_coord, 1); }
344 ;
345
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); }
383 ;
384 assign:
385 name '=' expr { $$ = setvar($1, $3); }
386 ;
387
388 name:
389 NAME
390 | VARNAME
391 ;
392
393 optexpr:
394 expr
395 | /* empty */ { $$ = 0.0; }
396 ;