Home | History | Annotate | Line # | Download | only in atc
grammar.y revision 1.5
      1 /*	$NetBSD: grammar.y,v 1.5 1999/07/21 13:10:47 hubertf Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1990, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * This code is derived from software contributed to Berkeley by
      8  * Ed James.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  * 3. All advertising materials mentioning features or use of this software
     19  *    must display the following acknowledgement:
     20  *	This product includes software developed by the University of
     21  *	California, Berkeley and its contributors.
     22  * 4. Neither the name of the University nor the names of its contributors
     23  *    may be used to endorse or promote products derived from this software
     24  *    without specific prior written permission.
     25  *
     26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     36  * SUCH DAMAGE.
     37  */
     38 
     39 /*
     40  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
     41  *
     42  * Copy permission is hereby granted provided that this notice is
     43  * retained on all partial or complete copies.
     44  *
     45  * For more info on this and all of my stuff, mail edjames (at) berkeley.edu.
     46  */
     47 
     48 %token <ival>	HeightOp
     49 %token <ival>	WidthOp
     50 %token <ival>	UpdateOp
     51 %token <ival>	NewplaneOp
     52 %token <cval>	DirOp
     53 %token <ival>	ConstOp
     54 %token <ival>	LineOp
     55 %token <ival>	AirportOp
     56 %token <ival>	BeaconOp
     57 %token <ival>	ExitOp
     58 %union {
     59 	int	ival;
     60 	char	cval;
     61 }
     62 
     63 %{
     64 #include "include.h"
     65 
     66 #include <sys/cdefs.h>
     67 #ifndef lint
     68 #if 0
     69 static char sccsid[] = "@(#)grammar.y	8.1 (Berkeley) 5/31/93";
     70 #else
     71 __RCSID("$NetBSD: grammar.y,v 1.5 1999/07/21 13:10:47 hubertf Exp $");
     72 #endif
     73 #endif /* not lint */
     74 
     75 int	errors = 0;
     76 int	line = 1;
     77 %}
     78 
     79 %%
     80 file:
     81 	bunch_of_defs { if (checkdefs() < 0) return (errors); } bunch_of_lines
     82 		{
     83 		if (sp->num_exits + sp->num_airports < 2)
     84 			yyerror("Need at least 2 airports and/or exits.");
     85 		return (errors);
     86 		}
     87 	;
     88 
     89 bunch_of_defs:
     90 	def bunch_of_defs
     91 	| def
     92 	;
     93 
     94 def:
     95 	udef
     96 	| ndef
     97 	| wdef
     98 	| hdef
     99 	;
    100 
    101 udef:
    102 	UpdateOp '=' ConstOp ';'
    103 		{
    104 		if (sp->update_secs != 0)
    105 			return (yyerror("Redefinition of 'update'."));
    106 		else if ($3 < 1)
    107 			return (yyerror("'update' is too small."));
    108 		else
    109 			sp->update_secs = $3;
    110 		}
    111 	;
    112 
    113 ndef:
    114 	NewplaneOp '=' ConstOp ';'
    115 		{
    116 		if (sp->newplane_time != 0)
    117 			return (yyerror("Redefinition of 'newplane'."));
    118 		else if ($3 < 1)
    119 			return (yyerror("'newplane' is too small."));
    120 		else
    121 			sp->newplane_time = $3;
    122 		}
    123 	;
    124 
    125 hdef:
    126 	HeightOp '=' ConstOp ';'
    127 		{
    128 		if (sp->height != 0)
    129 			return (yyerror("Redefinition of 'height'."));
    130 		else if ($3 < 3)
    131 			return (yyerror("'height' is too small."));
    132 		else
    133 			sp->height = $3;
    134 		}
    135 	;
    136 
    137 wdef:
    138 	WidthOp '=' ConstOp ';'
    139 		{
    140 		if (sp->width != 0)
    141 			return (yyerror("Redefinition of 'width'."));
    142 		else if ($3 < 3)
    143 			return (yyerror("'width' is too small."));
    144 		else
    145 			sp->width = $3;
    146 		}
    147 	;
    148 
    149 bunch_of_lines:
    150 	line bunch_of_lines
    151 		{}
    152 	| line
    153 		{}
    154 	;
    155 
    156 line:
    157 	BeaconOp ':' Bpoint_list ';'
    158 		{}
    159 	| ExitOp ':' Epoint_list ';'
    160 		{}
    161 	| LineOp ':' Lline_list ';'
    162 		{}
    163 	| AirportOp ':' Apoint_list ';'
    164 		{}
    165 	;
    166 
    167 Bpoint_list:
    168 	Bpoint Bpoint_list
    169 		{}
    170 	| Bpoint
    171 		{}
    172 	;
    173 
    174 Bpoint:
    175 	'(' ConstOp ConstOp ')'
    176 		{
    177 		if (sp->num_beacons % REALLOC == 0) {
    178 			if (sp->beacon == NULL)
    179 				sp->beacon = (BEACON *) malloc((sp->num_beacons
    180 					+ REALLOC) * sizeof (BEACON));
    181 			else
    182 				sp->beacon = (BEACON *) realloc(sp->beacon,
    183 					(sp->num_beacons + REALLOC) *
    184 					sizeof (BEACON));
    185 			if (sp->beacon == NULL)
    186 				return (yyerror("No memory available."));
    187 		}
    188 		sp->beacon[sp->num_beacons].x = $2;
    189 		sp->beacon[sp->num_beacons].y = $3;
    190 		check_point($2, $3);
    191 		sp->num_beacons++;
    192 		}
    193 	;
    194 
    195 Epoint_list:
    196 	Epoint Epoint_list
    197 		{}
    198 	| Epoint
    199 		{}
    200 	;
    201 
    202 Epoint:
    203 	'(' ConstOp ConstOp DirOp ')'
    204 		{
    205 		int	dir;
    206 
    207 		if (sp->num_exits % REALLOC == 0) {
    208 			if (sp->exit == NULL)
    209 				sp->exit = (EXIT *) malloc((sp->num_exits +
    210 					REALLOC) * sizeof (EXIT));
    211 			else
    212 				sp->exit = (EXIT *) realloc(sp->exit,
    213 					(sp->num_exits + REALLOC) *
    214 					sizeof (EXIT));
    215 			if (sp->exit == NULL)
    216 				return (yyerror("No memory available."));
    217 		}
    218 		dir = dir_no($4);
    219 		sp->exit[sp->num_exits].x = $2;
    220 		sp->exit[sp->num_exits].y = $3;
    221 		sp->exit[sp->num_exits].dir = dir;
    222 		check_edge($2, $3);
    223 		check_edir($2, $3, dir);
    224 		sp->num_exits++;
    225 		}
    226 	;
    227 
    228 Apoint_list:
    229 	Apoint Apoint_list
    230 		{}
    231 	| Apoint
    232 		{}
    233 	;
    234 
    235 Apoint:
    236 	'(' ConstOp ConstOp DirOp ')'
    237 		{
    238 		int	dir;
    239 
    240 		if (sp->num_airports % REALLOC == 0) {
    241 			if (sp->airport == NULL)
    242 				sp->airport=(AIRPORT *)malloc((sp->num_airports
    243 					+ REALLOC) * sizeof(AIRPORT));
    244 			else
    245 				sp->airport = (AIRPORT *) realloc(sp->airport,
    246 					(sp->num_airports + REALLOC) *
    247 					sizeof(AIRPORT));
    248 			if (sp->airport == NULL)
    249 				return (yyerror("No memory available."));
    250 		}
    251 		dir = dir_no($4);
    252 		sp->airport[sp->num_airports].x = $2;
    253 		sp->airport[sp->num_airports].y = $3;
    254 		sp->airport[sp->num_airports].dir = dir;
    255 		check_point($2, $3);
    256 		check_adir($2, $3, dir);
    257 		sp->num_airports++;
    258 		}
    259 	;
    260 
    261 Lline_list:
    262 	Lline Lline_list
    263 		{}
    264 	| Lline
    265 		{}
    266 	;
    267 
    268 Lline:
    269 	'[' '(' ConstOp ConstOp ')' '(' ConstOp ConstOp ')' ']'
    270 		{
    271 		if (sp->num_lines % REALLOC == 0) {
    272 			if (sp->line == NULL)
    273 				sp->line = (LINE *) malloc((sp->num_lines +
    274 					REALLOC) * sizeof (LINE));
    275 			else
    276 				sp->line = (LINE *) realloc(sp->line,
    277 					(sp->num_lines + REALLOC) *
    278 					sizeof (LINE));
    279 			if (sp->line == NULL)
    280 				return (yyerror("No memory available."));
    281 		}
    282 		sp->line[sp->num_lines].p1.x = $3;
    283 		sp->line[sp->num_lines].p1.y = $4;
    284 		sp->line[sp->num_lines].p2.x = $7;
    285 		sp->line[sp->num_lines].p2.y = $8;
    286 		check_line($3, $4, $7, $8);
    287 		sp->num_lines++;
    288 		}
    289 	;
    290 %%
    291 
    292 void
    293 check_edge(x, y)
    294 	int x, y;
    295 {
    296 	if (!(x == 0) && !(x == sp->width - 1) &&
    297 	    !(y == 0) && !(y == sp->height - 1))
    298 		yyerror("edge value not on edge.");
    299 }
    300 
    301 void
    302 check_point(x, y)
    303 	int x, y;
    304 {
    305 	if (x < 1 || x >= sp->width - 1)
    306 		yyerror("X value out of range.");
    307 	if (y < 1 || y >= sp->height - 1)
    308 		yyerror("Y value out of range.");
    309 }
    310 
    311 void
    312 check_linepoint(x, y)
    313 	int x, y;
    314 {
    315 	if (x < 0 || x >= sp->width)
    316 		yyerror("X value out of range.");
    317 	if (y < 0 || y >= sp->height)
    318 		yyerror("Y value out of range.");
    319 }
    320 
    321 void
    322 check_line(x1, y1, x2, y2)
    323 	int x1, y1, x2, y2;
    324 {
    325 	int	d1, d2;
    326 
    327 	check_linepoint(x1, y1);
    328 	check_linepoint(x2, y2);
    329 
    330 	d1 = ABS(x2 - x1);
    331 	d2 = ABS(y2 - y1);
    332 
    333 	if (!(d1 == d2) && !(d1 == 0) && !(d2 == 0))
    334 		yyerror("Bad line endpoints.");
    335 }
    336 
    337 int
    338 yyerror(s)
    339 	const char *s;
    340 {
    341 	fprintf(stderr, "\"%s\": line %d: %s\n", file, line, s);
    342 	errors++;
    343 
    344 	return (errors);
    345 }
    346 
    347 void
    348 check_edir(x, y, dir)
    349 	int x, y, dir;
    350 {
    351 	int	bad = 0;
    352 
    353 	if (x == sp->width - 1)
    354 		x = 2;
    355 	else if (x != 0)
    356 		x = 1;
    357 	if (y == sp->height - 1)
    358 		y = 2;
    359 	else if (y != 0)
    360 		y = 1;
    361 
    362 	switch (x * 10 + y) {
    363 	case 00: if (dir != 3) bad++; break;
    364 	case 01: if (dir < 1 || dir > 3) bad++; break;
    365 	case 02: if (dir != 1) bad++; break;
    366 	case 10: if (dir < 3 || dir > 5) bad++; break;
    367 	case 11: break;
    368 	case 12: if (dir > 1 && dir < 7) bad++; break;
    369 	case 20: if (dir != 5) bad++; break;
    370 	case 21: if (dir < 5) bad++; break;
    371 	case 22: if (dir != 7) bad++; break;
    372 	default:
    373 		yyerror("Unknown value in checkdir!  Get help!");
    374 		break;
    375 	}
    376 	if (bad)
    377 		yyerror("Bad direction for entrance at exit.");
    378 }
    379 
    380 void
    381 check_adir(x, y, dir)
    382 	int x, y, dir;
    383 {
    384 }
    385 
    386 int
    387 checkdefs()
    388 {
    389 	int	err = 0;
    390 
    391 	if (sp->width == 0) {
    392 		yyerror("'width' undefined.");
    393 		err++;
    394 	}
    395 	if (sp->height == 0) {
    396 		yyerror("'height' undefined.");
    397 		err++;
    398 	}
    399 	if (sp->update_secs == 0) {
    400 		yyerror("'update' undefined.");
    401 		err++;
    402 	}
    403 	if (sp->newplane_time == 0) {
    404 		yyerror("'newplane' undefined.");
    405 		err++;
    406 	}
    407 	if (err)
    408 		return (-1);
    409 	else
    410 		return (0);
    411 }
    412