|
|
1.1 root 1: %{
2: #include <stdio.h>
3: #include <math.h>
4: #include "grap.h"
5:
6: #define RAND_MAX 32767 /* if your rand() returns bigger, change this too */
7:
8: %}
9:
10: %token <i> FRAME TICKS GRID LABEL COORD
11: %token <i> LINE ARROW CIRCLE DRAW NEW PLOT NEXT
12: %token <p> PIC
13: %token <i> COPY THRU UNTIL
14: %token <i> FOR FROM TO BY AT WITH
15: %token <i> IF
16: %token <p> GRAPH THEN ELSE DOSTR
17: %token <i> DOT DASH INVIS SOLID
18: %token <i> TEXT JUST SIZE
19: %token <i> LOG EXP SIN COS ATAN2 SQRT RAND MAX MIN INT PRINT SPRINTF
20: %token <i> X Y SIDE IN OUT OFF UP DOWN ACROSS
21: %token <i> HEIGHT WIDTH RADIUS
22: %token <f> NUMBER
23: %token <op> NAME VARNAME DEFNAME
24: %token <p> STRING
25: %token <i> ST '(' ')' ','
26:
27: %right <f> '='
28: %left <f> OR
29: %left <f> AND
30: %nonassoc <f> GT LT LE GE EQ NE
31: %left <f> '+' '-'
32: %left <f> '*' '/' '%'
33: %right <f> UMINUS NOT
34: %right <f> '^'
35:
36: %type <f> expr optexpr if_expr number assign
37: %type <i> optop
38: %type <p> optstring if
39: %type <op> optname iterator name
40: %type <pt> point
41: %type <i> side optside numlist comma linetype drawtype
42: %type <ap> linedesc optdesc stringlist string stringattr sattrlist exprlist
43: %type <i> frameitem framelist coordlog
44:
45: %%
46:
47: top:
48: graphseq { if (codegen && !synerr) graph((char *) 0); }
49: | /* empty */ { codegen = 0; }
50: | error { codegen = 0; ERROR "syntax error" WARNING; }
51: ;
52:
53: graphseq:
54: statlist
55: | graph statlist
56: | graphseq graph statlist
57: ;
58: graph:
59: GRAPH { graph($1); endstat(); }
60: ;
61:
62: statlist:
63: ST
64: | stat ST { endstat(); }
65: | statlist stat ST { endstat(); }
66: ;
67:
68: stat:
69: FRAME framelist { codegen = 1; }
70: | ticks { codegen = 1; }
71: | grid { codegen = 1; }
72: | label { codegen = 1; }
73: | coord
74: | plot { codegen = 1; }
75: | line { codegen = 1; }
76: | circle { codegen = 1; }
77: | draw
78: | next { codegen = 1; }
79: | PIC { codegen = 1; pic($1); }
80: | for
81: | if
82: | copy
83: | numlist { codegen = 1; numlist(); }
84: | assign
85: | PRINT expr { fprintf(stderr, "\t%g\n", $2); }
86: | PRINT string { fprintf(stderr, "\t%s\n", $2->sval); freeattr($2); }
87: | /* empty */
88: ;
89:
90: numlist:
91: number { savenum(0, $1); $$ = 1; }
92: | numlist number { savenum($1, $2); $$ = $1+1; }
93: | numlist comma number { savenum($1, $3); $$ = $1+1; }
94: ;
95: number:
96: NUMBER
97: | '-' NUMBER %prec UMINUS { $$ = -$2; }
98: | '+' NUMBER %prec UMINUS { $$ = $2; }
99: ;
100:
101: label:
102: LABEL optside stringlist lablist { label($2, $3); }
103: ;
104: lablist:
105: labattr
106: | lablist labattr
107: | /* empty */
108: ;
109: labattr:
110: UP expr { labelmove($1, $2); }
111: | DOWN expr { labelmove($1, $2); }
112: | SIDE expr { labelmove($1, $2); /* LEFT or RIGHT only */ }
113: | WIDTH expr { labelwid($2); }
114: ;
115:
116: framelist:
117: framelist frameitem
118: | /* empty */ { $$ = 0; }
119: ;
120: frameitem:
121: HEIGHT expr { frameht($2); }
122: | WIDTH expr { framewid($2); }
123: | side linedesc { frameside($1, $2); }
124: | linedesc { frameside(0, $1); }
125: ;
126: side:
127: SIDE
128: ;
129: optside:
130: side
131: | /* empty */ { $$ = 0; }
132: ;
133:
134: linedesc:
135: linetype optexpr { $$ = makeattr($1, $2, (char *) 0, 0, 0); }
136: ;
137: linetype:
138: DOT | DASH | SOLID | INVIS
139: ;
140: optdesc:
141: linedesc
142: | /* empty */ { $$ = makeattr(0, 0.0, (char *) 0, 0, 0); }
143: ;
144:
145: ticks:
146: TICKS tickdesc { ticks(); }
147: ;
148: tickdesc:
149: tickattr
150: | tickdesc tickattr
151: ;
152: tickattr:
153: side { tickside($1); }
154: | IN expr { tickdir(IN, $2, 1); }
155: | OUT expr { tickdir(OUT, $2, 1); }
156: | IN { tickdir(IN, 0.0, 0); }
157: | OUT { tickdir(OUT, 0.0, 0); }
158: | AT optname ticklist { setlist(); ticklist($2, AT); }
159: | iterator { setlist(); ticklist($1, AT); }
160: | side OFF { tickoff($1); }
161: | OFF { tickoff(LEFT|RIGHT|TOP|BOT); }
162: | labattr
163: ;
164: ticklist:
165: tickpoint
166: | ticklist comma tickpoint
167: ;
168: tickpoint:
169: expr { savetick($1, (char *) 0); }
170: | expr STRING { savetick($1, $2); }
171: ;
172: iterator:
173: FROM optname expr TO optname expr BY optop expr optstring
174: { iterator($3, $6, $8, $9, $10); $$ = $2; }
175: | FROM optname expr TO optname expr optstring
176: { iterator($3, $6, '+', 1.0, $7); $$ = $2; }
177: ;
178: optop:
179: '+' { $$ = '+'; }
180: | '-' { $$ = '-'; }
181: | '*' { $$ = '*'; }
182: | '/' { $$ = '/'; }
183: | /* empty */ { $$ = ' '; }
184: ;
185: optstring:
186: STRING
187: | /* empty */ { $$ = (char *) 0; }
188: ;
189:
190: grid:
191: GRID griddesc { ticks(); }
192: ;
193: griddesc:
194: gridattr
195: | griddesc gridattr
196: ;
197: gridattr:
198: side { tickside($1); }
199: | X { tickside(BOT); }
200: | Y { tickside(LEFT); }
201: | linedesc { griddesc($1); }
202: | AT optname ticklist { setlist(); gridlist($2); }
203: | iterator { setlist(); gridlist($1); }
204: | TICKS OFF { gridtickoff(); }
205: | OFF { gridtickoff(); }
206: | labattr
207: ;
208:
209: line:
210: LINE FROM point TO point optdesc { line($1, $3, $5, $6); }
211: | LINE optdesc FROM point TO point { line($1, $4, $6, $2); }
212: ;
213: circle:
214: CIRCLE RADIUS expr AT point { circle($3, $5); }
215: | CIRCLE AT point RADIUS expr { circle($5, $3); }
216: | CIRCLE AT point { circle(0.0, $3); }
217: ;
218:
219: stringlist:
220: string
221: | stringlist string { $$ = addattr($1, $2); }
222: ;
223: string:
224: STRING sattrlist { $$ = makesattr($1); }
225: | SPRINTF '(' STRING ')' sattrlist
226: { $$ = makesattr(sprntf($3, (Attr*) 0)); }
227: | SPRINTF '(' STRING ',' exprlist ')' sattrlist
228: { $$ = makesattr(sprntf($3, $5)); }
229: ;
230: exprlist:
231: expr { $$ = makefattr(NUMBER, $1); }
232: | exprlist ',' expr { $$ = addattr($1, makefattr(NUMBER, $3)); }
233: ;
234: sattrlist:
235: stringattr
236: | sattrlist stringattr
237: | /* empty */ { $$ = (Attr *) 0; }
238: ;
239: stringattr:
240: JUST { setjust($1); }
241: | SIZE optop expr { setsize($2, $3); }
242: ;
243:
244: coord:
245: COORD optname coordlist { coord($2); }
246: | COORD optname { resetcoord($2); }
247: ;
248: coordlist:
249: coorditem
250: | coordlist coorditem
251: ;
252: coorditem:
253: coordlog { coordlog($1); }
254: | X point { coord_x($2); }
255: | Y point { coord_y($2); }
256: | X optname expr TO expr { coord_x(makepoint($2, $3, $5)); }
257: | Y optname expr TO expr { coord_y(makepoint($2, $3, $5)); }
258: | X FROM optname expr TO expr { coord_x(makepoint($3, $4, $6)); }
259: | Y FROM optname expr TO expr { coord_y(makepoint($3, $4, $6)); }
260: ;
261: coordlog:
262: LOG X { $$ = XFLAG; }
263: | LOG Y { $$ = YFLAG; }
264: | LOG X LOG Y { $$ = XFLAG|YFLAG; }
265: | LOG Y LOG X { $$ = XFLAG|YFLAG; }
266: | LOG LOG { $$ = XFLAG|YFLAG; }
267: ;
268:
269: plot:
270: stringlist AT point { plot($1, $3); }
271: | PLOT stringlist AT point { plot($2, $4); }
272: | PLOT expr optstring AT point { plotnum($2, $3, $5); }
273: ;
274:
275: draw:
276: drawtype optname linedesc { drawdesc($1, $2, $3, (char *) 0); }
277: | drawtype optname optdesc STRING { drawdesc($1, $2, $3, $4); }
278: | drawtype optname STRING optdesc { drawdesc($1, $2, $4, $3); }
279: ;
280: drawtype:
281: DRAW
282: | NEW
283: ;
284:
285: next:
286: NEXT optname AT point optdesc { next($2, $4, $5); }
287:
288: copy:
289: COPY copylist { copy(); }
290: ;
291: copylist:
292: copyattr
293: | copylist copyattr
294: ;
295: copyattr:
296: STRING { copyfile($1); }
297: | THRU DEFNAME { copydef($2); }
298: | UNTIL STRING { copyuntil($2); }
299: ;
300:
301: for:
302: FOR name FROM expr TO expr BY optop expr DOSTR
303: { forloop($2, $4, $6, $8, $9, $10); }
304: | FOR name FROM expr TO expr DOSTR
305: { forloop($2, $4, $6, '+', 1.0, $7); }
306: | FOR name '=' expr TO expr BY optop expr DOSTR
307: { forloop($2, $4, $6, $8, $9, $10); }
308: | FOR name '=' expr TO expr DOSTR
309: { forloop($2, $4, $6, '+', 1.0, $7); }
310: ;
311:
312: if:
313: IF if_expr THEN ELSE { $$ = ifstat($2, $3, $4); }
314: | IF if_expr THEN { $$ = ifstat($2, $3, (char *) 0); }
315: ;
316: if_expr:
317: expr
318: | STRING EQ STRING { $$ = strcmp($1,$3) == 0; free($1); free($3); }
319: | STRING NE STRING { $$ = strcmp($1,$3) != 0; free($1); free($3); }
320: ;
321:
322: point:
323: optname expr comma expr { $$ = makepoint($1, $2, $4); }
324: | optname '(' expr comma expr ')' { $$ = makepoint($1, $3, $5); }
325: ;
326: comma:
327: ',' { $$ = ','; }
328: ;
329:
330: optname:
331: NAME { $$ = $1; }
332: | /* empty */ { $$ = lookup(curr_coord, 1); }
333: ;
334:
335: expr:
336: NUMBER
337: | assign
338: | VARNAME { $$ = getvar($1); }
339: | expr '+' expr { $$ = $1 + $3; }
340: | expr '-' expr { $$ = $1 - $3; }
341: | expr '*' expr { $$ = $1 * $3; }
342: | expr '/' expr { if ($3 == 0.0) {
343: ERROR "division by 0" WARNING; $3 = 1; }
344: $$ = $1 / $3; }
345: | expr '%' expr { if ((long)$3 == 0) {
346: ERROR "mod division by 0" WARNING; $3 = 1; }
347: $$ = (long)$1 % (long)$3; }
348: | '-' expr %prec UMINUS { $$ = -$2; }
349: | '+' expr %prec UMINUS { $$ = $2; }
350: | '(' expr ')' { $$ = $2; }
351: | LOG '(' expr ')' { $$ = Log10($3); }
352: | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); }
353: | expr '^' expr { $$ = pow($1, $3); }
354: | SIN '(' expr ')' { $$ = sin($3); }
355: | COS '(' expr ')' { $$ = cos($3); }
356: | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); }
357: | SQRT '(' expr ')' { $$ = Sqrt($3); }
358: | RAND '(' ')' { $$ = (double)rand() / (double)RAND_MAX; }
359: | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; }
360: | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; }
361: | INT '(' expr ')' { $$ = (long) $3; }
362: | expr GT expr { $$ = $1 > $3; }
363: | expr LT expr { $$ = $1 < $3; }
364: | expr LE expr { $$ = $1 <= $3; }
365: | expr GE expr { $$ = $1 >= $3; }
366: | expr EQ expr { $$ = $1 == $3; }
367: | expr NE expr { $$ = $1 != $3; }
368: | expr AND expr { $$ = $1 && $3; }
369: | expr OR expr { $$ = $1 || $3; }
370: | NOT expr { $$ = !($2); }
371: ;
372: assign:
373: name '=' expr { $$ = setvar($1, $3); }
374: ;
375:
376: name:
377: NAME
378: | VARNAME
379: ;
380:
381: optexpr:
382: expr
383: | /* empty */ { $$ = 0.0; }
384: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.