OSDN Git Service

no bone
[nethackexpress/trunk.git] / sys / share / dgn_yacc.c
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.4     1996/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
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
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
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
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
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
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
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
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
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 }