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