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