summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/util/levcomp.ypp
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/util/levcomp.ypp')
-rw-r--r--crawl-ref/source/util/levcomp.ypp238
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);
+ }
+ ;
+
+%%