diff options
Diffstat (limited to 'crawl-ref/source/util/levcomp.ypp')
-rw-r--r-- | crawl-ref/source/util/levcomp.ypp | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp new file mode 100644 index 0000000000..94bc916f38 --- /dev/null +++ b/crawl-ref/source/util/levcomp.ypp @@ -0,0 +1,238 @@ +%{ + +#include "levcomp.h" + +int yylex(); + +extern int yylineno; + +void yyerror(const char *e) +{ + fprintf(stderr, "Error on line %d: %s\n", yylineno, e); + + // If an error occurs, delete the file we're supposed to be writing to + // so that life is easier for makefile writers. + if (outhandle && outfilename) { + fclose(outhandle); + outhandle = NULL; + } + + if (outfilename) { + unlink(outfilename); + outfilename = NULL; + } +} + +%} + +%union +{ + int i; + const char *text; +} + +%token <i> DEFAULT_DEPTH SYMBOL TAGS +%token <i> NAME DEPTH ORIENT PLACE CHANCE FLAGS MONS +%token <i> ENCOMPASS +%token <i> NORTH EAST SOUTH WEST NORTH_DIS +%token <i> NORTHEAST SOUTHEAST SOUTHWEST NORTHWEST + +%token <i> BAD_CHARACTER + +%token <i> NO_HMIRROR NO_VMIRROR + +%token <i> PANDEMONIC +%token <i> DASH COMMA +%token <i> INTEGER + +%type <i> orient_name flagname + +%token <text> STRING MAP_LINE MONSTER_NAME + +%% + +file : defs levels + { + if (outhandle && outfilename) { + fclose(outhandle); + outhandle = NULL; + } + } + ; + +defs : /* empty */ + | defs def + ; + +def : defdepth + ; + +defdepth : DEFAULT_DEPTH depth_range + { + default_depth = range; + } + ; + +levels : /* no levels */ + | level levels + ; + +level : name metalines map_def metalines + { + if (!outhandle) { + if (outfilename) { + if (!(outhandle = + fopen(outfilename, + write_append? "a" :"w"))) + outfilename = NULL; + } + if (!outhandle) + outhandle = stdout; + } + if (!autowarned) { + fprintf(outhandle, "%s", autogenheader); + autowarned = true; + } + fprintf(outhandle, "%s", map.get_initialiser().c_str()); + } + ; + +name : NAME STRING + { + map.init(); + map.depth = default_depth; + map.name = $2; + } + ; + +metalines : /* no metadata */ + | metaline metalines + ; + +metaline : place + | depth + | chance + | orientation + | flags + | mons + | symbol + | tags + ; + +tags : TAGS tagstrings {} + ; + +tagstrings : /* empty */ + | STRING tagstrings + { + map.tags += " "; + map.tags += $1; + map.tags += " "; + } + ; + +symbol : SYMBOL {} + | SYMBOL STRING + { + map.random_symbols = $2; + } + ; + +mons : MONS {} + | MONS mnames {} + ; + +mnames : mname COMMA mnames + | mname + ; + +mname : MONSTER_NAME + { + map.mons.add_mons($1); + } + ; + +place : PLACE STRING + { + map.place = $2; + } + ; + +depth : DEPTH {} + | DEPTH depth_range + { + map.depth = range; + } + ; + +depth_range : INTEGER DASH INTEGER + { + range.set($1, $3); + } + + | INTEGER + { + range.set($1); + } + ; + +chance : CHANCE INTEGER + { + map.chance = $2; + } + ; + +orientation : ORIENT {} + | ORIENT orient_name + { + map.orient = (map_section_type) $2; + } + ; + +orient_name : ENCOMPASS { $$ = MAP_ENCOMPASS; } + | NORTH { $$ = MAP_NORTH; } + | EAST { $$ = MAP_EAST; } + | SOUTH { $$ = MAP_SOUTH; } + | WEST { $$ = MAP_WEST; } + | NORTHEAST { $$ = MAP_NORTHEAST; } + | SOUTHEAST { $$ = MAP_SOUTHEAST; } + | SOUTHWEST { $$ = MAP_SOUTHWEST; } + | NORTHWEST { $$ = MAP_NORTHWEST; } + | NORTH_DIS { $$ = MAP_NORTH_DIS; } + ; + +flags : FLAGS flagnames {} + ; + +flagnames : /* empty */ + | flagname flagnames + { + switch ($1) { + case NO_HMIRROR: + map.flags &= ~MAPF_MIRROR_HORIZONTAL; + break; + case NO_VMIRROR: + map.flags &= ~MAPF_MIRROR_VERTICAL; + break; + } + } + ; + +flagname : NO_HMIRROR { $$ = NO_HMIRROR; } + | NO_VMIRROR { $$ = NO_VMIRROR; } + ; + +map_def : map_lines + ; + +map_lines : map_line + | map_line map_lines + ; + +map_line : MAP_LINE + { + map.map.add_line($1); + } + ; + +%% |