Blob


1 %{
2 #include <stdio.h>
3 #include "pic.h"
4 #include <math.h>
5 #include <stdlib.h>
6 #include <string.h>
8 YYSTYPE y;
10 extern void yyerror(char *);
11 extern int yylex(void);
12 %}
14 %token <i> BOX 1 /* DON'T CHANGE THESE! */
15 %token <i> LINE 2
16 %token <i> ARROW 3
17 %token <i> CIRCLE 4
18 %token <i> ELLIPSE 5
19 %token <i> ARC 6
20 %token <i> SPLINE 7
21 %token <i> BLOCK 8
22 %token <p> TEXT 9
23 %token <p> TROFF 10
24 %token <i> MOVE 11
25 %token <i> BLOCKEND 12
26 %token <i> PLACE 13
27 %token <i> PRINT RESET THRU UNTIL
28 %token <o> FOR IF COPY
29 %token <p> THENSTR ELSESTR DOSTR PLACENAME VARNAME SPRINTF
30 %token <st> DEFNAME
31 %token <i> ATTR TEXTATTR
32 %token <i> LEFT RIGHT UP DOWN FROM TO AT BY WITH HEAD CW CCW THEN
33 %token <i> HEIGHT WIDTH RADIUS DIAMETER LENGTH SIZE
34 %token <i> CORNER HERE LAST NTH SAME BETWEEN AND
35 %token <i> EAST WEST NORTH SOUTH NE NW SE SW START END
36 %token <i> DOTX DOTY DOTHT DOTWID DOTRAD
37 %token <f> NUMBER
38 %token <f> LOG EXP SIN COS ATAN2 SQRT RAND MIN MAX INT
39 %token <i> DIR
40 %token <i> DOT DASH CHOP FILL NOEDGE
41 %token <o> ST /* statement terminator */
43 %right <f> '='
44 %left <f> OROR
45 %left <f> ANDAND
46 %nonassoc <f> GT LT LE GE EQ NEQ
47 %left <f> '+' '-'
48 %left <f> '*' '/' '%'
49 %right <f> UMINUS NOT
50 %right <f> '^'
52 %type <f> expr if_expr asgn
53 %type <p> name text
54 %type <i> optop exprlist
55 %type <o> if for copy
57 /* this is a lie: picture and position are really the whole union */
58 %type <o> leftbrace picture piclist position lbracket
59 %type <o> prim place blockname
60 %type <i> textlist textattr /* not a sensible value */
61 %type <i> last type
63 %%
65 top:
66 piclist
67 | /* empty */
68 | error { ERROR "syntax error" WARNING; }
69 ;
71 piclist:
72 picture
73 | piclist picture
74 ;
76 picture:
77 prim ST { codegen = 1; makeiattr(0, 0); }
78 | leftbrace piclist '}' { rightthing($1, '}'); $$ = $2; }
79 | PLACENAME ':' picture { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; }
80 | PLACENAME ':' ST picture { y.o=$4; makevar($1,PLACENAME,y); $$ = $4; }
81 | PLACENAME ':' position ST { y.o=$3; makevar($1,PLACENAME,y); $$ = $3; }
82 | asgn ST { y.f = $1; $$ = y.o; $$ = makenode(PLACE, 0); }
83 | DIR { setdir($1); $$ = makenode(PLACE, 0); }
84 | PRINT expr ST { printexpr($2); $$ = makenode(PLACE, 0); }
85 | PRINT position ST { printpos($2); $$ = makenode(PLACE, 0); }
86 | PRINT text ST { printf("%s\n", $2); free($2); $$ = makenode(PLACE, 0); }
87 | RESET varlist ST { resetvar(); makeiattr(0, 0); $$ = makenode(PLACE, 0); }
88 | copy
89 | for
90 | if
91 | ST
92 ;
94 varlist:
95 /* empty */
96 | VARNAME { makevattr($1); }
97 | varlist VARNAME { makevattr($2); }
98 | varlist ',' VARNAME { makevattr($3); }
99 ;
101 asgn:
102 VARNAME '=' expr { $$=y.f=$3; makevar($1,VARNAME,y); checkscale($1); }
105 copy:
106 COPY copylist { copy(); }
108 copylist:
109 copyattr
110 | copylist copyattr
112 copyattr:
113 text { copyfile($1); }
114 | THRU DEFNAME { copydef($2); }
115 | UNTIL text { copyuntil($2); }
118 for:
119 FOR name FROM expr TO expr BY optop expr DOSTR
120 { forloop($2, $4, $6, $8, $9, $10); }
121 | FOR name FROM expr TO expr DOSTR
122 { forloop($2, $4, $6, '+', 1.0, $7); }
123 | FOR name '=' expr TO expr BY optop expr DOSTR
124 { forloop($2, $4, $6, $8, $9, $10); }
125 | FOR name '=' expr TO expr DOSTR
126 { forloop($2, $4, $6, '+', 1.0, $7); }
129 if:
130 IF if_expr THENSTR ELSESTR { ifstat($2, $3, $4); }
131 | IF if_expr THENSTR { ifstat($2, $3, (char *) 0); }
133 if_expr:
134 expr
135 | text EQ text { $$ = strcmp($1,$3) == 0; free($1); free($3); }
136 | text NEQ text { $$ = strcmp($1,$3) != 0; free($1); free($3); }
139 name:
140 VARNAME { y.f = 0; makevar($1, VARNAME, y); }
142 optop:
143 '+' { $$ = '+'; }
144 | '-' { $$ = '-'; }
145 | '*' { $$ = '*'; }
146 | '/' { $$ = '/'; }
147 | /* empty */ { $$ = ' '; }
151 leftbrace:
152 '{' { $$ = leftthing('{'); }
155 prim:
156 BOX attrlist { $$ = boxgen(); }
157 | CIRCLE attrlist { $$ = circgen($1); }
158 | ELLIPSE attrlist { $$ = circgen($1); }
159 | ARC attrlist { $$ = arcgen($1); }
160 | LINE attrlist { $$ = linegen($1); }
161 | ARROW attrlist { $$ = linegen($1); }
162 | SPLINE attrlist { $$ = linegen($1); }
163 | MOVE attrlist { $$ = movegen(); }
164 | textlist attrlist { $$ = textgen(); }
165 | TROFF { $$ = troffgen($1); }
166 | lbracket piclist ']' { $<o>$=rightthing($1,']'); } attrlist
167 { $$ = blockgen($1, $<o>4); }
170 lbracket:
171 '[' { $$ = leftthing('['); }
174 attrlist:
175 attrlist attr
176 | /* empty */
179 attr:
180 ATTR expr { makefattr($1, !DEFAULT, $2); }
181 | ATTR { makefattr($1, DEFAULT, 0.0); }
182 | expr { makefattr(curdir(), !DEFAULT, $1); }
183 | DIR expr { makefattr($1, !DEFAULT, $2); }
184 | DIR { makefattr($1, DEFAULT, 0.0); }
185 | FROM position { makeoattr($1, $2); }
186 | TO position { makeoattr($1, $2); }
187 | AT position { makeoattr($1, $2); }
188 | BY position { makeoattr($1, $2); }
189 | WITH CORNER { makeiattr(WITH, $2); }
190 | WITH '.' PLACENAME { makeoattr(PLACE, getblock(getlast(1,BLOCK), $3)); }
191 | WITH '.' PLACENAME CORNER
192 { makeoattr(PLACE, getpos(getblock(getlast(1,BLOCK), $3), $4)); }
193 | WITH position { makeoattr(PLACE, $2); }
194 | SAME { makeiattr(SAME, $1); }
195 | TEXTATTR { maketattr($1, (char *) 0); }
196 | HEAD { makeiattr(HEAD, $1); }
197 | DOT expr { makefattr(DOT, !DEFAULT, $2); }
198 | DOT { makefattr(DOT, DEFAULT, 0.0); }
199 | DASH expr { makefattr(DASH, !DEFAULT, $2); }
200 | DASH { makefattr(DASH, DEFAULT, 0.0); }
201 | CHOP expr { makefattr(CHOP, !DEFAULT, $2); }
202 | CHOP { makefattr(CHOP, DEFAULT, 0.0); }
203 | CHOP PLACENAME { makeattr(CHOP, PLACENAME, getvar($2)); }
204 | FILL expr { makefattr(FILL, !DEFAULT, $2); }
205 | FILL { makefattr(FILL, DEFAULT, 0.0); }
206 | NOEDGE { makeiattr(NOEDGE, 0); }
207 | textlist
210 textlist:
211 textattr
212 | textlist textattr
214 textattr:
215 text { maketattr(CENTER, $1); }
216 | text TEXTATTR { maketattr($2, $1); }
217 | textattr TEXTATTR { addtattr($2); }
219 text:
220 TEXT
221 | SPRINTF '(' text ')' { $$ = sprintgen($3); }
222 | SPRINTF '(' text ',' exprlist ')' { $$ = sprintgen($3); }
225 exprlist:
226 expr { exprsave($1); $$ = 0; }
227 | exprlist ',' expr { exprsave($3); }
230 position: /* absolute, not relative */
231 place
232 | '(' position ')' { $$ = $2; }
233 | expr ',' expr { $$ = makepos($1, $3); }
234 | position '+' expr ',' expr { $$ = fixpos($1, $3, $5); }
235 | position '-' expr ',' expr { $$ = fixpos($1, -$3, -$5); }
236 | position '+' '(' expr ',' expr ')' { $$ = fixpos($1, $4, $6); }
237 | position '-' '(' expr ',' expr ')' { $$ = fixpos($1, -$4, -$6); }
238 | position '+' place { $$ = addpos($1, $3); }
239 | position '-' place { $$ = subpos($1, $3); }
240 | '(' place ',' place ')' { $$ = makepos(getcomp($2,DOTX), getcomp($4,DOTY)); }
241 | expr LT position ',' position GT { $$ = makebetween($1, $3, $5); }
242 | expr BETWEEN position AND position { $$ = makebetween($1, $3, $5); }
245 place:
246 PLACENAME { y = getvar($1); $$ = y.o; }
247 | PLACENAME CORNER { y = getvar($1); $$ = getpos(y.o, $2); }
248 | CORNER PLACENAME { y = getvar($2); $$ = getpos(y.o, $1); }
249 | HERE { $$ = gethere(); }
250 | last type { $$ = getlast($1, $2); }
251 | last type CORNER { $$ = getpos(getlast($1, $2), $3); }
252 | CORNER last type { $$ = getpos(getlast($2, $3), $1); }
253 | NTH type { $$ = getfirst($1, $2); }
254 | NTH type CORNER { $$ = getpos(getfirst($1, $2), $3); }
255 | CORNER NTH type { $$ = getpos(getfirst($2, $3), $1); }
256 | blockname
257 | blockname CORNER { $$ = getpos($1, $2); }
258 | CORNER blockname { $$ = getpos($2, $1); }
261 blockname:
262 last BLOCK '.' PLACENAME { $$ = getblock(getlast($1,$2), $4); }
263 | NTH BLOCK '.' PLACENAME { $$ = getblock(getfirst($1,$2), $4); }
264 | PLACENAME '.' PLACENAME { y = getvar($1); $$ = getblock(y.o, $3); }
267 last:
268 last LAST { $$ = $1 + 1; }
269 | NTH LAST { $$ = $1; }
270 | LAST { $$ = 1; }
273 type:
274 BOX
275 | CIRCLE
276 | ELLIPSE
277 | ARC
278 | LINE
279 | ARROW
280 | SPLINE
281 | BLOCK
284 expr:
285 NUMBER
286 | VARNAME { $$ = getfval($1); }
287 | asgn
288 | expr '+' expr { $$ = $1 + $3; }
289 | expr '-' expr { $$ = $1 - $3; }
290 | expr '*' expr { $$ = $1 * $3; }
291 | expr '/' expr { if ($3 == 0.0) {
292 ERROR "division by 0" WARNING; $3 = 1; }
293 $$ = $1 / $3; }
294 | expr '%' expr { if ((long)$3 == 0) {
295 ERROR "mod division by 0" WARNING; $3 = 1; }
296 $$ = (long)$1 % (long)$3; }
297 | '-' expr %prec UMINUS { $$ = -$2; }
298 | '+' expr %prec UMINUS { $$ = $2; }
299 | '(' expr ')' { $$ = $2; }
300 | place DOTX { $$ = getcomp($1, $2); }
301 | place DOTY { $$ = getcomp($1, $2); }
302 | place DOTHT { $$ = getcomp($1, $2); }
303 | place DOTWID { $$ = getcomp($1, $2); }
304 | place DOTRAD { $$ = getcomp($1, $2); }
305 | PLACENAME '.' VARNAME { y = getvar($1); $$ = getblkvar(y.o, $3); }
306 | last BLOCK '.' VARNAME { $$ = getblkvar(getlast($1,$2), $4); }
307 | NTH BLOCK '.' VARNAME { $$ = getblkvar(getfirst($1,$2), $4); }
308 | expr GT expr { $$ = $1 > $3; }
309 | expr LT expr { $$ = $1 < $3; }
310 | expr LE expr { $$ = $1 <= $3; }
311 | expr GE expr { $$ = $1 >= $3; }
312 | expr EQ expr { $$ = $1 == $3; }
313 | expr NEQ expr { $$ = $1 != $3; }
314 | expr ANDAND expr { $$ = $1 && $3; }
315 | expr OROR expr { $$ = $1 || $3; }
316 | NOT expr { $$ = !($2); }
317 | LOG '(' expr ')' { $$ = Log10($3); }
318 | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); }
319 | expr '^' expr { $$ = pow($1, $3); }
320 | SIN '(' expr ')' { $$ = sin($3); }
321 | COS '(' expr ')' { $$ = cos($3); }
322 | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); }
323 | SQRT '(' expr ')' { $$ = Sqrt($3); }
324 | RAND '(' ')' { $$ = (float)rand() / 32767.0; /* might be 2^31-1 */ }
325 | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; }
326 | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; }
327 | INT '(' expr ')' { $$ = (long) $3; }