From 77e3814f0c0e3dea4d0032e25666f77e6f83bfff Mon Sep 17 00:00:00 2001 From: cgd Date: Sun, 21 Mar 1993 09:45:37 +0000 Subject: initial import of 386bsd-0.1 sources --- atc/grammar.y | 389 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 atc/grammar.y (limited to 'atc/grammar.y') diff --git a/atc/grammar.y b/atc/grammar.y new file mode 100644 index 00000000..a59a3820 --- /dev/null +++ b/atc/grammar.y @@ -0,0 +1,389 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Ed James. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Copyright (c) 1987 by Ed James, UC Berkeley. All rights reserved. + * + * Copy permission is hereby granted provided that this notice is + * retained on all partial or complete copies. + * + * For more info on this and all of my stuff, mail edjames@berkeley.edu. + */ + +%token HeightOp +%token WidthOp +%token UpdateOp +%token NewplaneOp +%token DirOp +%token ConstOp +%token LineOp +%token AirportOp +%token BeaconOp +%token ExitOp +%union { + int ival; + char cval; +} + +%{ +#include "include.h" + +#ifndef lint +static char sccsid[] = "@(#)grammar.y 5.2 (Berkeley) 4/30/90"; +#endif /* not lint */ + +int errors = 0; +int line = 1; +%} + +%% +file: + bunch_of_defs { if (checkdefs() < 0) return (errors); } bunch_of_lines + { + if (sp->num_exits + sp->num_airports < 2) + yyerror("Need at least 2 airports and/or exits."); + return (errors); + } + ; + +bunch_of_defs: + def bunch_of_defs + | def + ; + +def: + udef + | ndef + | wdef + | hdef + ; + +udef: + UpdateOp '=' ConstOp ';' + { + if (sp->update_secs != 0) + return (yyerror("Redefinition of 'update'.")); + else if ($3 < 1) + return (yyerror("'update' is too small.")); + else + sp->update_secs = $3; + } + ; + +ndef: + NewplaneOp '=' ConstOp ';' + { + if (sp->newplane_time != 0) + return (yyerror("Redefinition of 'newplane'.")); + else if ($3 < 1) + return (yyerror("'newplane' is too small.")); + else + sp->newplane_time = $3; + } + ; + +hdef: + HeightOp '=' ConstOp ';' + { + if (sp->height != 0) + return (yyerror("Redefinition of 'height'.")); + else if ($3 < 3) + return (yyerror("'height' is too small.")); + else + sp->height = $3; + } + ; + +wdef: + WidthOp '=' ConstOp ';' + { + if (sp->height != 0) + return (yyerror("Redefinition of 'width'.")); + else if ($3 < 3) + return (yyerror("'width' is too small.")); + else + sp->width = $3; + } + ; + +bunch_of_lines: + line bunch_of_lines + {} + | line + {} + ; + +line: + BeaconOp ':' Bpoint_list ';' + {} + | ExitOp ':' Epoint_list ';' + {} + | LineOp ':' Lline_list ';' + {} + | AirportOp ':' Apoint_list ';' + {} + ; + +Bpoint_list: + Bpoint Bpoint_list + {} + | Bpoint + {} + ; + +Bpoint: + '(' ConstOp ConstOp ')' + { + if (sp->num_beacons % REALLOC == 0) { + if (sp->beacon == NULL) + sp->beacon = (BEACON *) malloc((sp->num_beacons + + REALLOC) * sizeof (BEACON)); + else + sp->beacon = (BEACON *) realloc(sp->beacon, + (sp->num_beacons + REALLOC) * + sizeof (BEACON)); + if (sp->beacon == NULL) + return (yyerror("No memory available.")); + } + sp->beacon[sp->num_beacons].x = $2; + sp->beacon[sp->num_beacons].y = $3; + check_point($2, $3); + sp->num_beacons++; + } + ; + +Epoint_list: + Epoint Epoint_list + {} + | Epoint + {} + ; + +Epoint: + '(' ConstOp ConstOp DirOp ')' + { + int dir; + + if (sp->num_exits % REALLOC == 0) { + if (sp->exit == NULL) + sp->exit = (EXIT *) malloc((sp->num_exits + + REALLOC) * sizeof (EXIT)); + else + sp->exit = (EXIT *) realloc(sp->exit, + (sp->num_exits + REALLOC) * + sizeof (EXIT)); + if (sp->exit == NULL) + return (yyerror("No memory available.")); + } + dir = dir_no($4); + sp->exit[sp->num_exits].x = $2; + sp->exit[sp->num_exits].y = $3; + sp->exit[sp->num_exits].dir = dir; + check_edge($2, $3); + check_edir($2, $3, dir); + sp->num_exits++; + } + ; + +Apoint_list: + Apoint Apoint_list + {} + | Apoint + {} + ; + +Apoint: + '(' ConstOp ConstOp DirOp ')' + { + int dir; + + if (sp->num_airports % REALLOC == 0) { + if (sp->airport == NULL) + sp->airport=(AIRPORT *)malloc((sp->num_airports + + REALLOC) * sizeof(AIRPORT)); + else + sp->airport = (AIRPORT *) realloc(sp->airport, + (sp->num_airports + REALLOC) * + sizeof(AIRPORT)); + if (sp->airport == NULL) + return (yyerror("No memory available.")); + } + dir = dir_no($4); + sp->airport[sp->num_airports].x = $2; + sp->airport[sp->num_airports].y = $3; + sp->airport[sp->num_airports].dir = dir; + check_point($2, $3); + check_adir($2, $3, dir); + sp->num_airports++; + } + ; + +Lline_list: + Lline Lline_list + {} + | Lline + {} + ; + +Lline: + '[' '(' ConstOp ConstOp ')' '(' ConstOp ConstOp ')' ']' + { + if (sp->num_lines % REALLOC == 0) { + if (sp->line == NULL) + sp->line = (LINE *) malloc((sp->num_lines + + REALLOC) * sizeof (LINE)); + else + sp->line = (LINE *) realloc(sp->line, + (sp->num_lines + REALLOC) * + sizeof (LINE)); + if (sp->line == NULL) + return (yyerror("No memory available.")); + } + sp->line[sp->num_lines].p1.x = $3; + sp->line[sp->num_lines].p1.y = $4; + sp->line[sp->num_lines].p2.x = $7; + sp->line[sp->num_lines].p2.y = $8; + check_line($3, $4, $7, $8); + sp->num_lines++; + } + ; +%% + +check_edge(x, y) +{ + if (!(x == 0) && !(x == sp->width - 1) && + !(y == 0) && !(y == sp->height - 1)) + yyerror("edge value not on edge."); +} + +check_point(x, y) +{ + if (x < 1 || x >= sp->width - 1) + yyerror("X value out of range."); + if (y < 1 || y >= sp->height - 1) + yyerror("Y value out of range."); +} + +check_linepoint(x, y) +{ + if (x < 0 || x >= sp->width) + yyerror("X value out of range."); + if (y < 0 || y >= sp->height) + yyerror("Y value out of range."); +} + +check_line(x1, y1, x2, y2) +{ + int d1, d2; + + check_linepoint(x1, y1); + check_linepoint(x2, y2); + + d1 = ABS(x2 - x1); + d2 = ABS(y2 - y1); + + if (!(d1 == d2) && !(d1 == 0) && !(d2 == 0)) + yyerror("Bad line endpoints."); +} + +yyerror(s) +{ + fprintf(stderr, "\"%s\": line %d: %s\n", file, line, s); + errors++; + + return (errors); +} + +check_edir(x, y, dir) +{ + int bad = 0; + + if (x == sp->width - 1) + x = 2; + else if (x != 0) + x = 1; + if (y == sp->height - 1) + y = 2; + else if (y != 0) + y = 1; + + switch (x * 10 + y) { + case 00: if (dir != 3) bad++; break; + case 01: if (dir < 1 || dir > 3) bad++; break; + case 02: if (dir != 1) bad++; break; + case 10: if (dir < 3 || dir > 5) bad++; break; + case 11: break; + case 12: if (dir > 1 && dir < 7) bad++; break; + case 20: if (dir != 5) bad++; break; + case 21: if (dir < 5) bad++; break; + case 22: if (dir != 7) bad++; break; + default: + yyerror("Unknown value in checkdir! Get help!"); + break; + } + if (bad) + yyerror("Bad direction for entrance at exit."); +} + +check_adir(x, y, dir) +{ +} + +checkdefs() +{ + int err = 0; + + if (sp->width == 0) { + yyerror("'width' undefined."); + err++; + } + if (sp->height == 0) { + yyerror("'height' undefined."); + err++; + } + if (sp->update_secs == 0) { + yyerror("'update' undefined."); + err++; + } + if (sp->newplane_time == 0) { + yyerror("'newplane' undefined."); + err++; + } + if (err) + return (-1); + else + return (0); +} -- cgit v1.2.3-56-ge451