*/
#include <stdio.h>
-
+#include <string.h>
+#include <stdlib.h>
#include "monoburg.h"
extern void yyparse (void);
static GHashTable *nonterm_hash;
static GList *nonterm_list;
static GList *rule_list;
+static GList *prefix_list;
FILE *inputfd;
FILE *outputfd;
+GHashTable *definedvars;
static FILE *deffd;
+static FILE *cfd;
+
+static int dag_mode = 0;
+static int predefined_terms = 0;
+static int default_cost = 0;
static void output (char *fmt, ...)
{
va_end (ap);
}
-void
-create_rule (char *id, Tree *tree, char *code, char *cost, char *cfunc)
+Rule*
+make_rule (char *id, Tree *tree)
{
Rule *rule = g_new0 (Rule, 1);
+ rule->lhs = nonterm (id);
+ rule->tree = tree;
+
+ return rule;
+}
+void
+rule_add (Rule *rule, char *code, char *cost, char *cfunc)
+{
if (!cfunc && !cost)
- cost = "0";
+ cost = g_strdup_printf ("%d", default_cost);
- rule->lhs = nonterm (id);
- rule->tree = tree;
rule_list = g_list_append (rule_list, rule);
rule->cost = g_strdup (cost);
rule->cfunc = g_strdup (cfunc);
if (cfunc) {
if (cost)
yyerror ("duplicated costs (constant costs and cost function)");
- else
- rule->cost = g_strdup_printf ("mono_burg_cost_%d (tree)",
- g_list_length (rule_list));
+ else {
+ if (dag_mode)
+ rule->cost = g_strdup_printf ("mono_burg_cost_%d (p, data)",
+ g_list_length (rule_list));
+ else
+ rule->cost = g_strdup_printf ("mono_burg_cost_%d (tree, data)",
+ g_list_length (rule_list));
+ }
}
rule->lhs->rules = g_list_append (rule->lhs->rules, rule);
- if (tree->op)
- tree->op->rules = g_list_append (tree->op->rules, rule);
+ if (rule->tree->op)
+ rule->tree->op->rules = g_list_append (rule->tree->op->rules, rule);
else
- tree->nonterm->chain = g_list_append (tree->nonterm->chain, rule);
+ rule->tree->nonterm->chain = g_list_append (rule->tree->nonterm->chain, rule);
+}
+
+void
+create_rule (char *id, Tree *tree, char *code, char *cost, char *cfunc)
+{
+ Rule *rule = make_rule (id, tree);
+
+ rule_add (rule, code, cost, cfunc);
}
Tree *
create_tree (char *id, Tree *left, Tree *right)
{
int arity = (left != NULL) + (right != NULL);
- Term *term = g_hash_table_lookup (term_hash, id);
+ Term *term = NULL;
Tree *tree = g_new0 (Tree, 1);
-
+
+ if (term_hash)
+ term = g_hash_table_lookup (term_hash, id);
+
+ /* try if id has termprefix */
+ if (!term) {
+ GList *pl;
+ for (pl = prefix_list; pl; pl = pl->next) {
+ char *pfx = (char *)pl->data;
+ if (!strncmp (pfx, id, strlen (pfx))) {
+ term = create_term (id, -1);
+ break;
+ }
+ }
+
+ }
+
if (term) {
if (term->arity == -1)
term->arity = arity;
}
void
+create_term_prefix (char *id)
+{
+ if (!predefined_terms)
+ yyerror ("%termprefix is only available with -p option");
+
+ prefix_list = g_list_prepend (prefix_list, g_strdup (id));
+}
+
+Term *
create_term (char *id, int num)
{
Term *term;
- if (nonterm_list)
+ if (!predefined_terms && nonterm_list)
yyerror ("terminal definition after nonterminal definition");
if (num < -1)
if (!term_hash)
term_hash = g_hash_table_new (g_str_hash , g_str_equal);
- g_hash_table_foreach (term_hash, (GHFunc) check_term_num, (gpointer) num);
+ g_hash_table_foreach (term_hash, (GHFunc) check_term_num, GINT_TO_POINTER (num));
term = g_new0 (Term, 1);
term_list = g_list_append (term_list, term);
g_hash_table_insert (term_hash, term->name, term);
+
+ return term;
}
NonTerm *
output ("#ifndef MBTREE_RIGHT\n#define MBTREE_RIGHT(t) ((t)->right)\n#endif\n");
output ("#ifndef MBTREE_STATE\n#define MBTREE_STATE(t) ((t)->state)\n#endif\n");
output ("#ifndef MBCGEN_TYPE\n#define MBCGEN_TYPE int\n#endif\n");
-
+ output ("#ifndef MBALLOC_STATE\n#define MBALLOC_STATE g_new (MBState, 1)\n#endif\n");
+ output ("#ifndef MBCOST_DATA\n#define MBCOST_DATA gpointer\n#endif\n");
output ("\n");
output ("#define MBMAXCOST 32768\n");
Term *t = (Term *)l->data;
if (t->number == -1)
t->number = next_term_num ();
-
- output ("#define MB_TERM_%s\t %d\n", t->name, t->number);
+
+ if (predefined_terms)
+ output ("#define MB_TERM_%s\t %s\n", t->name, t->name);
+ else
+ output ("#define MB_TERM_%s\t %d\n", t->name, t->number);
}
output ("\n");
output ("typedef struct _MBState MBState;\n");
output ("struct _MBState {\n");
output ("\tint\t\t op;\n");
+
+ if (dag_mode) {
+ output ("\tMBTREE_TYPE\t *tree;\n");
+ output ("\tgint32 reg1, reg2;\n");
+ }
+
output ("\tMBState\t\t*left, *right;\n");
output ("\tguint16\t\tcost[%d];\n", g_list_length (nonterm_list) + 1);
for (l = nonterm_list; l; l = l->next) {
NonTerm *n = (NonTerm *)l->data;
- output ("int mono_burg_decode_%s[] = {\n", n->name);
+ output ("const short mono_burg_decode_%s[] = {\n", n->name);
output ("\t0,\n");
for (rl = n->rules; rl; rl = rl->next) {
Rule *rule = (Rule *)rl->data;
emit_tree_match (char *st, Tree *t)
{
char *tn;
+ int not_first = strcmp (st, "p->");
+
+ /* we can omit this check at the top level */
+ if (not_first) {
+ if (predefined_terms)
+ output ("\t\t\t%sop == %s /* %s */", st, t->op->name, t->op->name);
+ else
+ output ("\t\t\t%sop == %d /* %s */", st, t->op->number, t->op->name);
+ }
- output ("\t\t\t%sop == %d /* %s */", st, t->op->number, t->op->name);
-
if (t->left && t->left->op) {
tn = g_strconcat (st, "left->", NULL);
- output (" &&\n");
+ if (not_first)
+ output (" &&\n");
+ not_first = 1;
emit_tree_match (tn, t->left);
g_free (tn);
}
if (t->right && t->right->op) {
tn = g_strconcat (st, "right->", NULL);
- output (" &&\n");
+ if (not_first)
+ output (" &&\n");
emit_tree_match (tn, t->right);
g_free (tn);
}
GList *l;
int i;
- output ("static MBState *\n");
- output ("mono_burg_label_priv (MBTREE_TYPE *tree) {\n");
+ if (dag_mode) {
+ output ("static void\n");
+ output ("mono_burg_label_priv (MBTREE_TYPE *tree, MBCOST_DATA *data, MBState *p) {\n");
+ } else {
+ output ("static MBState *\n");
+ output ("mono_burg_label_priv (MBTREE_TYPE *tree, MBCOST_DATA *data) {\n");
+ }
output ("\tint arity;\n");
output ("\tint c;\n");
- output ("\tMBState *p, *left, *right;\n\n");
+ if (!dag_mode)
+ output ("\tMBState *p;\n");
+ output ("\tMBState *left = NULL, *right = NULL;\n\n");
output ("\tswitch (mono_burg_arity [MBTREE_OP(tree)]) {\n");
output ("\tcase 0:\n");
- output ("\t\tleft = NULL;\n");
- output ("\t\tright = NULL;\n");
output ("\t\tbreak;\n");
output ("\tcase 1:\n");
- output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree));\n");
- output ("\t\tright = NULL;\n");
+ if (dag_mode) {
+ output ("\t\tleft = MBALLOC_STATE;\n");
+ output ("\t\tmono_burg_label_priv (MBTREE_LEFT(tree), data, left);\n");
+ } else {
+ output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree), data);\n");
+ output ("\t\tright = NULL;\n");
+ }
output ("\t\tbreak;\n");
output ("\tcase 2:\n");
- output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree));\n");
- output ("\t\tright = mono_burg_label_priv (MBTREE_RIGHT(tree));\n");
+ if (dag_mode) {
+ output ("\t\tleft = MBALLOC_STATE;\n");
+ output ("\t\tmono_burg_label_priv (MBTREE_LEFT(tree), data, left);\n");
+ output ("\t\tright = MBALLOC_STATE;\n");
+ output ("\t\tmono_burg_label_priv (MBTREE_RIGHT(tree), data, right);\n");
+ } else {
+ output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree), data);\n");
+ output ("\t\tright = mono_burg_label_priv (MBTREE_RIGHT(tree), data);\n");
+ }
output ("\t}\n\n");
output ("\tarity = (left != NULL) + (right != NULL);\n");
output ("\tg_assert (arity == mono_burg_arity [MBTREE_OP(tree)]);\n\n");
- output ("\tp = g_new0 (MBState, 1);\n");
+ if (!dag_mode)
+ output ("\tp = MBALLOC_STATE;\n");
+
+ output ("\tmemset (p, 0, sizeof (MBState));\n");
output ("\tp->op = MBTREE_OP(tree);\n");
output ("\tp->left = left;\n");
output ("\tp->right = right;\n");
+
+ if (dag_mode)
+ output ("\tp->tree = tree;\n");
for (l = nonterm_list, i = 0; l; l = l->next) {
output ("\tp->cost [%d] = 32767;\n", ++i);
for (l = term_list; l; l = l->next) {
Term *t = (Term *)l->data;
GList *rl;
- output ("\tcase %d: /* %s */\n", t->number, t->name);
+
+ if (predefined_terms)
+ output ("\tcase %s: /* %s */\n", t->name, t->name);
+ else
+ output ("\tcase %d: /* %s */\n", t->number, t->name);
for (rl = t->rules; rl; rl = rl->next) {
Rule *rule = (Rule *)rl->data;
}
output ("\tdefault:\n");
- output ("\t\tg_error (\"unknown operator\");\n");
+ output ("#ifdef MBGET_OP_NAME\n");
+ output ("\t\tg_error (\"unknown operator: %%s\", MBGET_OP_NAME(MBTREE_OP(tree)));\n");
+ output ("#else\n");
+ output ("\t\tg_error (\"unknown operator: 0x%%04x\", MBTREE_OP(tree));\n");
+ output ("#endif\n");
output ("\t}\n\n");
- output ("\tMBTREE_STATE(tree) = p;\n");
-
- output ("\treturn p;\n");
+ if (!dag_mode) {
+ output ("\tMBTREE_STATE(tree) = p;\n");
+ output ("\treturn p;\n");
+ }
output ("}\n\n");
output ("MBState *\n");
- output ("mono_burg_label (MBTREE_TYPE *tree)\n{\n");
- output ("\tMBState *p = mono_burg_label_priv (tree);\n");
+ output ("mono_burg_label (MBTREE_TYPE *tree, MBCOST_DATA *data)\n{\n");
+ if (dag_mode) {
+ output ("\tMBState *p = MBALLOC_STATE;\n");
+ output ("\tmono_burg_label_priv (tree, data, p);\n");
+ } else {
+ output ("\tMBState *p = mono_burg_label_priv (tree, data);\n");
+ }
output ("\treturn p->rule_%s ? p : NULL;\n", ((NonTerm *)nonterm_list->data)->name);
output ("}\n\n");
}
} else if (tree->op && tree->op->arity) {
char *res2 = NULL;
- res = compute_kids (g_strdup_printf ("MBTREE_LEFT(%s)", ts),
- tree->left, n);
- if (tree->op->arity == 2)
- res2 = compute_kids (g_strdup_printf ("MBTREE_RIGHT(%s)", ts),
- tree->right, n);
+ if (dag_mode) {
+ res = compute_kids (g_strdup_printf ("%s->left", ts),
+ tree->left, n);
+ if (tree->op->arity == 2)
+ res2 = compute_kids (g_strdup_printf ("%s->right", ts),
+ tree->right, n);
+ } else {
+ res = compute_kids (g_strdup_printf ("MBTREE_LEFT(%s)", ts),
+ tree->left, n);
+ if (tree->op->arity == 2)
+ res2 = compute_kids (g_strdup_printf ("MBTREE_RIGHT(%s)", ts),
+ tree->right, n);
+ }
+
return g_strconcat (res, res2, NULL);
}
return "";
output ("}\n\n");
- output ("MBTREE_TYPE **\n");
- output ("mono_burg_kids (MBTREE_TYPE *tree, int rulenr, MBTREE_TYPE *kids [])\n{\n");
- output ("\tg_return_val_if_fail (tree != NULL, NULL);\n");
- output ("\tg_return_val_if_fail (MBTREE_STATE(tree) != NULL, NULL);\n");
- output ("\tg_return_val_if_fail (kids != NULL, NULL);\n\n");
+ if (dag_mode) {
+ output ("MBState **\n");
+ output ("mono_burg_kids (MBState *state, int rulenr, MBState *kids [])\n{\n");
+ output ("\tg_return_val_if_fail (state != NULL, NULL);\n");
+ output ("\tg_return_val_if_fail (kids != NULL, NULL);\n\n");
+
+ } else {
+ output ("MBTREE_TYPE **\n");
+ output ("mono_burg_kids (MBTREE_TYPE *tree, int rulenr, MBTREE_TYPE *kids [])\n{\n");
+ output ("\tg_return_val_if_fail (tree != NULL, NULL);\n");
+ output ("\tg_return_val_if_fail (kids != NULL, NULL);\n\n");
+ }
output ("\tswitch (rulenr) {\n");
int kn = 0;
char *k;
- k = compute_kids ("tree", rule->tree, &kn);
+ if (dag_mode)
+ k = compute_kids ("state", rule->tree, &kn);
+ else
+ k = compute_kids ("tree", rule->tree, &kn);
+
for (j = 0; j < c; j++)
if (!strcmp (sa [j], k))
break;
emit_emitter_func ()
{
GList *l;
- int i;
+ int i, rulen;
+ GHashTable *cache = g_hash_table_new (g_str_hash, g_str_equal);
for (l = rule_list, i = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
if (rule->code) {
+ if ((rulen = GPOINTER_TO_INT (g_hash_table_lookup (cache, rule->code)))) {
+ emit_rule_string (rule, "");
+ output ("#define mono_burg_emit_%d mono_burg_emit_%d\n\n", i, rulen);
+ i++;
+ continue;
+ }
output ("static void ");
emit_rule_string (rule, "");
- output ("mono_burg_emit_%d (MBTREE_TYPE *tree, MBCGEN_TYPE *s)\n", i);
+ if (dag_mode)
+ output ("mono_burg_emit_%d (MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s)\n", i);
+ else
+ output ("mono_burg_emit_%d (MBTREE_TYPE *tree, MBCGEN_TYPE *s)\n", i);
output ("{\n");
output ("%s\n", rule->code);
output ("}\n\n");
+ g_hash_table_insert (cache, rule->code, GINT_TO_POINTER (i));
}
i++;
}
- output ("MBEmitFunc mono_burg_func [] = {\n");
+ g_hash_table_destroy (cache);
+
+ output ("MBEmitFunc const mono_burg_func [] = {\n");
output ("\tNULL,\n");
for (l = rule_list, i = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
Rule *rule = (Rule *)l->data;
if (rule->cfunc) {
- output ("static guint16\n");
+ output ("inline static guint16\n");
emit_rule_string (rule, "");
-
- output ("mono_burg_cost_%d (MBTREE_TYPE *tree)\n", i + 1);
+
+ if (dag_mode)
+ output ("mono_burg_cost_%d (MBState *state, MBCOST_DATA *data)\n", i + 1);
+ else
+ output ("mono_burg_cost_%d (MBTREE_TYPE *tree, MBCOST_DATA *data)\n", i + 1);
output ("{\n");
output ("%s\n", rule->cfunc);
output ("}\n\n");
}
}
+static int
+count_nonterms (Tree *tree)
+{
+ if (!tree)
+ return 0;
+
+ if (tree->nonterm) {
+ return 1;
+ } else {
+ return count_nonterms (tree->left) + count_nonterms (tree->right);
+ }
+}
+
static void
emit_vardefs ()
{
GList *l;
int i, j, c, n, *si;
char **sa;
+ int *nts_offsets;
+ int current_offset;
+
+ if (predefined_terms) {
+ output ("#if HAVE_ARRAY_ELEM_INIT\n");
+ output ("const guint8 mono_burg_arity [MBMAX_OPCODES] = {\n");
+ for (l = term_list, i = 0; l; l = l->next) {
+ Term *t = (Term *)l->data;
+ output ("\t [%s] = %d, /* %s */\n", t->name, t->arity, t->name);
+ }
+ output ("};\n\n");
+ output ("void\nmono_burg_init (void) {\n");
+ output ("}\n\n");
+ output ("#else\n");
+ output ("guint8 mono_burg_arity [MBMAX_OPCODES];\n");
- output ("guint8 mono_burg_arity [] = {\n");
- for (l = term_list, i = 0; l; l = l->next) {
- Term *t = (Term *)l->data;
+ output ("void\nmono_burg_init (void)\n{\n");
- while (i < t->number) {
- output ("\t0,\n");
- i++;
+ for (l = term_list, i = 0; l; l = l->next) {
+ Term *t = (Term *)l->data;
+ output ("\tmono_burg_arity [%s] = %d; /* %s */\n", t->name, t->arity, t->name);
}
+ output ("}\n\n");
+ output ("#endif /* HAVE_ARRAY_ELEM_INIT */\n");
+
+ } else {
+ output ("const guint8 mono_burg_arity [] = {\n");
+ for (l = term_list, i = 0; l; l = l->next) {
+ Term *t = (Term *)l->data;
+
+ while (i < t->number) {
+ output ("\t0,\n");
+ i++;
+ }
- output ("\t%d, /* %s */\n", t->arity, t->name);
+ output ("\t%d, /* %s */\n", t->arity, t->name);
- i++;
- }
- output ("};\n\n");
+ i++;
+ }
+ output ("};\n\n");
- output ("char *mono_burg_term_string [] = {\n");
- output ("\tNULL,\n");
- for (l = term_list, i = 0; l; l = l->next) {
- Term *t = (Term *)l->data;
- output ("\t\"%s\",\n", t->name);
+ output ("const char *const mono_burg_term_string [] = {\n");
+ output ("\tNULL,\n");
+ for (l = term_list, i = 0; l; l = l->next) {
+ Term *t = (Term *)l->data;
+ output ("\t\"%s\",\n", t->name);
+ }
+ output ("};\n\n");
}
- output ("};\n\n");
- output ("char *mono_burg_rule_string [] = {\n");
+ output ("#if MONOBURG_LOG\n");
+ output ("const char * const mono_burg_rule_string [] = {\n");
output ("\tNULL,\n");
for (l = rule_list, i = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
emit_tree_string (rule->tree);
output ("\",\n");
}
- output ("};\n\n");
+ output ("};\n");
+ output ("#endif /* MONOBURG_LOG */\n\n");
n = g_list_length (rule_list);
sa = g_new0 (char *, n);
si = g_new0 (int, n);
+ nts_offsets = g_new0 (int, n);
+ /* at offset 0 we store 0 to mean end of list */
+ current_offset = 1;
+ output ("const guint16 mono_burg_nts_data [] = {\n\t0,\n");
/* compress the _nts array */
for (l = rule_list, i = 0, c = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
si [i++] = j;
if (j == c) {
- output ("static guint16 mono_burg_nts_%d [] = { %s0 };\n", c, s);
+ output ("\t%s0,\n", s);
+ nts_offsets [c] = current_offset;
sa [c++] = s;
+ current_offset += count_nonterms (rule->tree) + 1;
}
}
- output ("\n");
+ output ("\t0\n};\n\n");
- output ("guint16 *mono_burg_nts [] = {\n");
+ output ("const guint8 mono_burg_nts [] = {\n");
output ("\t0,\n");
for (l = rule_list, i = 0; l; l = l->next) {
Rule *rule = (Rule *)l->data;
- output ("\tmono_burg_nts_%d, ", si [i++]);
+ output ("\t%d, /* %s */ ", nts_offsets [si [i]], sa [si [i]]);
+ ++i;
emit_rule_string (rule, "");
}
output ("};\n\n");
static void
emit_prototypes ()
{
- output ("typedef void (*MBEmitFunc) (MBTREE_TYPE *tree, MBCGEN_TYPE *s);\n\n");
-
- output ("extern char *mono_burg_term_string [];\n");
- output ("extern char *mono_burg_rule_string [];\n");
- output ("extern guint16 *mono_burg_nts [];\n");
- output ("extern MBEmitFunc mono_burg_func [];\n");
-
- output ("MBState *mono_burg_label (MBTREE_TYPE *tree);\n");
+ if (dag_mode)
+ output ("typedef void (*MBEmitFunc) (MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s);\n\n");
+ else
+ output ("typedef void (*MBEmitFunc) (MBTREE_TYPE *tree, MBCGEN_TYPE *s);\n\n");
+
+ output ("extern const char * const mono_burg_term_string [];\n");
+ output ("#if MONOBURG_LOG\n");
+ output ("extern const char * const mono_burg_rule_string [];\n");
+ output ("#endif /* MONOBURG_LOG */\n");
+ output ("extern const guint16 mono_burg_nts_data [];\n");
+ output ("extern const guint8 mono_burg_nts [];\n");
+ output ("extern MBEmitFunc const mono_burg_func [];\n");
+
+ output ("MBState *mono_burg_label (MBTREE_TYPE *tree, MBCOST_DATA *data);\n");
output ("int mono_burg_rule (MBState *state, int goal);\n");
- output ("MBTREE_TYPE **mono_burg_kids (MBTREE_TYPE *tree, int rulenr, MBTREE_TYPE *kids []);\n");
+ if (dag_mode)
+ output ("MBState **mono_burg_kids (MBState *state, int rulenr, MBState *kids []);\n");
+ else
+ output ("MBTREE_TYPE **mono_burg_kids (MBTREE_TYPE *tree, int rulenr, MBTREE_TYPE *kids []);\n");
+
+ output ("extern void mono_burg_init (void);\n");
output ("\n");
}
for (l = nonterm_list; l; l = l->next) {
NonTerm *n = (NonTerm *)l->data;
if (!n->reached)
- g_error ("unreachable nonterm \"%s\"", n->name);
+ g_warning ("unreachable nonterm \"%s\"", n->name);
}
}
usage ()
{
fprintf (stderr,
- "Usage is: monoburg [-d file] [file] \n");
+ "Usage is: monoburg -d file.h -s file.c [inputfile] \n");
exit (1);
}
+static void
+warning_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+ (void) fprintf ((FILE *) user_data, "** WARNING **: %s\n", message);
+}
+
int
main (int argc, char *argv [])
{
+ char *cfile = NULL;
char *deffile = NULL;
- char *infile = NULL;
+ GList *infiles = NULL;
int i;
+ definedvars = g_hash_table_new (g_str_hash, g_str_equal);
+ g_log_set_handler (NULL, G_LOG_LEVEL_WARNING, warning_handler, stderr);
+
for (i = 1; i < argc; i++){
if (argv [i][0] == '-'){
if (argv [i][1] == 'h') {
usage ();
+ } else if (argv [i][1] == 'e') {
+ dag_mode = 1;
+ } else if (argv [i][1] == 'p') {
+ predefined_terms = 1;
} else if (argv [i][1] == 'd') {
deffile = argv [++i];
+ } else if (argv [i][1] == 's') {
+ cfile = argv [++i];
+ } else if (argv [i][1] == 'c') {
+ default_cost = atoi (argv [++i]);
+ } else if (argv [i][1] == 'D') {
+ g_hash_table_insert (definedvars, &argv [i][2],
+ GUINT_TO_POINTER (1));
} else {
usage ();
}
} else {
- if (infile)
- usage ();
- else
- infile = argv [i];
+ infiles = g_list_append (infiles, argv [i]);
}
}
outputfd = stdout;
- if (infile) {
- if (!(inputfd = fopen (infile, "r"))) {
- perror ("cant open input file");
- exit (-1);
+ if (infiles) {
+ GList *l = infiles;
+ while (l) {
+ char *infile = (char *)l->data;
+ if (!(inputfd = fopen (infile, "r"))) {
+ perror ("cant open input file");
+ exit (-1);
+ }
+
+ yyparse ();
+
+ reset_parser ();
+
+ l->data = inputfd;
+ l = l->next;
}
} else {
inputfd = stdin;
+ yyparse ();
}
- yyparse ();
-
check_result ();
if (!nonterm_list)
if (deffd) {
output ("#endif /* _MONO_BURG_DEFS_ */\n");
fclose (deffd);
- outputfd = stdout;
+
+ if (cfile == NULL)
+ outputfd = stdout;
+ else {
+ if (!(cfd = fopen (cfile, "w"))) {
+ perror ("cant open c output file");
+ (void) remove (deffile);
+ exit (-1);
+ }
+
+ outputfd = cfd;
+ }
output ("#include \"%s\"\n\n", deffile);
}
emit_kids ();
- yyparsetail ();
-
- if (infile)
- fclose (inputfd);
+ if (infiles) {
+ GList *l = infiles;
+ while (l) {
+ inputfd = l->data;
+ yyparsetail ();
+ fclose (inputfd);
+ l = l->next;
+ }
+ } else {
+ yyparsetail ();
+ }
+ if (cfile)
+ fclose (cfd);
return 0;
}