1 #ifndef lint
2 static char yysccsid[] = "@(#)yaccpar	1.9 (Berkeley) 02/21/93";
3 #endif
4 #define YYBYACC 1
5 #define YYMAJOR 1
6 #define YYMINOR 9
7 #define yyclearin (yychar=(-1))
8 #define yyerrok (yyerrflag=0)
9 #define YYRECOVERING (yyerrflag!=0)
10 #define YYPREFIX "yy"
11 /*	SCCS Id: @(#)dgn_comp.c	3.3	96/06/22	*/
12 /*	Copyright (c) 1989 by Jean-Christophe Collet */
13 /*	Copyright (c) 1990 by M. Stephenson				  */
14 /* NetHack may be freely redistributed.  See license for details. */
15 
16 /*
17  * This file contains the Dungeon Compiler code
18  */
19 
20 /* In case we're using bison in AIX.  This definition must be
21  * placed before any other C-language construct in the file
22  * excluding comments and preprocessor directives (thanks IBM
23  * for this wonderful feature...).
24  *
25  * Note: some cpps barf on this 'undefined control' (#pragma).
26  * Addition of the leading space seems to prevent barfage for now,
27  * and AIX will still see the directive in its non-standard locale.
28  */
29 
30 #ifdef _AIX
31  #pragma alloca		/* keep leading space! */
32 #endif
33 
34 #include "config.h"
35 #include "date.h"
36 #include "dgn_file.h"
37 
38 void FDECL(yyerror, (const char *));
39 void FDECL(yywarning, (const char *));
40 int NDECL(yylex);
41 int NDECL(yyparse);
42 int FDECL(getchain, (char *));
43 int NDECL(check_dungeon);
44 int NDECL(check_branch);
45 int NDECL(check_level);
46 void NDECL(init_dungeon);
47 void NDECL(init_branch);
48 void NDECL(init_level);
49 void NDECL(output_dgn);
50 
51 #define Free(ptr)		free((genericptr_t)ptr)
52 
53 #ifdef AMIGA
54 # undef	printf
55 #ifndef	LATTICE
56 # define    memset(addr,val,len)    setmem(addr,len,val)
57 #endif
58 #endif
59 
60 #define ERR		(-1)
61 
62 static struct couple couple;
63 static struct tmpdungeon tmpdungeon[MAXDUNGEON];
64 static struct tmplevel tmplevel[LEV_LIMIT];
65 static struct tmpbranch tmpbranch[BRANCH_LIMIT];
66 
67 static int in_dungeon = 0, n_dgns = -1, n_levs = -1, n_brs = -1;
68 
69 extern int fatal_error;
70 extern const char *fname;
71 extern FILE *yyin, *yyout;	/* from dgn_lex.c */
72 
73 typedef union
74 {
75 	int	i;
76 	char*	str;
77 } YYSTYPE;
78 #define INTEGER 257
79 #define A_DUNGEON 258
80 #define BRANCH 259
81 #define CHBRANCH 260
82 #define LEVEL 261
83 #define RNDLEVEL 262
84 #define CHLEVEL 263
85 #define RNDCHLEVEL 264
86 #define UP_OR_DOWN 265
87 #define PROTOFILE 266
88 #define DESCRIPTION 267
89 #define DESCRIPTOR 268
90 #define LEVELDESC 269
91 #define ALIGNMENT 270
92 #define LEVALIGN 271
93 #define ENTRY 272
94 #define STAIR 273
95 #define NO_UP 274
96 #define NO_DOWN 275
97 #define PORTAL 276
98 #define STRING 277
99 #define YYERRCODE 256
100 short yylhs[] = {                                        -1,
101     0,    0,    5,    5,    6,    6,    6,    6,    7,    1,
102     1,    8,    8,    8,   12,   13,   15,   15,   14,   10,
103    10,   10,   10,   10,   16,   16,   17,   17,   18,   18,
104    19,   19,   20,   20,    9,    9,   22,   23,    3,    3,
105     3,    3,    3,    2,    2,    4,   21,   11,
106 };
107 short yylen[] = {                                         2,
108     0,    1,    1,    2,    1,    1,    1,    1,    6,    0,
109     1,    1,    1,    1,    3,    1,    3,    3,    3,    1,
110     1,    1,    1,    1,    6,    7,    7,    8,    3,    3,
111     7,    8,    8,    9,    1,    1,    7,    8,    0,    1,
112     1,    1,    1,    0,    1,    1,    5,    5,
113 };
114 short yydefred[] = {                                      0,
115     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
116     0,    0,    0,    0,    0,    3,    5,    6,    7,    8,
117    12,   13,   14,   16,   20,   21,   22,   23,   24,   35,
118    36,    0,    0,    0,    0,    0,    0,    0,    0,    0,
119     0,    0,    0,    0,    4,    0,    0,    0,    0,    0,
120     0,    0,   19,   17,   29,   18,   30,   15,   46,    0,
121     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
122     0,    0,    0,    0,    0,    0,   11,    9,    0,   40,
123    41,   42,   43,    0,    0,    0,    0,    0,    0,    0,
124     0,   45,   37,    0,   27,    0,    0,    0,    0,    0,
125    38,   28,   33,    0,   48,   47,   34,
126 };
127 short yydgoto[] = {                                      14,
128    78,   93,   84,   60,   15,   16,   17,   18,   19,   20,
129    68,   21,   22,   23,   24,   25,   26,   27,   28,   29,
130    70,   30,   31,
131 };
132 short yysindex[] = {                                   -237,
133   -46,  -45,  -44,  -39,  -38,  -30,  -22,  -21,  -20,  -19,
134   -18,  -17,  -16,    0, -237,    0,    0,    0,    0,    0,
135     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
136     0, -262, -234, -233, -232, -230, -229, -228, -227, -217,
137  -216, -215, -214, -202,    0, -221,   -7, -219, -221, -221,
138  -221, -221,    0,    0,    0,    0,    0,    0,    0,   19,
139    20,   21,   -2,   -1, -212, -211, -190, -189, -188, -271,
140    19,   20,   20,   27,   28,   29,    0,    0,   30,    0,
141     0,    0,    0, -193, -271, -182, -180,   19,   19, -179,
142  -178,    0,    0, -193,    0, -177, -176, -175,   42,   43,
143     0,    0,    0, -172,    0,    0,    0,
144 };
145 short yyrindex[] = {                                     86,
146     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
147     0,    0,    0,    0,   87,    0,    0,    0,    0,    0,
148     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
149     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
150     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
151     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
152     0,    0,    0,    0,    0,    0,    0,   16,    0,    1,
153     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
154     0,    0,    0,   31,    1,   46,    0,    0,    0,    0,
155     0,    0,    0,   31,    0,   61,   76,    0,    0,    0,
156     0,    0,    0,   91,    0,    0,    0,
157 };
158 short yygindex[] = {                                      0,
159     0,   -6,    4,  -43,    0,   75,    0,    0,    0,    0,
160   -71,    0,    0,    0,    0,    0,    0,    0,    0,    0,
161   -62,    0,    0,
162 };
163 #define YYTABLESIZE 363
164 short yytable[] = {                                      85,
165    39,   80,   81,   82,   83,   63,   64,   65,   66,   86,
166    87,   32,   33,   34,   46,   10,   97,   98,   35,   36,
167     1,    2,    3,    4,    5,    6,    7,   37,    8,    9,
168    44,   10,   11,   12,   13,   38,   39,   40,   41,   42,
169    43,   44,   47,   48,   49,   25,   50,   51,   52,   53,
170    54,   55,   56,   57,   58,   59,   61,   62,   67,   69,
171    26,   72,   73,   71,   74,   75,   76,   77,   79,   88,
172    89,   92,   90,   91,   95,   31,   96,   99,  100,  102,
173   103,  104,  105,  106,  107,    1,    2,  101,   94,   45,
174    32,    0,    0,    0,    0,    0,    0,    0,    0,    0,
175     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
176     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
177     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
178     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
179     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
180     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
181     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
182     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
183     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
184     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
185     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
186     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
187     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
188     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
189     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
190     0,    0,    0,    0,    0,    0,    0,    0,   39,   39,
191    39,   39,   39,   39,   39,   39,   39,   39,    0,   39,
192    39,   39,   39,   10,   10,   10,   10,   10,   10,   10,
193     0,   10,   10,    0,   10,   10,   10,   10,   44,   44,
194    44,   44,   44,   44,   44,    0,   44,   44,    0,   44,
195    44,   44,   44,   25,   25,   25,   25,   25,   25,   25,
196     0,   25,   25,    0,   25,   25,   25,   25,   26,   26,
197    26,   26,   26,   26,   26,    0,   26,   26,    0,   26,
198    26,   26,   26,   31,   31,   31,   31,   31,   31,   31,
199     0,   31,   31,    0,   31,   31,   31,   31,   32,   32,
200    32,   32,   32,   32,   32,    0,   32,   32,    0,   32,
201    32,   32,   32,
202 };
203 short yycheck[] = {                                      71,
204     0,  273,  274,  275,  276,   49,   50,   51,   52,   72,
205    73,   58,   58,   58,  277,    0,   88,   89,   58,   58,
206   258,  259,  260,  261,  262,  263,  264,   58,  266,  267,
207     0,  269,  270,  271,  272,   58,   58,   58,   58,   58,
208    58,   58,  277,  277,  277,    0,  277,  277,  277,  277,
209   268,  268,  268,  268,  257,  277,   64,  277,   40,   40,
210     0,   64,   64,   43,  277,  277,  257,  257,  257,   43,
211    43,  265,   44,   44,  257,    0,  257,  257,  257,  257,
212   257,  257,   41,   41,  257,    0,    0,   94,   85,   15,
213     0,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
214    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
215    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
216    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
217    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
218    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
219    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
220    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
221    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
222    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
223    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
224    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
225    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
226    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
227    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
228    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
229    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,  259,
230   260,  261,  262,  263,  264,  265,  266,  267,   -1,  269,
231   270,  271,  272,  258,  259,  260,  261,  262,  263,  264,
232    -1,  266,  267,   -1,  269,  270,  271,  272,  258,  259,
233   260,  261,  262,  263,  264,   -1,  266,  267,   -1,  269,
234   270,  271,  272,  258,  259,  260,  261,  262,  263,  264,
235    -1,  266,  267,   -1,  269,  270,  271,  272,  258,  259,
236   260,  261,  262,  263,  264,   -1,  266,  267,   -1,  269,
237   270,  271,  272,  258,  259,  260,  261,  262,  263,  264,
238    -1,  266,  267,   -1,  269,  270,  271,  272,  258,  259,
239   260,  261,  262,  263,  264,   -1,  266,  267,   -1,  269,
240   270,  271,  272,
241 };
242 #define YYFINAL 14
243 #ifndef YYDEBUG
244 #define YYDEBUG 0
245 #endif
246 #define YYMAXTOKEN 277
247 #if YYDEBUG
248 char *yyname[] = {
249 "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
250 0,0,0,0,0,0,"'('","')'",0,"'+'","','",0,0,0,0,0,0,0,0,0,0,0,0,0,"':'",0,0,0,0,0,
251 "'@'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
252 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
253 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
254 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
255 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"INTEGER",
256 "A_DUNGEON","BRANCH","CHBRANCH","LEVEL","RNDLEVEL","CHLEVEL","RNDCHLEVEL",
257 "UP_OR_DOWN","PROTOFILE","DESCRIPTION","DESCRIPTOR","LEVELDESC","ALIGNMENT",
258 "LEVALIGN","ENTRY","STAIR","NO_UP","NO_DOWN","PORTAL","STRING",
259 };
260 char *yyrule[] = {
261 "$accept : file",
262 "file :",
263 "file : dungeons",
264 "dungeons : dungeon",
265 "dungeons : dungeons dungeon",
266 "dungeon : dungeonline",
267 "dungeon : dungeondesc",
268 "dungeon : branches",
269 "dungeon : levels",
270 "dungeonline : A_DUNGEON ':' STRING bones_tag rcouple optional_int",
271 "optional_int :",
272 "optional_int : INTEGER",
273 "dungeondesc : entry",
274 "dungeondesc : descriptions",
275 "dungeondesc : prototype",
276 "entry : ENTRY ':' INTEGER",
277 "descriptions : desc",
278 "desc : DESCRIPTION ':' DESCRIPTOR",
279 "desc : ALIGNMENT ':' DESCRIPTOR",
280 "prototype : PROTOFILE ':' STRING",
281 "levels : level1",
282 "levels : level2",
283 "levels : levdesc",
284 "levels : chlevel1",
285 "levels : chlevel2",
286 "level1 : LEVEL ':' STRING bones_tag '@' acouple",
287 "level1 : RNDLEVEL ':' STRING bones_tag '@' acouple INTEGER",
288 "level2 : LEVEL ':' STRING bones_tag '@' acouple INTEGER",
289 "level2 : RNDLEVEL ':' STRING bones_tag '@' acouple INTEGER INTEGER",
290 "levdesc : LEVELDESC ':' DESCRIPTOR",
291 "levdesc : LEVALIGN ':' DESCRIPTOR",
292 "chlevel1 : CHLEVEL ':' STRING bones_tag STRING '+' rcouple",
293 "chlevel1 : RNDCHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER",
294 "chlevel2 : CHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER",
295 "chlevel2 : RNDCHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER INTEGER",
296 "branches : branch",
297 "branches : chbranch",
298 "branch : BRANCH ':' STRING '@' acouple branch_type direction",
299 "chbranch : CHBRANCH ':' STRING STRING '+' rcouple branch_type direction",
300 "branch_type :",
301 "branch_type : STAIR",
302 "branch_type : NO_UP",
303 "branch_type : NO_DOWN",
304 "branch_type : PORTAL",
305 "direction :",
306 "direction : UP_OR_DOWN",
307 "bones_tag : STRING",
308 "acouple : '(' INTEGER ',' INTEGER ')'",
309 "rcouple : '(' INTEGER ',' INTEGER ')'",
310 };
311 #endif
312 #ifdef YYSTACKSIZE
313 #undef YYMAXDEPTH
314 #define YYMAXDEPTH YYSTACKSIZE
315 #else
316 #ifdef YYMAXDEPTH
317 #define YYSTACKSIZE YYMAXDEPTH
318 #else
319 #define YYSTACKSIZE 500
320 #define YYMAXDEPTH 500
321 #endif
322 #endif
323 int yydebug;
324 int yynerrs;
325 int yyerrflag;
326 int yychar;
327 short *yyssp;
328 YYSTYPE *yyvsp;
329 YYSTYPE yyval;
330 YYSTYPE yylval;
331 short yyss[YYSTACKSIZE];
332 YYSTYPE yyvs[YYSTACKSIZE];
333 #define yystacksize YYSTACKSIZE
334 
335 void
init_dungeon()336 init_dungeon()
337 {
338 	if(++n_dgns > MAXDUNGEON) {
339 	    (void) fprintf(stderr, "FATAL - Too many dungeons (limit: %d).\n",
340 		    MAXDUNGEON);
341 	    (void) fprintf(stderr, "To increase the limit edit MAXDUNGEON in global.h\n");
342 	    exit(EXIT_FAILURE);
343 	}
344 
345 	in_dungeon = 1;
346 	tmpdungeon[n_dgns].lev.base = 0;
347 	tmpdungeon[n_dgns].lev.rand = 0;
348 	tmpdungeon[n_dgns].chance = 100;
349 	Strcpy(tmpdungeon[n_dgns].name, "");
350 	Strcpy(tmpdungeon[n_dgns].protoname, "");
351 	tmpdungeon[n_dgns].flags = 0;
352 	tmpdungeon[n_dgns].levels = 0;
353 	tmpdungeon[n_dgns].branches = 0;
354 	tmpdungeon[n_dgns].entry_lev = 0;
355 }
356 
357 void
init_level()358 init_level()
359 {
360 	if(++n_levs > LEV_LIMIT) {
361 
362 		yyerror("FATAL - Too many special levels defined.");
363 		exit(EXIT_FAILURE);
364 	}
365 	tmplevel[n_levs].lev.base = 0;
366 	tmplevel[n_levs].lev.rand = 0;
367 	tmplevel[n_levs].chance = 100;
368 	tmplevel[n_levs].rndlevs = 0;
369 	tmplevel[n_levs].flags = 0;
370 	Strcpy(tmplevel[n_levs].name, "");
371 	tmplevel[n_levs].chain = -1;
372 }
373 
374 void
init_branch()375 init_branch()
376 {
377 	if(++n_brs > BRANCH_LIMIT) {
378 
379 		yyerror("FATAL - Too many special levels defined.");
380 		exit(EXIT_FAILURE);
381 	}
382 	tmpbranch[n_brs].lev.base = 0;
383 	tmpbranch[n_brs].lev.rand = 0;
384 	Strcpy(tmpbranch[n_brs].name, "");
385 	tmpbranch[n_brs].chain = -1;
386 }
387 
388 int
getchain(s)389 getchain(s)
390 	char	*s;
391 {
392 	int i;
393 
394 	if(strlen(s)) {
395 
396 	    for(i = n_levs - tmpdungeon[n_dgns].levels + 1; i <= n_levs; i++)
397 		if(!strcmp(tmplevel[i].name, s)) return i;
398 
399 	    yyerror("Can't locate the specified chain level.");
400 	    return(-2);
401 	}
402 	return(-1);
403 }
404 
405 /*
406  *	Consistancy checking routines:
407  *
408  *	- A dungeon must have a unique name.
409  *	- A dungeon must have a originating "branch" command
410  *	  (except, of course, for the first dungeon).
411  *	- A dungeon must have a proper depth (at least (1, 0)).
412  */
413 
414 int
check_dungeon()415 check_dungeon()
416 {
417 	int i;
418 
419 	for(i = 0; i < n_dgns; i++)
420 	    if(!strcmp(tmpdungeon[i].name, tmpdungeon[n_dgns].name)) {
421 		yyerror("Duplicate dungeon name.");
422 		return(0);
423 	    }
424 
425 	if(n_dgns)
426 	  for(i = 0; i < n_brs - tmpdungeon[n_dgns].branches; i++) {
427 	    if(!strcmp(tmpbranch[i].name, tmpdungeon[n_dgns].name)) break;
428 
429 	    if(i >= n_brs - tmpdungeon[n_dgns].branches) {
430 		yyerror("Dungeon cannot be reached.");
431 		return(0);
432 	    }
433 	  }
434 
435 	if(tmpdungeon[n_dgns].lev.base <= 0 ||
436 	   tmpdungeon[n_dgns].lev.rand < 0) {
437 		yyerror("Invalid dungeon depth specified.");
438 		return(0);
439 	}
440 	return(1);	/* OK */
441 }
442 
443 /*
444  *	- A level must have a unique level name.
445  *	- If chained, the level used as reference for the chain
446  *	  must be in this dungeon, must be previously defined, and
447  *	  the level chained from must be "non-probabilistic" (ie.
448  *	  have a 100% chance of existing).
449  */
450 
451 int
check_level()452 check_level()
453 {
454 	int i;
455 
456 	if(!in_dungeon) {
457 		yyerror("Level defined outside of dungeon.");
458 		return(0);
459 	}
460 
461 	for(i = 0; i < n_levs; i++)
462 	    if(!strcmp(tmplevel[i].name, tmplevel[n_levs].name)) {
463 		yyerror("Duplicate level name.");
464 		return(0);
465 	    }
466 
467 	if(tmplevel[i].chain == -2) {
468 		yyerror("Invaild level chain reference.");
469 		return(0);
470 	} else if(tmplevel[i].chain != -1) {	/* there is a chain */
471 	    /* KMH -- tmplevel[tmpbranch[i].chain].chance was in error */
472 	    if(tmplevel[tmplevel[i].chain].chance != 100) {
473 		yyerror("Level cannot chain from a probabilistic level.");
474 		return(0);
475 	    } else if(tmplevel[i].chain == n_levs) {
476 		yyerror("A level cannot chain to itself!");
477 		return(0);
478 	    }
479 	}
480 	return(1);	/* OK */
481 }
482 
483 /*
484  *	- A branch may not branch backwards - to avoid branch loops.
485  *	- A branch name must be unique.
486  *	  (ie. You can only have one entry point to each dungeon).
487  *	- If chained, the level used as reference for the chain
488  *	  must be in this dungeon, must be previously defined, and
489  *	  the level chained from must be "non-probabilistic" (ie.
490  *	  have a 100% chance of existing).
491  */
492 
493 int
check_branch()494 check_branch()
495 {
496 	int i;
497 
498 	if(!in_dungeon) {
499 		yyerror("Branch defined outside of dungeon.");
500 		return(0);
501 	}
502 
503 	for(i = 0; i < n_dgns; i++)
504 	    if(!strcmp(tmpdungeon[i].name, tmpbranch[n_brs].name)) {
505 
506 		yyerror("Reverse branching not allowed.");
507 		return(0);
508 	    }
509 
510 	if(tmpbranch[i].chain == -2) {
511 
512 		yyerror("Invaild branch chain reference.");
513 		return(0);
514 	} else if(tmpbranch[i].chain != -1) {	/* it is chained */
515 
516 	    if(tmplevel[tmpbranch[i].chain].chance != 100) {
517 		yyerror("Branch cannot chain from a probabilistic level.");
518 		return(0);
519 	    }
520 	}
521 	return(1);	/* OK */
522 }
523 
524 /*
525  *	Output the dungon definition into a file.
526  *
527  *	The file will have the following format:
528  *
529  *	[ nethack version ID ]
530  *	[ number of dungeons ]
531  *	[ first dungeon struct ]
532  *	[ levels for the first dungeon ]
533  *	  ...
534  *	[ branches for the first dungeon ]
535  *	  ...
536  *	[ second dungeon struct ]
537  *	  ...
538  */
539 
540 void
output_dgn()541 output_dgn()
542 {
543 	int	nd, cl = 0, nl = 0,
544 		    cb = 0, nb = 0;
545 	static struct version_info version_data = {
546 			VERSION_NUMBER, VERSION_FEATURES,
547 			VERSION_SANITY1, VERSION_SANITY2
548 	};
549 
550 	if(++n_dgns <= 0) {
551 	    yyerror("FATAL - no dungeons were defined.");
552 	    exit(EXIT_FAILURE);
553 	}
554 
555 	if (fwrite((char *)&version_data, sizeof version_data, 1, yyout) != 1) {
556 	    yyerror("FATAL - output failure.");
557 	    exit(EXIT_FAILURE);
558 	}
559 
560 	(void) fwrite((char *)&n_dgns, sizeof(int), 1, yyout);
561 	for (nd = 0; nd < n_dgns; nd++) {
562 	    (void) fwrite((char *)&tmpdungeon[nd], sizeof(struct tmpdungeon),
563 							1, yyout);
564 
565 	    nl += tmpdungeon[nd].levels;
566 	    for(; cl < nl; cl++)
567 		(void) fwrite((char *)&tmplevel[cl], sizeof(struct tmplevel),
568 							1, yyout);
569 
570 	    nb += tmpdungeon[nd].branches;
571 	    for(; cb < nb; cb++)
572 		(void) fwrite((char *)&tmpbranch[cb], sizeof(struct tmpbranch),
573 							1, yyout);
574 	}
575 	/* apparently necessary for Think C 5.x, otherwise harmless */
576 	(void) fflush(yyout);
577 }
578 
579 /*dgn_comp.y*/
580 #define YYABORT goto yyabort
581 #define YYREJECT goto yyabort
582 #define YYACCEPT goto yyaccept
583 #define YYERROR goto yyerrlab
584 int
yyparse()585 yyparse()
586 {
587     register int yym, yyn, yystate;
588 #if YYDEBUG
589     register char *yys;
590     extern char *getenv();
591 
592     if ((yys = getenv("YYDEBUG")) != 0)
593     {
594         yyn = *yys;
595         if (yyn >= '0' && yyn <= '9')
596             yydebug = yyn - '0';
597     }
598 #endif
599 
600     yynerrs = 0;
601     yyerrflag = 0;
602     yychar = (-1);
603 
604     yyssp = yyss;
605     yyvsp = yyvs;
606     *yyssp = yystate = 0;
607 
608 yyloop:
609     if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
610     if (yychar < 0)
611     {
612         if ((yychar = yylex()) < 0) yychar = 0;
613 #if YYDEBUG
614         if (yydebug)
615         {
616             yys = 0;
617             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
618             if (!yys) yys = "illegal-symbol";
619             printf("%sdebug: state %d, reading %d (%s)\n",
620                     YYPREFIX, yystate, yychar, yys);
621         }
622 #endif
623     }
624     if ((yyn = yysindex[yystate]) != 0 && (yyn += yychar) >= 0 &&
625             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
626     {
627 #if YYDEBUG
628         if (yydebug)
629             printf("%sdebug: state %d, shifting to state %d\n",
630                     YYPREFIX, yystate, yytable[yyn]);
631 #endif
632         if (yyssp >= yyss + yystacksize - 1)
633         {
634             goto yyoverflow;
635         }
636         *++yyssp = yystate = yytable[yyn];
637         *++yyvsp = yylval;
638         yychar = (-1);
639         if (yyerrflag > 0)  --yyerrflag;
640         goto yyloop;
641     }
642     if ((yyn = yyrindex[yystate]) != 0 && (yyn += yychar) >= 0 &&
643             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
644     {
645         yyn = yytable[yyn];
646         goto yyreduce;
647     }
648     if (yyerrflag) goto yyinrecovery;
649 #ifdef lint
650     goto yynewerror;
651 #endif
652 yynewerror:
653     yyerror("syntax error");
654 #ifdef lint
655     goto yyerrlab;
656 #endif
657 yyerrlab:
658     ++yynerrs;
659 yyinrecovery:
660     if (yyerrflag < 3)
661     {
662         yyerrflag = 3;
663         for (;;)
664         {
665             if ((yyn = yysindex[*yyssp]) != 0 && (yyn += YYERRCODE) >= 0 &&
666                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
667             {
668 #if YYDEBUG
669                 if (yydebug)
670                     printf("%sdebug: state %d, error recovery shifting\
671  to state %d\n", YYPREFIX, *yyssp, yytable[yyn]);
672 #endif
673                 if (yyssp >= yyss + yystacksize - 1)
674                 {
675                     goto yyoverflow;
676                 }
677                 *++yyssp = yystate = yytable[yyn];
678                 *++yyvsp = yylval;
679                 goto yyloop;
680             }
681             else
682             {
683 #if YYDEBUG
684                 if (yydebug)
685                     printf("%sdebug: error recovery discarding state %d\n",
686                             YYPREFIX, *yyssp);
687 #endif
688                 if (yyssp <= yyss) goto yyabort;
689                 --yyssp;
690                 --yyvsp;
691             }
692         }
693     }
694     else
695     {
696         if (yychar == 0) goto yyabort;
697 #if YYDEBUG
698         if (yydebug)
699         {
700             yys = 0;
701             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
702             if (!yys) yys = "illegal-symbol";
703             printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
704                     YYPREFIX, yystate, yychar, yys);
705         }
706 #endif
707         yychar = (-1);
708         goto yyloop;
709     }
710 yyreduce:
711 #if YYDEBUG
712     if (yydebug)
713         printf("%sdebug: state %d, reducing by rule %d (%s)\n",
714                 YYPREFIX, yystate, yyn, yyrule[yyn]);
715 #endif
716     yym = yylen[yyn];
717     yyval = yyvsp[1-yym];
718     switch (yyn)
719     {
720 case 2:
721 {
722 			output_dgn();
723 		  }
724 break;
725 case 9:
726 {
727 			init_dungeon();
728 			Strcpy(tmpdungeon[n_dgns].name, yyvsp[-3].str);
729 			tmpdungeon[n_dgns].boneschar = (char)yyvsp[-2].i;
730 			tmpdungeon[n_dgns].lev.base = couple.base;
731 			tmpdungeon[n_dgns].lev.rand = couple.rand;
732 			tmpdungeon[n_dgns].chance = yyvsp[0].i;
733 			Free(yyvsp[-3].str);
734 		  }
735 break;
736 case 10:
737 {
738 			yyval.i = 0;
739 		  }
740 break;
741 case 11:
742 {
743 			yyval.i = yyvsp[0].i;
744 		  }
745 break;
746 case 15:
747 {
748 			tmpdungeon[n_dgns].entry_lev = yyvsp[0].i;
749 		  }
750 break;
751 case 17:
752 {
753 			if(yyvsp[0].i <= TOWN || yyvsp[0].i >= D_ALIGN_CHAOTIC)
754 			    yyerror("Illegal description - ignoring!");
755 			else
756 			    tmpdungeon[n_dgns].flags |= yyvsp[0].i ;
757 		  }
758 break;
759 case 18:
760 {
761 			if(yyvsp[0].i && yyvsp[0].i < D_ALIGN_CHAOTIC)
762 			    yyerror("Illegal alignment - ignoring!");
763 			else
764 			    tmpdungeon[n_dgns].flags |= yyvsp[0].i ;
765 		  }
766 break;
767 case 19:
768 {
769 			Strcpy(tmpdungeon[n_dgns].protoname, yyvsp[0].str);
770 			Free(yyvsp[0].str);
771 		  }
772 break;
773 case 25:
774 {
775 			init_level();
776 			Strcpy(tmplevel[n_levs].name, yyvsp[-3].str);
777 			tmplevel[n_levs].boneschar = (char)yyvsp[-2].i;
778 			tmplevel[n_levs].lev.base = couple.base;
779 			tmplevel[n_levs].lev.rand = couple.rand;
780 			tmpdungeon[n_dgns].levels++;
781 			Free(yyvsp[-3].str);
782 		  }
783 break;
784 case 26:
785 {
786 			init_level();
787 			Strcpy(tmplevel[n_levs].name, yyvsp[-4].str);
788 			tmplevel[n_levs].boneschar = (char)yyvsp[-3].i;
789 			tmplevel[n_levs].lev.base = couple.base;
790 			tmplevel[n_levs].lev.rand = couple.rand;
791 			tmplevel[n_levs].rndlevs = yyvsp[0].i;
792 			tmpdungeon[n_dgns].levels++;
793 			Free(yyvsp[-4].str);
794 		  }
795 break;
796 case 27:
797 {
798 			init_level();
799 			Strcpy(tmplevel[n_levs].name, yyvsp[-4].str);
800 			tmplevel[n_levs].boneschar = (char)yyvsp[-3].i;
801 			tmplevel[n_levs].lev.base = couple.base;
802 			tmplevel[n_levs].lev.rand = couple.rand;
803 			tmplevel[n_levs].chance = yyvsp[0].i;
804 			tmpdungeon[n_dgns].levels++;
805 			Free(yyvsp[-4].str);
806 		  }
807 break;
808 case 28:
809 {
810 			init_level();
811 			Strcpy(tmplevel[n_levs].name, yyvsp[-5].str);
812 			tmplevel[n_levs].boneschar = (char)yyvsp[-4].i;
813 			tmplevel[n_levs].lev.base = couple.base;
814 			tmplevel[n_levs].lev.rand = couple.rand;
815 			tmplevel[n_levs].chance = yyvsp[-1].i;
816 			tmplevel[n_levs].rndlevs = yyvsp[0].i;
817 			tmpdungeon[n_dgns].levels++;
818 			Free(yyvsp[-5].str);
819 		  }
820 break;
821 case 29:
822 {
823 			if(yyvsp[0].i >= D_ALIGN_CHAOTIC)
824 			    yyerror("Illegal description - ignoring!");
825 			else
826 			    tmplevel[n_levs].flags |= yyvsp[0].i ;
827 		  }
828 break;
829 case 30:
830 {
831 			if(yyvsp[0].i && yyvsp[0].i < D_ALIGN_CHAOTIC)
832 			    yyerror("Illegal alignment - ignoring!");
833 			else
834 			    tmplevel[n_levs].flags |= yyvsp[0].i ;
835 		  }
836 break;
837 case 31:
838 {
839 			init_level();
840 			Strcpy(tmplevel[n_levs].name, yyvsp[-4].str);
841 			tmplevel[n_levs].boneschar = (char)yyvsp[-3].i;
842 			tmplevel[n_levs].chain = getchain(yyvsp[-2].str);
843 			tmplevel[n_levs].lev.base = couple.base;
844 			tmplevel[n_levs].lev.rand = couple.rand;
845 			if(!check_level()) n_levs--;
846 			else tmpdungeon[n_dgns].levels++;
847 			Free(yyvsp[-4].str);
848 			Free(yyvsp[-2].str);
849 		  }
850 break;
851 case 32:
852 {
853 			init_level();
854 			Strcpy(tmplevel[n_levs].name, yyvsp[-5].str);
855 			tmplevel[n_levs].boneschar = (char)yyvsp[-4].i;
856 			tmplevel[n_levs].chain = getchain(yyvsp[-3].str);
857 			tmplevel[n_levs].lev.base = couple.base;
858 			tmplevel[n_levs].lev.rand = couple.rand;
859 			tmplevel[n_levs].rndlevs = yyvsp[0].i;
860 			if(!check_level()) n_levs--;
861 			else tmpdungeon[n_dgns].levels++;
862 			Free(yyvsp[-5].str);
863 			Free(yyvsp[-3].str);
864 		  }
865 break;
866 case 33:
867 {
868 			init_level();
869 			Strcpy(tmplevel[n_levs].name, yyvsp[-5].str);
870 			tmplevel[n_levs].boneschar = (char)yyvsp[-4].i;
871 			tmplevel[n_levs].chain = getchain(yyvsp[-3].str);
872 			tmplevel[n_levs].lev.base = couple.base;
873 			tmplevel[n_levs].lev.rand = couple.rand;
874 			tmplevel[n_levs].chance = yyvsp[0].i;
875 			if(!check_level()) n_levs--;
876 			else tmpdungeon[n_dgns].levels++;
877 			Free(yyvsp[-5].str);
878 			Free(yyvsp[-3].str);
879 		  }
880 break;
881 case 34:
882 {
883 			init_level();
884 			Strcpy(tmplevel[n_levs].name, yyvsp[-6].str);
885 			tmplevel[n_levs].boneschar = (char)yyvsp[-5].i;
886 			tmplevel[n_levs].chain = getchain(yyvsp[-4].str);
887 			tmplevel[n_levs].lev.base = couple.base;
888 			tmplevel[n_levs].lev.rand = couple.rand;
889 			tmplevel[n_levs].chance = yyvsp[-1].i;
890 			tmplevel[n_levs].rndlevs = yyvsp[0].i;
891 			if(!check_level()) n_levs--;
892 			else tmpdungeon[n_dgns].levels++;
893 			Free(yyvsp[-6].str);
894 			Free(yyvsp[-4].str);
895 		  }
896 break;
897 case 37:
898 {
899 			init_branch();
900 			Strcpy(tmpbranch[n_brs].name, yyvsp[-4].str);
901 			tmpbranch[n_brs].lev.base = couple.base;
902 			tmpbranch[n_brs].lev.rand = couple.rand;
903 			tmpbranch[n_brs].type = yyvsp[-1].i;
904 			tmpbranch[n_brs].up = yyvsp[0].i;
905 			if(!check_branch()) n_brs--;
906 			else tmpdungeon[n_dgns].branches++;
907 			Free(yyvsp[-4].str);
908 		  }
909 break;
910 case 38:
911 {
912 			init_branch();
913 			Strcpy(tmpbranch[n_brs].name, yyvsp[-5].str);
914 			tmpbranch[n_brs].chain = getchain(yyvsp[-4].str);
915 			tmpbranch[n_brs].lev.base = couple.base;
916 			tmpbranch[n_brs].lev.rand = couple.rand;
917 			tmpbranch[n_brs].type = yyvsp[-1].i;
918 			tmpbranch[n_brs].up = yyvsp[0].i;
919 			if(!check_branch()) n_brs--;
920 			else tmpdungeon[n_dgns].branches++;
921 			Free(yyvsp[-5].str);
922 			Free(yyvsp[-4].str);
923 		  }
924 break;
925 case 39:
926 {
927 			yyval.i = TBR_STAIR;	/* two way stair */
928 		  }
929 break;
930 case 40:
931 {
932 			yyval.i = TBR_STAIR;	/* two way stair */
933 		  }
934 break;
935 case 41:
936 {
937 			yyval.i = TBR_NO_UP;	/* no up staircase */
938 		  }
939 break;
940 case 42:
941 {
942 			yyval.i = TBR_NO_DOWN;	/* no down staircase */
943 		  }
944 break;
945 case 43:
946 {
947 			yyval.i = TBR_PORTAL;	/* portal connection */
948 		  }
949 break;
950 case 44:
951 {
952 			yyval.i = 0;	/* defaults to down */
953 		  }
954 break;
955 case 45:
956 {
957 			yyval.i = yyvsp[0].i;
958 		  }
959 break;
960 case 46:
961 {
962 			char *p = yyvsp[0].str;
963 			if (strlen(p) != 1) {
964 			    if (strcmp(p, "none") != 0)
965 		   yyerror("Bones marker must be a single char, or \"none\"!");
966 			    *p = '\0';
967 			}
968 			yyval.i = *p;
969 			Free(p);
970 		  }
971 break;
972 case 47:
973 {
974 			if (yyvsp[-3].i < -MAXLEVEL || yyvsp[-3].i > MAXLEVEL) {
975 			    yyerror("Abs base out of dlevel range - zeroing!");
976 			    couple.base = couple.rand = 0;
977 			} else if (yyvsp[-1].i < -1 ||
978 				((yyvsp[-3].i < 0) ? (MAXLEVEL + yyvsp[-3].i + yyvsp[-1].i + 1) > MAXLEVEL :
979 					(yyvsp[-3].i + yyvsp[-1].i) > MAXLEVEL)) {
980 			    yyerror("Abs range out of dlevel range - zeroing!");
981 			    couple.base = couple.rand = 0;
982 			} else {
983 			    couple.base = yyvsp[-3].i;
984 			    couple.rand = yyvsp[-1].i;
985 			}
986 		  }
987 break;
988 case 48:
989 {
990 			if (yyvsp[-3].i < -MAXLEVEL || yyvsp[-3].i > MAXLEVEL) {
991 			    yyerror("Rel base out of dlevel range - zeroing!");
992 			    couple.base = couple.rand = 0;
993 			} else {
994 			    couple.base = yyvsp[-3].i;
995 			    couple.rand = yyvsp[-1].i;
996 			}
997 		  }
998 break;
999     }
1000     yyssp -= yym;
1001     yystate = *yyssp;
1002     yyvsp -= yym;
1003     yym = yylhs[yyn];
1004     if (yystate == 0 && yym == 0)
1005     {
1006 #if YYDEBUG
1007         if (yydebug)
1008             printf("%sdebug: after reduction, shifting from state 0 to\
1009  state %d\n", YYPREFIX, YYFINAL);
1010 #endif
1011         yystate = YYFINAL;
1012         *++yyssp = YYFINAL;
1013         *++yyvsp = yyval;
1014         if (yychar < 0)
1015         {
1016             if ((yychar = yylex()) < 0) yychar = 0;
1017 #if YYDEBUG
1018             if (yydebug)
1019             {
1020                 yys = 0;
1021                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
1022                 if (!yys) yys = "illegal-symbol";
1023                 printf("%sdebug: state %d, reading %d (%s)\n",
1024                         YYPREFIX, YYFINAL, yychar, yys);
1025             }
1026 #endif
1027         }
1028         if (yychar == 0) goto yyaccept;
1029         goto yyloop;
1030     }
1031     if ((yyn = yygindex[yym]) != 0 && (yyn += yystate) >= 0 &&
1032             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
1033         yystate = yytable[yyn];
1034     else
1035         yystate = yydgoto[yym];
1036 #if YYDEBUG
1037     if (yydebug)
1038         printf("%sdebug: after reduction, shifting from state %d \
1039 to state %d\n", YYPREFIX, *yyssp, yystate);
1040 #endif
1041     if (yyssp >= yyss + yystacksize - 1)
1042     {
1043         goto yyoverflow;
1044     }
1045     *++yyssp = yystate;
1046     *++yyvsp = yyval;
1047     goto yyloop;
1048 yyoverflow:
1049     yyerror("yacc stack overflow");
1050 yyabort:
1051     return (1);
1052 yyaccept:
1053     return (0);
1054 }
1055