|
|
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
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
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); }
153: | iterator { setlist(); ticklist($1); }
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: ;
218: sattrlist:
219: stringattr
220: | sattrlist stringattr
221: | /* empty */ { $$ = (Attr *) 0; }
222: ;
223: stringattr:
224: JUST { setjust($1); }
225: | SIZE optop expr { setsize($2, $3); }
226: ;
227:
228: coord:
229: COORD optname coordlist { coord($2); }
230: | COORD optname { resetcoord($2); }
231: ;
232: coordlist:
233: coorditem
234: | coordlist coorditem
235: ;
236: coorditem:
237: coordlog { coordlog($1); }
238: | X point { coord_x($2); }
239: | Y point { coord_y($2); }
240: | X optname expr TO expr { coord_x(makepoint($2, $3, $5)); }
241: | Y optname expr TO expr { coord_y(makepoint($2, $3, $5)); }
242: | X FROM optname expr TO expr { coord_x(makepoint($3, $4, $6)); }
243: | Y FROM optname expr TO expr { coord_y(makepoint($3, $4, $6)); }
244: ;
245: coordlog:
246: LOG X { $$ = XFLAG; }
247: | LOG Y { $$ = YFLAG; }
248: | LOG X LOG Y { $$ = XFLAG|YFLAG; }
249: | LOG Y LOG X { $$ = XFLAG|YFLAG; }
250: | LOG LOG { $$ = XFLAG|YFLAG; }
251: ;
252:
253: plot:
254: stringlist AT point { plot($1, $3); }
255: | PLOT stringlist AT point { plot($2, $4); }
256: | PLOT expr optstring AT point { plotnum($2, $3, $5); }
257: ;
258:
259: draw:
260: drawtype optname linedesc { drawdesc($1, $2, $3, (char *) 0); }
261: | drawtype optname optdesc STRING { drawdesc($1, $2, $3, $4); }
262: | drawtype optname STRING optdesc { drawdesc($1, $2, $4, $3); }
263: ;
264: drawtype:
265: DRAW
266: | NEW
267: ;
268:
269: next:
270: NEXT optname AT point optdesc { next($2, $4, $5); }
271:
272: copy:
273: COPY copylist { copy(); }
274: ;
275: copylist:
276: copyattr
277: | copylist copyattr
278: ;
279: copyattr:
280: STRING { copyfile($1); }
281: | THRU DEFNAME { copydef($2); }
282: | UNTIL STRING { copyuntil($2); }
283: ;
284:
285: for:
286: FOR name FROM expr TO expr BY optop expr DOSTR
287: { forloop($2, $4, $6, $8, $9, $10); }
288: | FOR name FROM expr TO expr DOSTR
289: { forloop($2, $4, $6, '+', 1.0, $7); }
290: | FOR name '=' expr TO expr BY optop expr DOSTR
291: { forloop($2, $4, $6, $8, $9, $10); }
292: | FOR name '=' expr TO expr DOSTR
293: { forloop($2, $4, $6, '+', 1.0, $7); }
294: ;
295:
296: if:
297: IF if_expr THEN ELSE { $$ = ifstat($2, $3, $4); }
298: | IF if_expr THEN { $$ = ifstat($2, $3, (char *) 0); }
299: ;
300: if_expr:
301: expr
302: | STRING EQ STRING { $$ = strcmp($1,$3) == 0; free($1); free($3); }
303: | STRING NE STRING { $$ = strcmp($1,$3) != 0; free($1); free($3); }
304: ;
305:
306: point:
307: optname expr comma expr { $$ = makepoint($1, $2, $4); }
308: | optname '(' expr comma expr ')' { $$ = makepoint($1, $3, $5); }
309: ;
310: comma:
311: ',' { $$ = ','; }
312: ;
313:
314: optname:
315: NAME { $$ = $1; }
316: | /* empty */ { $$ = lookup(curr_coord, 1); }
317: ;
318:
319: expr:
320: NUMBER
321: | assign
322: | VARNAME { $$ = getvar($1); }
323: | expr '+' expr { $$ = $1 + $3; }
324: | expr '-' expr { $$ = $1 - $3; }
325: | expr '*' expr { $$ = $1 * $3; }
326: | expr '/' expr { if ($3 == 0.0) {
327: yyerror("division by 0"); $3 = 1; }
328: $$ = $1 / $3; }
329: | '-' expr %prec UMINUS { $$ = -$2; }
330: | '+' expr %prec UMINUS { $$ = $2; }
331: | '(' expr ')' { $$ = $2; }
332: | LOG '(' expr ')' { $$ = Log10($3); }
333: | EXP '(' expr ')' { $$ = Exp($3 * log(10.0)); }
334: | SIN '(' expr ')' { $$ = sin($3); }
335: | COS '(' expr ')' { $$ = cos($3); }
336: | ATAN2 '(' expr ',' expr ')' { $$ = atan2($3, $5); }
337: | SQRT '(' expr ')' { $$ = Sqrt($3); }
338: | RAND '(' ')' { $$ = (float)rand() / 32767.0; }
339: | MAX '(' expr ',' expr ')' { $$ = $3 >= $5 ? $3 : $5; }
340: | MIN '(' expr ',' expr ')' { $$ = $3 <= $5 ? $3 : $5; }
341: | INT '(' expr ')' { $$ = (long) $3; }
342: | expr GT expr { $$ = $1 > $3; }
343: | expr LT expr { $$ = $1 < $3; }
344: | expr LE expr { $$ = $1 <= $3; }
345: | expr GE expr { $$ = $1 >= $3; }
346: | expr EQ expr { $$ = $1 == $3; }
347: | expr NE expr { $$ = $1 != $3; }
348: | expr AND expr { $$ = $1 && $3; }
349: | expr OR expr { $$ = $1 || $3; }
350: | NOT expr { $$ = !($2); }
351: ;
352: assign:
353: name '=' expr { $$ = setvar($1, $3); }
354: ;
355:
356: name:
357: NAME
358: | VARNAME
359: ;
360:
361: optexpr:
362: expr
363: | /* empty */ { $$ = 0.0; }
364: ;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.