|
|
1.1 root 1: %{
2: #include <stdio.h>
3: #include "pic.h"
4: #include <math.h>
5: #include <stdlib.h>
6: #include <string.h>
7:
8: YYSTYPE y;
9:
10: extern void yyerror(char *);
11: extern int yylex(void);
12: %}
13:
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 */
42:
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> '^'
51:
52: %type <f> expr if_expr asgn
53: %type <p> name text
54: %type <i> optop exprlist
55: %type <o> if for copy
56:
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
62:
63: %%
64:
65: top:
66: piclist
67: | /* empty */
68: | error { ERROR "syntax error" WARNING; }
69: ;
70:
71: piclist:
72: picture
73: | piclist picture
74: ;
75:
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: ;
93:
94: varlist:
95: /* empty */
96: | VARNAME { makevattr($1); }
97: | varlist VARNAME { makevattr($2); }
98: | varlist ',' VARNAME { makevattr($3); }
99: ;
100:
101: asgn:
102: VARNAME '=' expr { $$=y.f=$3; makevar($1,VARNAME,y); checkscale($1); }
103: ;
104:
105: copy:
106: COPY copylist { copy(); }
107: ;
108: copylist:
109: copyattr
110: | copylist copyattr
111: ;
112: copyattr:
113: text { copyfile($1); }
114: | THRU DEFNAME { copydef($2); }
115: | UNTIL text { copyuntil($2); }
116: ;
117:
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); }
127: ;
128:
129: if:
130: IF if_expr THENSTR ELSESTR { ifstat($2, $3, $4); }
131: | IF if_expr THENSTR { ifstat($2, $3, (char *) 0); }
132: ;
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); }
137: ;
138:
139: name:
140: VARNAME { y.f = 0; makevar($1, VARNAME, y); }
141: ;
142: optop:
143: '+' { $$ = '+'; }
144: | '-' { $$ = '-'; }
145: | '*' { $$ = '*'; }
146: | '/' { $$ = '/'; }
147: | /* empty */ { $$ = ' '; }
148: ;
149:
150:
151: leftbrace:
152: '{' { $$ = leftthing('{'); }
153: ;
154:
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); }
168: ;
169:
170: lbracket:
171: '[' { $$ = leftthing('['); }
172: ;
173:
174: attrlist:
175: attrlist attr
176: | /* empty */
177: ;
178:
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
208: ;
209:
210: textlist:
211: textattr
212: | textlist textattr
213: ;
214: textattr:
215: text { maketattr(CENTER, $1); }
216: | text TEXTATTR { maketattr($2, $1); }
217: | textattr TEXTATTR { addtattr($2); }
218: ;
219: text:
220: TEXT
221: | SPRINTF '(' text ')' { $$ = sprintgen($3); }
222: | SPRINTF '(' text ',' exprlist ')' { $$ = sprintgen($3); }
223: ;
224:
225: exprlist:
226: expr { exprsave($1); $$ = 0; }
227: | exprlist ',' expr { exprsave($3); }
228: ;
229:
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); }
243: ;
244:
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); }
259: ;
260:
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); }
265: ;
266:
267: last:
268: last LAST { $$ = $1 + 1; }
269: | NTH LAST { $$ = $1; }
270: | LAST { $$ = 1; }
271: ;
272:
273: type:
274: BOX
275: | CIRCLE
276: | ELLIPSE
277: | ARC
278: | LINE
279: | ARROW
280: | SPLINE
281: | BLOCK
282: ;
283:
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 ')' { $$ = $2; }
299: | place DOTX { $$ = getcomp($1, $2); }
300: | place DOTY { $$ = getcomp($1, $2); }
301: | place DOTHT { $$ = getcomp($1, $2); }
302: | place DOTWID { $$ = getcomp($1, $2); }
303: | place DOTRAD { $$ = getcomp($1, $2); }
304: | PLACENAME '.' VARNAME { y = getvar($1); $$ = getblkvar(y.o, $3); }
305: | last BLOCK '.' VARNAME { $$ = getblkvar(getlast($1,$2), $4); }
306: | NTH BLOCK '.' VARNAME { $$ = getblkvar(getfirst($1,$2), $4); }
307: | expr GT expr { $$ = $1 > $3; }
308: | expr LT expr { $$ = $1 < $3; }
309: | expr LE expr { $$ = $1 <= $3; }
310: | expr GE expr { $$ = $1 >= $3; }
311: | expr EQ expr { $$ = $1 == $3; }
312: | expr NEQ expr { $$ = $1 != $3; }
313: | expr ANDAND expr { $$ = $1 && $3; }
314: | expr OROR expr { $$ = $1 || $3; }
315: | NOT expr { $$ = !($2); }
316: | LOG '(' expr ')' { $$ = Log10($3); }
317: | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); }
318: | expr '^' expr { $$ = pow($1, $3); }
319: | SIN '(' expr ')' { $$ = sin($3); }
320: | COS '(' expr ')' { $$ = cos($3); }
321: | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); }
322: | SQRT '(' expr ')' { $$ = Sqrt($3); }
323: | RAND '(' ')' { $$ = (float)rand() / 32767.0; /* might be 2^31-1 */ }
324: | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; }
325: | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; }
326: | INT '(' expr ')' { $$ = (long) $3; }
327: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.