Lua: remove dgn_comp, use lua instead
This commit is contained in:
-144
@@ -1,144 +0,0 @@
|
||||
%{
|
||||
/* NetHack 3.6 dgn_comp.l $NHDT-Date: 1455415007 2016/02/14 01:56:47 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.13 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* Copyright (c) 1990 by M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#define DGN_COMP
|
||||
|
||||
#include "config.h"
|
||||
#include "dgn_comp.h"
|
||||
#include "dgn_file.h"
|
||||
|
||||
/*
|
||||
* Most of these don't exist in flex, yywrap is macro and
|
||||
* yyunput is properly declared in flex.skel.
|
||||
*/
|
||||
#if !defined(FLEX_SCANNER) && !defined(FLEXHACK_SCANNER)
|
||||
int FDECL(yyback, (int *,int));
|
||||
int NDECL(yylook);
|
||||
int NDECL(yyinput);
|
||||
int NDECL(yywrap);
|
||||
int NDECL(yylex);
|
||||
/* Traditional lexes let yyunput() and yyoutput() default to int;
|
||||
* newer ones may declare them as void since they don't return
|
||||
* values. For even more fun, the lex supplied as part of the
|
||||
* newer unbundled compiler for SunOS 4.x adds the void declarations
|
||||
* (under __STDC__ or _cplusplus ifdefs -- otherwise they remain
|
||||
* int) while the bundled lex and the one with the older unbundled
|
||||
* compiler do not. To detect this, we need help from outside --
|
||||
* sys/unix/Makefile.utl.
|
||||
*
|
||||
* Digital UNIX is difficult and still has int in spite of all
|
||||
* other signs.
|
||||
*/
|
||||
# if defined(NeXT) || defined(SVR4) || defined(_AIX32)
|
||||
# define VOIDYYPUT
|
||||
# endif
|
||||
# if !defined(VOIDYYPUT) && defined(POSIX_TYPES)
|
||||
# if !defined(BOS) && !defined(HISX) && !defined(_M_UNIX) && !defined(VMS)
|
||||
# define VOIDYYPUT
|
||||
# endif
|
||||
# endif
|
||||
# if !defined(VOIDYYPUT) && defined(WEIRD_LEX)
|
||||
# if defined(SUNOS4) && defined(__STDC__) && (WEIRD_LEX > 1)
|
||||
# define VOIDYYPUT
|
||||
# endif
|
||||
# endif
|
||||
# if defined(VOIDYYPUT) && defined(__osf__)
|
||||
# undef VOIDYYPUT
|
||||
# endif
|
||||
# ifdef VOIDYYPUT
|
||||
void FDECL(yyunput, (int));
|
||||
void FDECL(yyoutput, (int));
|
||||
# else
|
||||
int FDECL(yyunput, (int));
|
||||
int FDECL(yyoutput, (int));
|
||||
# endif
|
||||
|
||||
#else /* !FLEX_SCANNER && !FLEXHACK_SCANNER */
|
||||
/* most recent flex allows suppressing yyunput() altogether when not needed */
|
||||
#define YY_NO_UNPUT
|
||||
#define YY_NO_INPUT
|
||||
#endif
|
||||
|
||||
#if defined(FLEX_SCANNER) || defined(FLEXHACK_SCANNER)
|
||||
/* older flex wants this */
|
||||
#define YY_MALLOC_DECL genericptr_t FDECL(malloc, (size_t)); \
|
||||
genericptr_t FDECL(realloc, (genericptr_t, size_t));
|
||||
/* newer flex assumes <stdlib.h> so needs this in case it's been suppressed */
|
||||
YY_MALLOC_DECL
|
||||
#endif
|
||||
|
||||
void FDECL(init_yyin, (FILE *));
|
||||
void FDECL(init_yyout, (FILE *));
|
||||
|
||||
/* this doesn't always get put in dgn_comp.h
|
||||
* (esp. when using older versions of bison)
|
||||
*/
|
||||
extern YYSTYPE yylval;
|
||||
|
||||
int nh_line_number = 1;
|
||||
|
||||
%}
|
||||
%%
|
||||
DUNGEON return(A_DUNGEON);
|
||||
up { yylval.i=1; return(UP_OR_DOWN); }
|
||||
down { yylval.i=0; return(UP_OR_DOWN); }
|
||||
ENTRY return(ENTRY);
|
||||
stair return(STAIR);
|
||||
no_up return(NO_UP);
|
||||
no_down return(NO_DOWN);
|
||||
portal return(PORTAL);
|
||||
PROTOFILE return(PROTOFILE);
|
||||
DESCRIPTION return(DESCRIPTION);
|
||||
LEVELDESC return(LEVELDESC);
|
||||
ALIGNMENT return(ALIGNMENT);
|
||||
LEVALIGN return(LEVALIGN);
|
||||
town { yylval.i=TOWN ; return(DESCRIPTOR); }
|
||||
hellish { yylval.i=HELLISH ; return(DESCRIPTOR); }
|
||||
mazelike { yylval.i=MAZELIKE ; return(DESCRIPTOR); }
|
||||
roguelike { yylval.i=ROGUELIKE ; return(DESCRIPTOR); }
|
||||
unaligned { yylval.i=D_ALIGN_NONE ; return(DESCRIPTOR); }
|
||||
noalign { yylval.i=D_ALIGN_NONE ; return(DESCRIPTOR); }
|
||||
lawful { yylval.i=D_ALIGN_LAWFUL ; return(DESCRIPTOR); }
|
||||
neutral { yylval.i=D_ALIGN_NEUTRAL ; return(DESCRIPTOR); }
|
||||
chaotic { yylval.i=D_ALIGN_CHAOTIC ; return(DESCRIPTOR); }
|
||||
BRANCH return(BRANCH);
|
||||
CHAINBRANCH return(CHBRANCH);
|
||||
LEVEL return(LEVEL);
|
||||
RNDLEVEL return(RNDLEVEL);
|
||||
CHAINLEVEL return(CHLEVEL);
|
||||
RNDCHLEVEL return(RNDCHLEVEL);
|
||||
[-0-9]+ { yylval.i=atoi(yytext); return(INTEGER); }
|
||||
\"[^"]*\" { yytext[yyleng - 1] = '\0'; /* discard the trailing \" */
|
||||
yylval.str = dupstr(yytext + 1); /* skip the first \" */
|
||||
return STRING; }
|
||||
^#.*\n { nh_line_number++; }
|
||||
\r?\n { nh_line_number++; }
|
||||
[ \t]+ ; /* skip trailing tabs & spaces */
|
||||
. { return yytext[0]; }
|
||||
%%
|
||||
|
||||
/* routine to switch to another input file; needed for flex */
|
||||
void
|
||||
init_yyin( input_f )
|
||||
FILE *input_f;
|
||||
{
|
||||
#if defined(FLEX_SCANNER) || defined(FLEXHACK_SCANNER)
|
||||
if (yyin)
|
||||
yyrestart(input_f);
|
||||
else
|
||||
#endif
|
||||
yyin = input_f;
|
||||
}
|
||||
|
||||
/* analogous routine (for completeness) */
|
||||
void
|
||||
init_yyout( output_f )
|
||||
FILE *output_f;
|
||||
{
|
||||
yyout = output_f;
|
||||
}
|
||||
|
||||
/*dgn_comp.l*/
|
||||
-678
@@ -1,678 +0,0 @@
|
||||
%{
|
||||
/* NetHack 3.6 dgn_comp.y $NHDT-Date: 1432512785 2015/05/25 00:13:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.8 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* Copyright (c) 1990 by M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
/*
|
||||
* This file contains the Dungeon Compiler code
|
||||
*/
|
||||
|
||||
/* In case we're using bison in AIX. This definition must be
|
||||
* placed before any other C-language construct in the file
|
||||
* excluding comments and preprocessor directives (thanks IBM
|
||||
* for this wonderful feature...).
|
||||
*
|
||||
* Note: some cpps barf on this 'undefined control' (#pragma).
|
||||
* Addition of the leading space seems to prevent barfage for now,
|
||||
* and AIX will still see the directive in its non-standard locale.
|
||||
*/
|
||||
|
||||
#ifdef _AIX
|
||||
#pragma alloca /* keep leading space! */
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
#include "date.h"
|
||||
#include "dgn_file.h"
|
||||
|
||||
void FDECL(yyerror, (const char *));
|
||||
void FDECL(yywarning, (const char *));
|
||||
int NDECL(yylex);
|
||||
int NDECL(yyparse);
|
||||
int FDECL(getchain, (char *));
|
||||
int NDECL(check_dungeon);
|
||||
int NDECL(check_branch);
|
||||
int NDECL(check_level);
|
||||
void NDECL(init_dungeon);
|
||||
void NDECL(init_branch);
|
||||
void NDECL(init_level);
|
||||
void NDECL(output_dgn);
|
||||
|
||||
#define Free(ptr) free((genericptr_t)ptr)
|
||||
|
||||
#ifdef AMIGA
|
||||
# undef printf
|
||||
#ifndef LATTICE
|
||||
# define memset(addr,val,len) setmem(addr,len,val)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define ERR (-1)
|
||||
|
||||
static struct couple couple;
|
||||
static struct tmpdungeon tmpdungeon[MAXDUNGEON];
|
||||
static struct tmplevel tmplevel[LEV_LIMIT];
|
||||
static struct tmpbranch tmpbranch[BRANCH_LIMIT];
|
||||
|
||||
static int in_dungeon = 0, n_dgns = -1, n_levs = -1, n_brs = -1;
|
||||
|
||||
extern int fatal_error;
|
||||
extern const char *fname;
|
||||
extern FILE *yyin, *yyout; /* from dgn_lex.c */
|
||||
|
||||
%}
|
||||
|
||||
%union
|
||||
{
|
||||
int i;
|
||||
char* str;
|
||||
}
|
||||
|
||||
%token <i> INTEGER
|
||||
%token <i> A_DUNGEON BRANCH CHBRANCH LEVEL RNDLEVEL CHLEVEL RNDCHLEVEL
|
||||
%token <i> UP_OR_DOWN PROTOFILE DESCRIPTION DESCRIPTOR LEVELDESC
|
||||
%token <i> ALIGNMENT LEVALIGN ENTRY STAIR NO_UP NO_DOWN PORTAL
|
||||
%token <str> STRING
|
||||
%type <i> optional_int direction branch_type bones_tag
|
||||
%start file
|
||||
|
||||
%%
|
||||
file : /* nothing */
|
||||
| dungeons
|
||||
{
|
||||
output_dgn();
|
||||
}
|
||||
;
|
||||
|
||||
dungeons : dungeon
|
||||
| dungeons dungeon
|
||||
;
|
||||
|
||||
dungeon : dungeonline
|
||||
| dungeondesc
|
||||
| branches
|
||||
| levels
|
||||
;
|
||||
|
||||
dungeonline : A_DUNGEON ':' STRING bones_tag rcouple optional_int
|
||||
{
|
||||
init_dungeon();
|
||||
Strcpy(tmpdungeon[n_dgns].name, $3);
|
||||
tmpdungeon[n_dgns].boneschar = (char)$4;
|
||||
tmpdungeon[n_dgns].lev.base = couple.base;
|
||||
tmpdungeon[n_dgns].lev.rand = couple.rand;
|
||||
tmpdungeon[n_dgns].chance = $6;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
optional_int : /* nothing */
|
||||
{
|
||||
$$ = 0;
|
||||
}
|
||||
| INTEGER
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
dungeondesc : entry
|
||||
| descriptions
|
||||
| prototype
|
||||
;
|
||||
|
||||
entry : ENTRY ':' INTEGER
|
||||
{
|
||||
tmpdungeon[n_dgns].entry_lev = $3;
|
||||
}
|
||||
;
|
||||
|
||||
descriptions : desc
|
||||
;
|
||||
|
||||
desc : DESCRIPTION ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 <= TOWN || $<i>3 >= D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal description - ignoring!");
|
||||
else
|
||||
tmpdungeon[n_dgns].flags |= $<i>3 ;
|
||||
}
|
||||
| ALIGNMENT ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 && $<i>3 < D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal alignment - ignoring!");
|
||||
else
|
||||
tmpdungeon[n_dgns].flags |= $<i>3 ;
|
||||
}
|
||||
;
|
||||
|
||||
prototype : PROTOFILE ':' STRING
|
||||
{
|
||||
Strcpy(tmpdungeon[n_dgns].protoname, $3);
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
levels : level1
|
||||
| level2
|
||||
| levdesc
|
||||
| chlevel1
|
||||
| chlevel2
|
||||
;
|
||||
|
||||
level1 : LEVEL ':' STRING bones_tag '@' acouple
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
| RNDLEVEL ':' STRING bones_tag '@' acouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].rndlevs = $7;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
level2 : LEVEL ':' STRING bones_tag '@' acouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $7;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
| RNDLEVEL ':' STRING bones_tag '@' acouple INTEGER INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $7;
|
||||
tmplevel[n_levs].rndlevs = $8;
|
||||
tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
levdesc : LEVELDESC ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 >= D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal description - ignoring!");
|
||||
else
|
||||
tmplevel[n_levs].flags |= $<i>3 ;
|
||||
}
|
||||
| LEVALIGN ':' DESCRIPTOR
|
||||
{
|
||||
if($<i>3 && $<i>3 < D_ALIGN_CHAOTIC)
|
||||
yyerror("Illegal alignment - ignoring!");
|
||||
else
|
||||
tmplevel[n_levs].flags |= $<i>3 ;
|
||||
}
|
||||
;
|
||||
|
||||
chlevel1 : CHLEVEL ':' STRING bones_tag STRING '+' rcouple
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
| RNDCHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].rndlevs = $8;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
;
|
||||
|
||||
chlevel2 : CHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $8;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
| RNDCHLEVEL ':' STRING bones_tag STRING '+' rcouple INTEGER INTEGER
|
||||
{
|
||||
init_level();
|
||||
Strcpy(tmplevel[n_levs].name, $3);
|
||||
tmplevel[n_levs].boneschar = (char)$4;
|
||||
tmplevel[n_levs].chain = getchain($5);
|
||||
tmplevel[n_levs].lev.base = couple.base;
|
||||
tmplevel[n_levs].lev.rand = couple.rand;
|
||||
tmplevel[n_levs].chance = $8;
|
||||
tmplevel[n_levs].rndlevs = $9;
|
||||
if(!check_level()) n_levs--;
|
||||
else tmpdungeon[n_dgns].levels++;
|
||||
Free($3);
|
||||
Free($5);
|
||||
}
|
||||
;
|
||||
|
||||
branches : branch
|
||||
| chbranch
|
||||
;
|
||||
|
||||
branch : BRANCH ':' STRING '@' acouple branch_type direction
|
||||
{
|
||||
init_branch();
|
||||
Strcpy(tmpbranch[n_brs].name, $3);
|
||||
tmpbranch[n_brs].lev.base = couple.base;
|
||||
tmpbranch[n_brs].lev.rand = couple.rand;
|
||||
tmpbranch[n_brs].type = $6;
|
||||
tmpbranch[n_brs].up = $7;
|
||||
if(!check_branch()) n_brs--;
|
||||
else tmpdungeon[n_dgns].branches++;
|
||||
Free($3);
|
||||
}
|
||||
;
|
||||
|
||||
chbranch : CHBRANCH ':' STRING STRING '+' rcouple branch_type direction
|
||||
{
|
||||
init_branch();
|
||||
Strcpy(tmpbranch[n_brs].name, $3);
|
||||
tmpbranch[n_brs].chain = getchain($4);
|
||||
tmpbranch[n_brs].lev.base = couple.base;
|
||||
tmpbranch[n_brs].lev.rand = couple.rand;
|
||||
tmpbranch[n_brs].type = $7;
|
||||
tmpbranch[n_brs].up = $8;
|
||||
if(!check_branch()) n_brs--;
|
||||
else tmpdungeon[n_dgns].branches++;
|
||||
Free($3);
|
||||
Free($4);
|
||||
}
|
||||
;
|
||||
|
||||
branch_type : /* nothing */
|
||||
{
|
||||
$$ = TBR_STAIR; /* two way stair */
|
||||
}
|
||||
| STAIR
|
||||
{
|
||||
$$ = TBR_STAIR; /* two way stair */
|
||||
}
|
||||
| NO_UP
|
||||
{
|
||||
$$ = TBR_NO_UP; /* no up staircase */
|
||||
}
|
||||
| NO_DOWN
|
||||
{
|
||||
$$ = TBR_NO_DOWN; /* no down staircase */
|
||||
}
|
||||
| PORTAL
|
||||
{
|
||||
$$ = TBR_PORTAL; /* portal connection */
|
||||
}
|
||||
;
|
||||
|
||||
direction : /* nothing */
|
||||
{
|
||||
$$ = 0; /* defaults to down */
|
||||
}
|
||||
| UP_OR_DOWN
|
||||
{
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
bones_tag : STRING
|
||||
{
|
||||
char *p = $1;
|
||||
if (strlen(p) != 1) {
|
||||
if (strcmp(p, "none") != 0)
|
||||
yyerror("Bones marker must be a single char, or \"none\"!");
|
||||
*p = '\0';
|
||||
}
|
||||
$$ = *p;
|
||||
Free(p);
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* acouple rules:
|
||||
*
|
||||
* (base, range) where:
|
||||
*
|
||||
* base is either a positive or negative integer with a value
|
||||
* less than or equal to MAXLEVEL.
|
||||
* base > 0 indicates the base level.
|
||||
* base < 0 indicates reverse index (-1 == lowest level)
|
||||
*
|
||||
* range is the random component.
|
||||
* if range is zero, there is no random component.
|
||||
* if range is -1 the dungeon loader will randomize between
|
||||
* the base and the end of the dungeon.
|
||||
* during dungeon load, range is always *added* to the base,
|
||||
* therefore range + base(converted) must not exceed MAXLEVEL.
|
||||
*/
|
||||
acouple : '(' INTEGER ',' INTEGER ')'
|
||||
{
|
||||
if ($2 < -MAXLEVEL || $2 > MAXLEVEL) {
|
||||
yyerror("Abs base out of dlevel range - zeroing!");
|
||||
couple.base = couple.rand = 0;
|
||||
} else if ($4 < -1 ||
|
||||
(($2 < 0) ? (MAXLEVEL + $2 + $4 + 1) > MAXLEVEL :
|
||||
($2 + $4) > MAXLEVEL)) {
|
||||
yyerror("Abs range out of dlevel range - zeroing!");
|
||||
couple.base = couple.rand = 0;
|
||||
} else {
|
||||
couple.base = $2;
|
||||
couple.rand = $4;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
/*
|
||||
* rcouple rules:
|
||||
*
|
||||
* (base, range) where:
|
||||
*
|
||||
* base is either a positive or negative integer with a value
|
||||
* less than or equal to MAXLEVEL.
|
||||
* base > 0 indicates a forward index.
|
||||
* base < 0 indicates a reverse index.
|
||||
* base == 0 indicates on the parent level.
|
||||
*
|
||||
* range is the random component.
|
||||
* if range is zero, there is no random component.
|
||||
* during dungeon load, range is always *added* to the base,
|
||||
* range + base(converted) may be very large. The dungeon
|
||||
* loader will then correct to "between here and the top/bottom".
|
||||
*
|
||||
* There is no practical way of specifying "between here and the
|
||||
* nth / nth last level".
|
||||
*/
|
||||
rcouple : '(' INTEGER ',' INTEGER ')'
|
||||
{
|
||||
if ($2 < -MAXLEVEL || $2 > MAXLEVEL) {
|
||||
yyerror("Rel base out of dlevel range - zeroing!");
|
||||
couple.base = couple.rand = 0;
|
||||
} else {
|
||||
couple.base = $2;
|
||||
couple.rand = $4;
|
||||
}
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
void
|
||||
init_dungeon()
|
||||
{
|
||||
if(++n_dgns > MAXDUNGEON) {
|
||||
(void) fprintf(stderr, "FATAL - Too many dungeons (limit: %d).\n",
|
||||
MAXDUNGEON);
|
||||
(void) fprintf(stderr, "To increase the limit edit MAXDUNGEON in global.h\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
in_dungeon = 1;
|
||||
tmpdungeon[n_dgns].lev.base = 0;
|
||||
tmpdungeon[n_dgns].lev.rand = 0;
|
||||
tmpdungeon[n_dgns].chance = 100;
|
||||
Strcpy(tmpdungeon[n_dgns].name, "");
|
||||
Strcpy(tmpdungeon[n_dgns].protoname, "");
|
||||
tmpdungeon[n_dgns].flags = 0;
|
||||
tmpdungeon[n_dgns].levels = 0;
|
||||
tmpdungeon[n_dgns].branches = 0;
|
||||
tmpdungeon[n_dgns].entry_lev = 0;
|
||||
}
|
||||
|
||||
void
|
||||
init_level()
|
||||
{
|
||||
if(++n_levs > LEV_LIMIT) {
|
||||
|
||||
yyerror("FATAL - Too many special levels defined.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
tmplevel[n_levs].lev.base = 0;
|
||||
tmplevel[n_levs].lev.rand = 0;
|
||||
tmplevel[n_levs].chance = 100;
|
||||
tmplevel[n_levs].rndlevs = 0;
|
||||
tmplevel[n_levs].flags = 0;
|
||||
Strcpy(tmplevel[n_levs].name, "");
|
||||
tmplevel[n_levs].chain = -1;
|
||||
}
|
||||
|
||||
void
|
||||
init_branch()
|
||||
{
|
||||
if(++n_brs > BRANCH_LIMIT) {
|
||||
|
||||
yyerror("FATAL - Too many special levels defined.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
tmpbranch[n_brs].lev.base = 0;
|
||||
tmpbranch[n_brs].lev.rand = 0;
|
||||
Strcpy(tmpbranch[n_brs].name, "");
|
||||
tmpbranch[n_brs].chain = -1;
|
||||
}
|
||||
|
||||
int
|
||||
getchain(s)
|
||||
char *s;
|
||||
{
|
||||
int i;
|
||||
|
||||
if(strlen(s)) {
|
||||
|
||||
for(i = n_levs - tmpdungeon[n_dgns].levels + 1; i <= n_levs; i++)
|
||||
if(!strcmp(tmplevel[i].name, s)) return i;
|
||||
|
||||
yyerror("Can't locate the specified chain level.");
|
||||
return(-2);
|
||||
}
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Consistancy checking routines:
|
||||
*
|
||||
* - A dungeon must have a unique name.
|
||||
* - A dungeon must have a originating "branch" command
|
||||
* (except, of course, for the first dungeon).
|
||||
* - A dungeon must have a proper depth (at least (1, 0)).
|
||||
*/
|
||||
|
||||
int
|
||||
check_dungeon()
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < n_dgns; i++)
|
||||
if(!strcmp(tmpdungeon[i].name, tmpdungeon[n_dgns].name)) {
|
||||
yyerror("Duplicate dungeon name.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(n_dgns)
|
||||
for(i = 0; i < n_brs - tmpdungeon[n_dgns].branches; i++) {
|
||||
if(!strcmp(tmpbranch[i].name, tmpdungeon[n_dgns].name)) break;
|
||||
|
||||
if(i >= n_brs - tmpdungeon[n_dgns].branches) {
|
||||
yyerror("Dungeon cannot be reached.");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if(tmpdungeon[n_dgns].lev.base <= 0 ||
|
||||
tmpdungeon[n_dgns].lev.rand < 0) {
|
||||
yyerror("Invalid dungeon depth specified.");
|
||||
return(0);
|
||||
}
|
||||
return(1); /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* - A level must have a unique level name.
|
||||
* - If chained, the level used as reference for the chain
|
||||
* must be in this dungeon, must be previously defined, and
|
||||
* the level chained from must be "non-probabilistic" (ie.
|
||||
* have a 100% chance of existing).
|
||||
*/
|
||||
|
||||
int
|
||||
check_level()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!in_dungeon) {
|
||||
yyerror("Level defined outside of dungeon.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
for(i = 0; i < n_levs; i++)
|
||||
if(!strcmp(tmplevel[i].name, tmplevel[n_levs].name)) {
|
||||
yyerror("Duplicate level name.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(tmplevel[i].chain == -2) {
|
||||
yyerror("Invaild level chain reference.");
|
||||
return(0);
|
||||
} else if(tmplevel[i].chain != -1) { /* there is a chain */
|
||||
/* KMH -- tmplevel[tmpbranch[i].chain].chance was in error */
|
||||
if(tmplevel[tmplevel[i].chain].chance != 100) {
|
||||
yyerror("Level cannot chain from a probabilistic level.");
|
||||
return(0);
|
||||
} else if(tmplevel[i].chain == n_levs) {
|
||||
yyerror("A level cannot chain to itself!");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1); /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* - A branch may not branch backwards - to avoid branch loops.
|
||||
* - A branch name must be unique.
|
||||
* (ie. You can only have one entry point to each dungeon).
|
||||
* - If chained, the level used as reference for the chain
|
||||
* must be in this dungeon, must be previously defined, and
|
||||
* the level chained from must be "non-probabilistic" (ie.
|
||||
* have a 100% chance of existing).
|
||||
*/
|
||||
|
||||
int
|
||||
check_branch()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!in_dungeon) {
|
||||
yyerror("Branch defined outside of dungeon.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
for(i = 0; i < n_dgns; i++)
|
||||
if(!strcmp(tmpdungeon[i].name, tmpbranch[n_brs].name)) {
|
||||
|
||||
yyerror("Reverse branching not allowed.");
|
||||
return(0);
|
||||
}
|
||||
|
||||
if(tmpbranch[i].chain == -2) {
|
||||
|
||||
yyerror("Invaild branch chain reference.");
|
||||
return(0);
|
||||
} else if(tmpbranch[i].chain != -1) { /* it is chained */
|
||||
|
||||
if(tmplevel[tmpbranch[i].chain].chance != 100) {
|
||||
yyerror("Branch cannot chain from a probabilistic level.");
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
return(1); /* OK */
|
||||
}
|
||||
|
||||
/*
|
||||
* Output the dungon definition into a file.
|
||||
*
|
||||
* The file will have the following format:
|
||||
*
|
||||
* [ nethack version ID ]
|
||||
* [ number of dungeons ]
|
||||
* [ first dungeon struct ]
|
||||
* [ levels for the first dungeon ]
|
||||
* ...
|
||||
* [ branches for the first dungeon ]
|
||||
* ...
|
||||
* [ second dungeon struct ]
|
||||
* ...
|
||||
*/
|
||||
|
||||
void
|
||||
output_dgn()
|
||||
{
|
||||
int nd, cl = 0, nl = 0,
|
||||
cb = 0, nb = 0;
|
||||
static struct version_info version_data = {
|
||||
VERSION_NUMBER, VERSION_FEATURES,
|
||||
VERSION_SANITY1, VERSION_SANITY2, VERSION_SANITY3
|
||||
};
|
||||
|
||||
if(++n_dgns <= 0) {
|
||||
yyerror("FATAL - no dungeons were defined.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (fwrite((char *)&version_data, sizeof version_data, 1, yyout) != 1) {
|
||||
yyerror("FATAL - output failure.");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
(void) fwrite((char *)&n_dgns, sizeof(int), 1, yyout);
|
||||
for (nd = 0; nd < n_dgns; nd++) {
|
||||
(void) fwrite((char *)&tmpdungeon[nd], sizeof(struct tmpdungeon),
|
||||
1, yyout);
|
||||
|
||||
nl += tmpdungeon[nd].levels;
|
||||
for(; cl < nl; cl++)
|
||||
(void) fwrite((char *)&tmplevel[cl], sizeof(struct tmplevel),
|
||||
1, yyout);
|
||||
|
||||
nb += tmpdungeon[nd].branches;
|
||||
for(; cb < nb; cb++)
|
||||
(void) fwrite((char *)&tmpbranch[cb], sizeof(struct tmpbranch),
|
||||
1, yyout);
|
||||
}
|
||||
/* apparently necessary for Think C 5.x, otherwise harmless */
|
||||
(void) fflush(yyout);
|
||||
}
|
||||
|
||||
/*dgn_comp.y*/
|
||||
-193
@@ -1,193 +0,0 @@
|
||||
/* NetHack 3.6 dgn_main.c $NHDT-Date: 1432512785 2015/05/25 00:13:05 $ $NHDT-Branch: master $:$NHDT-Revision: 1.11 $ */
|
||||
/* Copyright (c) 1989 by Jean-Christophe Collet */
|
||||
/* Copyright (c) 1990 by M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
/*
|
||||
* This file contains the main function for the parser
|
||||
* and some useful functions needed by yacc
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "dlb.h"
|
||||
|
||||
/* Macintosh-specific code */
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
/* MacOS X has Unix-style files and processes */
|
||||
#undef MAC
|
||||
#endif
|
||||
#ifdef MAC
|
||||
#if defined(__SC__) || defined(__MRC__)
|
||||
#define MPWTOOL
|
||||
#include <CursorCtl.h>
|
||||
#else
|
||||
/* put dungeon file in library location */
|
||||
#define PREFIX ":lib:"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MPWTOOL
|
||||
#define SpinCursor(x)
|
||||
#endif
|
||||
|
||||
#define MAX_ERRORS 25
|
||||
|
||||
extern int NDECL(yyparse);
|
||||
extern int nh_line_number;
|
||||
const char *fname = "(stdin)";
|
||||
int fatal_error = 0;
|
||||
|
||||
int FDECL(main, (int, char **));
|
||||
void FDECL(yyerror, (const char *));
|
||||
void FDECL(yywarning, (const char *));
|
||||
int NDECL(yywrap);
|
||||
void FDECL(init_yyin, (FILE *));
|
||||
void FDECL(init_yyout, (FILE *));
|
||||
|
||||
#ifdef AZTEC_36
|
||||
FILE *FDECL(freopen, (char *, char *, FILE *));
|
||||
#endif
|
||||
#define Fprintf (void) fprintf
|
||||
|
||||
#if defined(__BORLANDC__) && !defined(_WIN32)
|
||||
extern unsigned _stklen = STKSIZ;
|
||||
#endif
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char infile[64], outfile[64], basename[64];
|
||||
FILE *fin, *fout;
|
||||
int i, len;
|
||||
boolean errors_encountered = FALSE;
|
||||
#if defined(MAC) && (defined(THINK_C) || defined(__MWERKS__))
|
||||
char *mark;
|
||||
static char *mac_argv[] = { "dgn_comp", /* dummy argv[0] */
|
||||
":dat:dungeon.pdf" };
|
||||
|
||||
argc = SIZE(mac_argv);
|
||||
argv = mac_argv;
|
||||
#endif
|
||||
|
||||
Strcpy(infile, "(stdin)");
|
||||
fin = stdin;
|
||||
Strcpy(outfile, "(stdout)");
|
||||
fout = stdout;
|
||||
|
||||
if (argc == 1) { /* Read standard input */
|
||||
init_yyin(fin);
|
||||
init_yyout(fout);
|
||||
(void) yyparse();
|
||||
if (fatal_error > 0)
|
||||
errors_encountered = TRUE;
|
||||
} else { /* Otherwise every argument is a filename */
|
||||
for (i = 1; i < argc; i++) {
|
||||
fname = strcpy(infile, argv[i]);
|
||||
/* the input file had better be a .pdf file */
|
||||
len = strlen(fname) - 4; /* length excluding suffix */
|
||||
if (len < 0 || strncmp(".pdf", fname + len, 4)) {
|
||||
Fprintf(stderr, "Error - file name \"%s\" in wrong format.\n",
|
||||
fname);
|
||||
errors_encountered = TRUE;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* build output file name */
|
||||
#if defined(MAC) && (defined(THINK_C) || defined(__MWERKS__))
|
||||
/* extract basename from path to infile */
|
||||
mark = strrchr(infile, ':');
|
||||
strcpy(basename, mark ? mark + 1 : infile);
|
||||
mark = strchr(basename, '.');
|
||||
if (mark)
|
||||
*mark = '\0';
|
||||
#else
|
||||
/* Use the whole name - strip off the last 3 or 4 chars. */
|
||||
|
||||
#ifdef VMS /* avoid possible interaction with logical name */
|
||||
len++; /* retain "." as trailing punctuation */
|
||||
#endif
|
||||
(void) strncpy(basename, infile, len);
|
||||
basename[len] = '\0';
|
||||
#endif
|
||||
|
||||
outfile[0] = '\0';
|
||||
#ifdef PREFIX
|
||||
(void) strcat(outfile, PREFIX);
|
||||
#endif
|
||||
(void) strcat(outfile, basename);
|
||||
|
||||
fin = freopen(infile, "r", stdin);
|
||||
if (!fin) {
|
||||
Fprintf(stderr, "Can't open %s for input.\n", infile);
|
||||
perror(infile);
|
||||
errors_encountered = TRUE;
|
||||
continue;
|
||||
}
|
||||
fout = freopen(outfile, WRBMODE, stdout);
|
||||
if (!fout) {
|
||||
Fprintf(stderr, "Can't open %s for output.\n", outfile);
|
||||
perror(outfile);
|
||||
errors_encountered = TRUE;
|
||||
continue;
|
||||
}
|
||||
init_yyin(fin);
|
||||
init_yyout(fout);
|
||||
(void) yyparse();
|
||||
nh_line_number = 1;
|
||||
if (fatal_error > 0) {
|
||||
errors_encountered = TRUE;
|
||||
fatal_error = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fout && fclose(fout) < 0) {
|
||||
Fprintf(stderr, "Can't finish output file.");
|
||||
perror(outfile);
|
||||
errors_encountered = TRUE;
|
||||
}
|
||||
exit(errors_encountered ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Each time the parser detects an error, it uses this function.
|
||||
* Here we take count of the errors. To continue farther than
|
||||
* MAX_ERRORS wouldn't be reasonable.
|
||||
*/
|
||||
|
||||
void
|
||||
yyerror(s)
|
||||
const char *s;
|
||||
{
|
||||
(void) fprintf(stderr, "%s : line %d : %s\n", fname, nh_line_number, s);
|
||||
if (++fatal_error > MAX_ERRORS) {
|
||||
(void) fprintf(stderr, "Too many errors, good bye!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Just display a warning (that is : a non fatal error)
|
||||
*/
|
||||
|
||||
void
|
||||
yywarning(s)
|
||||
const char *s;
|
||||
{
|
||||
(void) fprintf(stderr, "%s : line %d : WARNING : %s\n", fname,
|
||||
nh_line_number, s);
|
||||
}
|
||||
|
||||
int
|
||||
yywrap()
|
||||
{
|
||||
SpinCursor(3); /* Don't know if this is a good place to put it ?
|
||||
Is it called for our grammar ?
|
||||
Often enough ?
|
||||
Too often ? -- h+ */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*dgn_main.c*/
|
||||
Reference in New Issue
Block a user