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