|
|
1.1 root 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: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.