%{ #include "AppHdr.h" #include "clua.h" #include "libutil.h" #include "luadgn.h" #include "mapdef.h" #include "maps.h" #include "stuff.h" #include #define YYERROR_VERBOSE 1 int yylex(); extern int yylineno; struct map_file_place { std::string filename; int lineno; map_file_place(const std::string &s = "", int line = 0) : filename(s), lineno(line) { } }; typedef std::map map_load_info_t; static map_load_info_t loaded_maps; void yyerror(const char *e) { if (strstr(e, lc_desfile.c_str()) == e) fprintf(stderr, "%s\n", e); else fprintf(stderr, "%s:%d: %s\n", lc_desfile.c_str(), yylineno, e); // Bail bail bail. end(1); } level_range set_range(const char *s, int start, int end) { try { lc_range.set(s, start, end); } catch (const std::string &err) { yyerror(err.c_str()); } return (lc_range); } %} %union { int i; const char *text; raw_range range; } %token BRANCHDEF BRANCH DESC DEFAULT %token DEFAULT_DEPTH SHUFFLE SUBST TAGS KFEAT KITEM KMONS %token NAME DEPTH ORIENT PLACE CHANCE MONS ITEM %token PRELUDE MAIN %token CHARACTER %token DASH COMMA QUOTE OPAREN CPAREN %token INTEGER %token STRING MAP_LINE MONSTER_NAME ITEM_INFO %token IDENTIFIER LUA_LINE %% file : definitions { } ; definitions : /* empty */ {} | definitions definition {} ; definition : def {} | level {} ; def : defdepth {} ; defdepth : DEFAULT_DEPTH STRING { dgn_reset_default_depth(); std::string err = dgn_set_default_depth($2); if (!err.empty()) yyerror(make_stringf("Bad default-depth: %s (%s)", $2, err.c_str()).c_str()); } ; level : name metalines map_def metalines { lc_map.set_file(lc_desfile); std::string err = lc_map.validate(); if (!err.empty()) yyerror(err.c_str()); if (!lc_map.has_depth() && !lc_default_depths.empty()) lc_map.add_depths(lc_default_depths.begin(), lc_default_depths.end()); add_parsed_map(lc_map); } ; name : NAME STRING { lc_map.init(); lc_map.name = $2; map_load_info_t::const_iterator i = loaded_maps.find($2); if (i != loaded_maps.end()) { yyerror( make_stringf( "Map named '%s' already loaded at %s:%d", $2, i->second.filename.c_str(), i->second.lineno).c_str() ); } loaded_maps[$2] = map_file_place(lc_desfile, yylineno); } ; metalines : /* no metadata */ | metaline metalines ; metaline : place | depth | chance | orientation | mons | items | subst | tags | shuffle | kfeat | kitem | kmons | main_lua | prelude_lua ; main_lua : MAIN main_lua_lines { } main_lua_lines : /* empty */ { } | main_lua_lines main_lua_line { } ; main_lua_line : LUA_LINE { lc_map.main.add(yylineno, $1); } prelude_lua : PRELUDE prelude_lua_lines { } prelude_lua_lines : /* empty */ { } | prelude_lua_lines prelude_lua_line { } ; prelude_lua_line : LUA_LINE { lc_map.prelude.add(yylineno, $1); } kfeat : KFEAT { } | KFEAT STRING { lc_map.main.add( yylineno, make_stringf("kfeat(\"%s\")", quote_lua_string($2).c_str())); } kmons : KMONS { } | KMONS STRING { lc_map.main.add( yylineno, make_stringf("kmons(\"%s\")", quote_lua_string($2).c_str())); } kitem : KITEM { } | KITEM STRING { lc_map.main.add( yylineno, make_stringf("kitem(\"%s\")", quote_lua_string($2).c_str())); } shuffle : SHUFFLE shuffle_specifiers {} ; shuffle_specifiers : shuffle_spec | shuffle_specifiers COMMA shuffle_spec ; shuffle_spec : ITEM_INFO { lc_map.main.add( yylineno, make_stringf("shuffle(\"%s\")", quote_lua_string($1).c_str())); } tags : TAGS tagstrings {} ; tagstrings : /* empty */ | tagstrings tagstring ; tagstring : STRING { lc_map.main.add( yylineno, make_stringf("tags(\"%s\")", quote_lua_string($1).c_str())); } ; subst : SUBST subst_specifiers { } ; subst_specifiers : subst_spec | subst_spec COMMA subst_specifiers ; subst_spec : ITEM_INFO { lc_map.main.add( yylineno, make_stringf("subst(\"%s\")", quote_lua_string($1).c_str())); } ; items : ITEM {} | ITEM item_specifiers {} ; item_specifiers : item_specifier COMMA item_specifiers | item_specifier ; item_specifier : ITEM_INFO { lc_map.main.add( yylineno, make_stringf("item(\"%s\")", quote_lua_string($1).c_str())); } mons : MONS {} | MONS mnames {} ; mnames : mname COMMA mnames | mname ; mname : MONSTER_NAME { lc_map.main.add( yylineno, make_stringf("mons(\"%s\")", quote_lua_string($1).c_str())); } ; place : PLACE STRING { lc_map.main.add( yylineno, make_stringf("place(\"%s\")", quote_lua_string($2).c_str())); } ; depth : DEPTH {} | DEPTH STRING { lc_map.main.add( yylineno, make_stringf("depth(\"%s\")", quote_lua_string($2).c_str())); } ; chance : CHANCE INTEGER { lc_map.main.add( yylineno, make_stringf("chance(\"%d\")", $2)); } ; orientation : ORIENT {} | ORIENT STRING { lc_map.main.add( yylineno, make_stringf("orient(\"%s\")", quote_lua_string($2).c_str())); } ; map_def : map_lines ; map_lines : map_line | map_line map_lines ; map_line : MAP_LINE { lc_map.main.add( yylineno, make_stringf("map(\"%s\")", quote_lua_string($1).c_str())); } ; %%