X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmonoburg%2Fmonoburg.y;h=83186439c8f1b772b62a0cfbdd68ee598f6a67a7;hb=9ddaa71e9ee65d90d1f9a48ff02d2de0038cc94e;hp=2ca7b7d64d997196f61ab76991389bac42abd5e2;hpb=10fbbd6de65465daad721159ec9f1207dbc68f5a;p=mono.git diff --git a/mono/monoburg/monoburg.y b/mono/monoburg/monoburg.y index 2ca7b7d64d9..83186439c8f 100644 --- a/mono/monoburg/monoburg.y +++ b/mono/monoburg/monoburg.y @@ -27,6 +27,8 @@ static int yylinepos = 0; char *text; int ivalue; Tree *tree; + Rule *rule; + GList *rule_list; } %token IDENT @@ -35,25 +37,46 @@ static int yylinepos = 0; %token START %token COST %token TERM +%token TERMPREFIX %token INTEGER %type tree %type optcost %type optcfunc %type optcode +%type rule +%type rule_list %% decls : /* empty */ | START IDENT { start_nonterm ($2); } decls | TERM tlist decls - | IDENT ':' tree optcost optcode optcfunc { create_rule ($1, $3, $5, $4, $6); } decls + | TERMPREFIX plist decls + | rule_list optcost optcode optcfunc { + GList *tmp; + for (tmp = $1; tmp; tmp = tmp->next) { + rule_add (tmp->data, $3, $2, $4); + } + g_list_free ($1); + } decls ; -optcode : /* empty */ { $$ = NULL } +rule : IDENT ':' tree { $$ = make_rule ($1, $3); } + ; + +rule_list : rule { $$ = g_list_append (NULL, $1); } + | rule ',' rule_list { $$ = g_list_prepend ($3, $1); } + ; + +optcode : /* empty */ { $$ = NULL; } | CODE ; +plist : /* empty */ + | plist IDENT { create_term_prefix ($2);} + ; + tlist : /* empty */ | tlist IDENT { create_term ($2, -1);} | tlist IDENT '=' INTEGER { create_term ($2, $4); } @@ -101,6 +124,64 @@ reset_parser () state = 0; } +struct pplist { + struct pplist *next; + gboolean ignore; +}; + +static struct pplist *pp = NULL; + +static char* +getvar (const char *input) +{ + char *var = g_strchug (g_strdup (input)); + char *ptr; + + for (ptr = var; *ptr && *ptr != '\n'; ++ptr) { + if (g_ascii_isspace (*ptr)) { + break; + } + } + *ptr = '\0'; + + return var; +} + +static void +push_if (char *input, gboolean flip) +{ + struct pplist *new_pp = g_new (struct pplist, 1); + char *var = getvar (input); + + new_pp->ignore = (g_hash_table_lookup (definedvars, var) == NULL) ^ flip; + new_pp->next = pp; + + new_pp->ignore |= (pp ? pp->ignore : 0); + pp = new_pp; + g_free (var); +} + +static void +flip_if () +{ + if (!pp) + yyerror ("%%else without %%if"); + + pp->ignore = !pp->ignore | (pp->next ? pp->next->ignore : 0); +} + +static void +pop_if () +{ + struct pplist *prev_pp = pp; + + if (!pp) + yyerror ("%%endif without %%if"); + + pp = pp->next; + g_free (prev_pp); +} + static char nextchar () { @@ -117,11 +198,40 @@ nextchar () ll = (input [0] == '%' && input [1] == '%'); next_state = state; + if (state == 1) { + if (!ll && input [0] == '%') { + if (!strncmp (&input [1], "ifdef", 5)) { + push_if (&input [6], FALSE); + ll = TRUE; + continue; + } + else if (!strncmp (&input [1], "ifndef", 6)) { + push_if (&input [7], TRUE); + ll = TRUE; + continue; + } + else if (!strncmp (&input [1], "else", 4)) { + flip_if (); + ll = TRUE; + continue; + } + else if (!strncmp (&input [1], "endif", 5)) { + pop_if (); + ll = TRUE; + continue; + } + } + if (pp && pp->ignore) { + ll = TRUE; + continue; + } + } + switch (state) { case 0: if (ll) { next_state = 1; - } else + } else fputs (input, outputfd); break; case 1: @@ -148,6 +258,7 @@ yyparsetail (void) fputs (input, outputfd); while (fgets (input, sizeof (input), inputfd)) fputs (input, outputfd); + input [0] = '\0'; } int @@ -171,6 +282,11 @@ yylex (void) return START; } + if (!strncmp (next, "termprefix", 10) && isspace (next[10])) { + next += 10; + return TERMPREFIX; + } + if (!strncmp (next, "term", 4) && isspace (next[4])) { next += 4; return TERM;