OSDN Git Service

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