1: /*
2: * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved.
3: *
4: * Copy permission is hereby granted provided that this notice is
5: * retained on all partial or complete copies.
6: *
7: * For more info on this and all of my stuff, mail edjames@berkeley.edu.
8: */
9:
10: %token <ival> HeightOp
11: %token <ival> WidthOp
12: %token <ival> UpdateOp
13: %token <ival> NewplaneOp
14: %token <cval> DirOp
15: %token <ival> ConstOp
16: %token <ival> LineOp
17: %token <ival> AirportOp
18: %token <ival> BeaconOp
19: %token <ival> ExitOp
20: %union {
21: int ival;
22: char cval;
23: }
24:
25: %{
26: #include "include.h"
27:
28: int errors = 0;
29: int line = 1;
30: %}
31:
32: %%
33: file:
34: bunch_of_defs { if (checkdefs() < 0) return (errors); } bunch_of_lines
35: {
36: if (sp->num_exits + sp->num_airports < 2)
37: yyerror("Need at least 2 airports and/or exits.");
38: return (errors);
39: }
40: ;
41:
42: bunch_of_defs:
43: def bunch_of_defs
44: | def
45: ;
46:
47: def:
48: udef
49: | ndef
50: | wdef
51: | hdef
52: ;
53:
54: udef:
55: UpdateOp '=' ConstOp ';'
56: {
57: if (sp->update_secs != 0)
58: return (yyerror("Redefinition of 'update'."));
59: else if ($3 < 1)
60: return (yyerror("'update' is too small."));
61: else
62: sp->update_secs = $3;
63: }
64: ;
65:
66: ndef:
67: NewplaneOp '=' ConstOp ';'
68: {
69: if (sp->newplane_time != 0)
70: return (yyerror("Redefinition of 'newplane'."));
71: else if ($3 < 1)
72: return (yyerror("'newplane' is too small."));
73: else
74: sp->newplane_time = $3;
75: }
76: ;
77:
78: hdef:
79: HeightOp '=' ConstOp ';'
80: {
81: if (sp->height != 0)
82: return (yyerror("Redefinition of 'height'."));
83: else if ($3 < 3)
84: return (yyerror("'height' is too small."));
85: else
86: sp->height = $3;
87: }
88: ;
89:
90: wdef:
91: WidthOp '=' ConstOp ';'
92: {
93: if (sp->height != 0)
94: return (yyerror("Redefinition of 'width'."));
95: else if ($3 < 3)
96: return (yyerror("'width' is too small."));
97: else
98: sp->width = $3;
99: }
100: ;
101:
102: bunch_of_lines:
103: line bunch_of_lines
104: {}
105: | line
106: {}
107: ;
108:
109: line:
110: BeaconOp ':' Bpoint_list ';'
111: {}
112: | ExitOp ':' Epoint_list ';'
113: {}
114: | LineOp ':' Lline_list ';'
115: {}
116: | AirportOp ':' Apoint_list ';'
117: {}
118: ;
119:
120: Bpoint_list:
121: Bpoint Bpoint_list
122: {}
123: | Bpoint
124: {}
125: ;
126:
127: Bpoint:
128: '(' ConstOp ConstOp ')'
129: {
130: if (sp->num_beacons % REALLOC == 0) {
131: if (sp->beacon == NULL)
132: sp->beacon = (BEACON *) malloc((sp->num_beacons
133: + REALLOC) * sizeof (BEACON));
134: else
135: sp->beacon = (BEACON *) realloc(sp->beacon,
136: (sp->num_beacons + REALLOC) *
137: sizeof (BEACON));
138: if (sp->beacon == NULL)
139: return (yyerror("No memory available."));
140: }
141: sp->beacon[sp->num_beacons].x = $2;
142: sp->beacon[sp->num_beacons].y = $3;
143: check_point($2, $3);
144: sp->num_beacons++;
145: }
146: ;
147:
148: Epoint_list:
149: Epoint Epoint_list
150: {}
151: | Epoint
152: {}
153: ;
154:
155: Epoint:
156: '(' ConstOp ConstOp DirOp ')'
157: {
158: int dir;
159:
160: if (sp->num_exits % REALLOC == 0) {
161: if (sp->exit == NULL)
162: sp->exit = (EXIT *) malloc((sp->num_exits +
163: REALLOC) * sizeof (EXIT));
164: else
165: sp->exit = (EXIT *) realloc(sp->exit,
166: (sp->num_exits + REALLOC) *
167: sizeof (EXIT));
168: if (sp->exit == NULL)
169: return (yyerror("No memory available."));
170: }
171: dir = dir_no($4);
172: sp->exit[sp->num_exits].x = $2;
173: sp->exit[sp->num_exits].y = $3;
174: sp->exit[sp->num_exits].dir = dir;
175: check_edge($2, $3);
176: check_edir($2, $3, dir);
177: sp->num_exits++;
178: }
179: ;
180:
181: Apoint_list:
182: Apoint Apoint_list
183: {}
184: | Apoint
185: {}
186: ;
187:
188: Apoint:
189: '(' ConstOp ConstOp DirOp ')'
190: {
191: int dir;
192:
193: if (sp->num_airports % REALLOC == 0) {
194: if (sp->airport == NULL)
195: sp->airport=(AIRPORT *)malloc((sp->num_airports
196: + REALLOC) * sizeof(AIRPORT));
197: else
198: sp->airport = (AIRPORT *) realloc(sp->airport,
199: (sp->num_airports + REALLOC) *
200: sizeof(AIRPORT));
201: if (sp->airport == NULL)
202: return (yyerror("No memory available."));
203: }
204: dir = dir_no($4);
205: sp->airport[sp->num_airports].x = $2;
206: sp->airport[sp->num_airports].y = $3;
207: sp->airport[sp->num_airports].dir = dir;
208: check_point($2, $3);
209: check_adir($2, $3, dir);
210: sp->num_airports++;
211: }
212: ;
213:
214: Lline_list:
215: Lline Lline_list
216: {}
217: | Lline
218: {}
219: ;
220:
221: Lline:
222: '[' '(' ConstOp ConstOp ')' '(' ConstOp ConstOp ')' ']'
223: {
224: if (sp->num_lines % REALLOC == 0) {
225: if (sp->line == NULL)
226: sp->line = (LINE *) malloc((sp->num_lines +
227: REALLOC) * sizeof (LINE));
228: else
229: sp->line = (LINE *) realloc(sp->line,
230: (sp->num_lines + REALLOC) *
231: sizeof (LINE));
232: if (sp->line == NULL)
233: return (yyerror("No memory available."));
234: }
235: sp->line[sp->num_lines].p1.x = $3;
236: sp->line[sp->num_lines].p1.y = $4;
237: sp->line[sp->num_lines].p2.x = $7;
238: sp->line[sp->num_lines].p2.y = $8;
239: check_line($3, $4, $7, $8);
240: sp->num_lines++;
241: }
242: ;
243: %%
244:
245: check_edge(x, y)
246: {
247: if (!(x == 0) && !(x == sp->width - 1) &&
248: !(y == 0) && !(y == sp->height - 1))
249: yyerror("edge value not on edge.");
250: }
251:
252: check_point(x, y)
253: {
254: if (x < 1 || x >= sp->width - 1)
255: yyerror("X value out of range.");
256: if (y < 1 || y >= sp->height - 1)
257: yyerror("Y value out of range.");
258: }
259:
260: check_linepoint(x, y)
261: {
262: if (x < 0 || x >= sp->width)
263: yyerror("X value out of range.");
264: if (y < 0 || y >= sp->height)
265: yyerror("Y value out of range.");
266: }
267:
268: check_line(x1, y1, x2, y2)
269: {
270: int d1, d2;
271:
272: check_linepoint(x1, y1);
273: check_linepoint(x2, y2);
274:
275: d1 = ABS(x2 - x1);
276: d2 = ABS(y2 - y1);
277:
278: if (!(d1 == d2) && !(d1 == 0) && !(d2 == 0))
279: yyerror("Bad line endpoints.");
280: }
281:
282: yyerror(s)
283: {
284: fprintf(stderr, "\"%s\": line %d: %s\n", file, line, s);
285: errors++;
286:
287: return (errors);
288: }
289:
290: check_edir(x, y, dir)
291: {
292: int bad = 0;
293:
294: if (x == sp->width - 1)
295: x = 2;
296: else if (x != 0)
297: x = 1;
298: if (y == sp->height - 1)
299: y = 2;
300: else if (y != 0)
301: y = 1;
302:
303: switch (x * 10 + y) {
304: case 00: if (dir != 3) bad++; break;
305: case 01: if (dir < 1 || dir > 3) bad++; break;
306: case 02: if (dir != 1) bad++; break;
307: case 10: if (dir < 3 || dir > 5) bad++; break;
308: case 11: break;
309: case 12: if (dir > 1 && dir < 7) bad++; break;
310: case 20: if (dir != 5) bad++; break;
311: case 21: if (dir < 5) bad++; break;
312: case 22: if (dir != 7) bad++; break;
313: default:
314: yyerror("Unknown value in checkdir! Get help!");
315: break;
316: }
317: if (bad)
318: yyerror("Bad direction for entrance at exit.");
319: }
320:
321: check_adir(x, y, dir)
322: {
323: }
324:
325: checkdefs()
326: {
327: int err = 0;
328:
329: if (sp->width == 0) {
330: yyerror("'width' undefined.");
331: err++;
332: }
333: if (sp->height == 0) {
334: yyerror("'height' undefined.");
335: err++;
336: }
337: if (sp->update_secs == 0) {
338: yyerror("'update' undefined.");
339: err++;
340: }
341: if (sp->newplane_time == 0) {
342: yyerror("'newplane' undefined.");
343: err++;
344: }
345: if (err)
346: return (-1);
347: else
348: return (0);
349: }
Defined functions
_yyerror
defined in line
282; used 25 times
- in line 37,
58-60(2),
70-72(2),
82-84(2),
94-96(2),
139,
169,
202,
233,
249,
255-257(2),
263-265(2),
279,
314-318(2),
330-342(4)