2 * monoburg.c: an iburg like code generator generator
5 * Dietmar Maurer (dietmar@ximian.com)
7 * (C) 2001 Ximian, Inc.
15 extern void yyparse (void);
17 static GHashTable
*term_hash
;
18 static GList
*term_list
;
19 static GHashTable
*nonterm_hash
;
20 static GList
*nonterm_list
;
21 static GList
*rule_list
;
22 static GList
*prefix_list
;
26 GHashTable
*definedvars
;
30 static int dag_mode
= 0;
31 static int predefined_terms
= 0;
32 static int default_cost
= 0;
34 static void output (char *fmt
, ...)
39 vfprintf (outputfd
, fmt
, ap
);
44 make_rule (char *id
, Tree
*tree
)
46 Rule
*rule
= g_new0 (Rule
, 1);
47 rule
->lhs
= nonterm (id
);
54 rule_add (Rule
*rule
, char *code
, char *cost
, char *cfunc
)
57 cost
= g_strdup_printf ("%d", default_cost
);
59 rule_list
= g_list_append (rule_list
, rule
);
60 rule
->cost
= g_strdup (cost
);
61 rule
->cfunc
= g_strdup (cfunc
);
62 rule
->code
= g_strdup (code
);
66 yyerror ("duplicated costs (constant costs and cost function)");
69 rule
->cost
= g_strdup_printf ("mono_burg_cost_%d (p, data)",
70 g_list_length (rule_list
));
72 rule
->cost
= g_strdup_printf ("mono_burg_cost_%d (tree, data)",
73 g_list_length (rule_list
));
77 rule
->lhs
->rules
= g_list_append (rule
->lhs
->rules
, rule
);
80 rule
->tree
->op
->rules
= g_list_append (rule
->tree
->op
->rules
, rule
);
82 rule
->tree
->nonterm
->chain
= g_list_append (rule
->tree
->nonterm
->chain
, rule
);
86 create_rule (char *id
, Tree
*tree
, char *code
, char *cost
, char *cfunc
)
88 Rule
*rule
= make_rule (id
, tree
);
90 rule_add (rule
, code
, cost
, cfunc
);
94 create_tree (char *id
, Tree
*left
, Tree
*right
)
96 int arity
= (left
!= NULL
) + (right
!= NULL
);
98 Tree
*tree
= g_new0 (Tree
, 1);
101 term
= g_hash_table_lookup (term_hash
, id
);
103 /* try if id has termprefix */
106 for (pl
= prefix_list
; pl
; pl
= pl
->next
) {
107 char *pfx
= (char *)pl
->data
;
108 if (!strncmp (pfx
, id
, strlen (pfx
))) {
109 term
= create_term (id
, -1);
117 if (term
->arity
== -1)
120 if (term
->arity
!= arity
)
121 yyerror ("changed arity of terminal %s from %d to %d",
122 id
, term
->arity
, arity
);
128 tree
->nonterm
= nonterm (id
);
135 check_term_num (char *key
, Term
*value
, int num
)
137 if (num
!= -1 && value
->number
== num
)
138 yyerror ("duplicate terminal id \"%s\"", key
);
142 create_term_prefix (char *id
)
144 if (!predefined_terms
)
145 yyerror ("%termprefix is only available with -p option");
147 prefix_list
= g_list_prepend (prefix_list
, g_strdup (id
));
151 create_term (char *id
, int num
)
155 if (!predefined_terms
&& nonterm_list
)
156 yyerror ("terminal definition after nonterminal definition");
159 yyerror ("invalid terminal number %d", num
);
162 term_hash
= g_hash_table_new (g_str_hash
, g_str_equal
);
164 g_hash_table_foreach (term_hash
, (GHFunc
) check_term_num
, GINT_TO_POINTER (num
));
166 term
= g_new0 (Term
, 1);
168 term
->name
= g_strdup (id
);
172 term_list
= g_list_append (term_list
, term
);
174 g_hash_table_insert (term_hash
, term
->name
, term
);
185 nonterm_hash
= g_hash_table_new (g_str_hash
, g_str_equal
);
187 if ((nterm
= g_hash_table_lookup (nonterm_hash
, id
)))
190 nterm
= g_new0 (NonTerm
, 1);
192 nterm
->name
= g_strdup (id
);
193 nonterm_list
= g_list_append (nonterm_list
, nterm
);
194 nterm
->number
= g_list_length (nonterm_list
);
196 g_hash_table_insert (nonterm_hash
, nterm
->name
, nterm
);
202 start_nonterm (char *id
)
204 static gboolean start_def
;
207 yyerror ("start symbol redeclared");
214 emit_tree_string (Tree
*tree
)
217 output ("%s", tree
->op
->name
);
218 if (tree
->op
->arity
) {
220 emit_tree_string (tree
->left
);
223 emit_tree_string (tree
->right
);
228 output ("%s", tree
->nonterm
->name
);
232 emit_rule_string (Rule
*rule
, char *fill
)
234 output ("%s/* ", fill
);
236 output ("%s: ", rule
->lhs
->name
);
238 emit_tree_string (rule
->tree
);
246 GList
*l
= term_list
;
250 Term
*t
= (Term
*)l
->data
;
251 if (t
->number
== i
) {
261 term_compare_func (Term
*t1
, Term
*t2
)
263 return t1
->number
- t2
->number
;
271 output ("#include <glib.h>\n");
274 output ("#ifndef MBTREE_TYPE\n#error MBTREE_TYPE undefined\n#endif\n");
275 output ("#ifndef MBTREE_OP\n#define MBTREE_OP(t) ((t)->op)\n#endif\n");
276 output ("#ifndef MBTREE_LEFT\n#define MBTREE_LEFT(t) ((t)->left)\n#endif\n");
277 output ("#ifndef MBTREE_RIGHT\n#define MBTREE_RIGHT(t) ((t)->right)\n#endif\n");
278 output ("#ifndef MBTREE_STATE\n#define MBTREE_STATE(t) ((t)->state)\n#endif\n");
279 output ("#ifndef MBREG_TYPE\n#define MBREG_TYPE gint32\n#endif\n");
280 output ("#ifndef MBCGEN_TYPE\n#define MBCGEN_TYPE int\n#endif\n");
281 output ("#ifndef MBALLOC_STATE\n#define MBALLOC_STATE g_new (MBState, 1)\n#endif\n");
282 output ("#ifndef MBCOST_DATA\n#define MBCOST_DATA gpointer\n#endif\n");
284 output ("#define MBMAXCOST 32768\n");
287 output ("#define MBCOND(x) if (!(x)) return MBMAXCOST;\n");
291 for (l
= term_list
; l
; l
= l
->next
) {
292 Term
*t
= (Term
*)l
->data
;
294 t
->number
= next_term_num ();
296 term_list
= g_list_sort (term_list
, (GCompareFunc
)term_compare_func
);
298 for (l
= term_list
; l
; l
= l
->next
) {
299 Term
*t
= (Term
*)l
->data
;
301 t
->number
= next_term_num ();
303 if (predefined_terms
)
304 output ("#define MB_TERM_%s\t %s\n", t
->name
, t
->name
);
306 output ("#define MB_TERM_%s\t %d\n", t
->name
, t
->number
);
318 for (l
= nonterm_list
; l
; l
= l
->next
) {
319 NonTerm
*n
= (NonTerm
*)l
->data
;
320 output ("#define MB_NTERM_%s\t%d\n", n
->name
, n
->number
);
322 output ("#define MB_MAX_NTERMS\t%d\n", g_list_length (nonterm_list
));
332 output ("typedef struct _MBState MBState;\n");
333 output ("struct _MBState {\n");
334 output ("\tint\t\t op;\n");
337 output ("\tMBTREE_TYPE\t *tree;\n");
338 output ("\tMBREG_TYPE\t reg1;\n");
339 output ("\tMBREG_TYPE\t reg2;\n");
342 output ("\tMBState\t\t*left, *right;\n");
343 output ("\tguint16\t\tcost[%d];\n", g_list_length (nonterm_list
) + 1);
345 for (l
= nonterm_list
; l
; l
= l
->next
) {
346 NonTerm
*n
= (NonTerm
*)l
->data
;
347 g_assert (g_list_length (n
->rules
) < 256);
348 i
= g_list_length (n
->rules
);
352 output ("\tunsigned int\t rule_%s:%d;\n", n
->name
, j
);
363 for (l
= nonterm_list
; l
; l
= l
->next
) {
364 NonTerm
*n
= (NonTerm
*)l
->data
;
365 output ("const short mono_burg_decode_%s[] = {\n", n
->name
);
367 for (rl
= n
->rules
; rl
; rl
= rl
->next
) {
368 Rule
*rule
= (Rule
*)rl
->data
;
369 output ("\t%d,\n", g_list_index (rule_list
, rule
) + 1);
377 emit_tree_match (char *st
, Tree
*t
)
380 int not_first
= strcmp (st
, "p->");
382 /* we can omit this check at the top level */
384 if (predefined_terms
)
385 output ("\t\t\t%sop == %s /* %s */", st
, t
->op
->name
, t
->op
->name
);
387 output ("\t\t\t%sop == %d /* %s */", st
, t
->op
->number
, t
->op
->name
);
390 if (t
->left
&& t
->left
->op
) {
391 tn
= g_strconcat (st
, "left->", NULL
);
395 emit_tree_match (tn
, t
->left
);
399 if (t
->right
&& t
->right
->op
) {
400 tn
= g_strconcat (st
, "right->", NULL
);
403 emit_tree_match (tn
, t
->right
);
409 emit_rule_match (Rule
*rule
)
411 Tree
*t
= rule
->tree
;
413 if ((t
->left
&& t
->left
->op
) ||
414 (t
->right
&& t
->right
->op
)) {
415 output ("\t\tif (\n");
416 emit_tree_match ("p->", t
);
417 output ("\n\t\t)\n");
422 emit_costs (char *st
, Tree
*t
)
429 tn
= g_strconcat (st
, "left->", NULL
);
430 emit_costs (tn
, t
->left
);
435 tn
= g_strconcat (st
, "right->", NULL
);
436 emit_costs (tn
, t
->right
);
439 output ("%scost[MB_NTERM_%s] + ", st
, t
->nonterm
->name
);
443 emit_cond_assign (Rule
*rule
, char *cost
, char *fill
)
448 rc
= g_strconcat ("c + ", cost
, NULL
);
453 output ("%sif (%s < p->cost[MB_NTERM_%s]) {\n", fill
, rc
, rule
->lhs
->name
);
455 output ("%s\tp->cost[MB_NTERM_%s] = %s;\n", fill
, rule
->lhs
->name
, rc
);
457 output ("%s\tp->rule_%s = %d;\n", fill
, rule
->lhs
->name
,
458 g_list_index (rule
->lhs
->rules
, rule
) + 1);
460 if (rule
->lhs
->chain
)
461 output ("%s\tclosure_%s (p, %s);\n", fill
, rule
->lhs
->name
, rc
);
463 output ("%s}\n", fill
);
476 output ("static void\n");
477 output ("mono_burg_label_priv (MBTREE_TYPE *tree, MBCOST_DATA *data, MBState *p) {\n");
479 output ("static MBState *\n");
480 output ("mono_burg_label_priv (MBTREE_TYPE *tree, MBCOST_DATA *data) {\n");
483 output ("\tint arity;\n");
484 output ("\tint c;\n");
486 output ("\tMBState *p;\n");
487 output ("\tMBState *left = NULL, *right = NULL;\n\n");
489 output ("\tswitch (mono_burg_arity [MBTREE_OP(tree)]) {\n");
490 output ("\tcase 0:\n");
491 output ("\t\tbreak;\n");
492 output ("\tcase 1:\n");
494 output ("\t\tleft = MBALLOC_STATE;\n");
495 output ("\t\tmono_burg_label_priv (MBTREE_LEFT(tree), data, left);\n");
497 output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree), data);\n");
498 output ("\t\tright = NULL;\n");
500 output ("\t\tbreak;\n");
501 output ("\tcase 2:\n");
503 output ("\t\tleft = MBALLOC_STATE;\n");
504 output ("\t\tmono_burg_label_priv (MBTREE_LEFT(tree), data, left);\n");
505 output ("\t\tright = MBALLOC_STATE;\n");
506 output ("\t\tmono_burg_label_priv (MBTREE_RIGHT(tree), data, right);\n");
508 output ("\t\tleft = mono_burg_label_priv (MBTREE_LEFT(tree), data);\n");
509 output ("\t\tright = mono_burg_label_priv (MBTREE_RIGHT(tree), data);\n");
513 output ("\tarity = (left != NULL) + (right != NULL);\n");
514 output ("\tg_assert (arity == mono_burg_arity [MBTREE_OP(tree)]);\n\n");
517 output ("\tp = MBALLOC_STATE;\n");
519 output ("\tmemset (p, 0, sizeof (MBState));\n");
520 output ("\tp->op = MBTREE_OP(tree);\n");
521 output ("\tp->left = left;\n");
522 output ("\tp->right = right;\n");
525 output ("\tp->tree = tree;\n");
527 for (l
= nonterm_list
, i
= 0; l
; l
= l
->next
) {
528 output ("\tp->cost [%d] = 32767;\n", ++i
);
532 output ("\tswitch (MBTREE_OP(tree)) {\n");
533 for (l
= term_list
; l
; l
= l
->next
) {
534 Term
*t
= (Term
*)l
->data
;
537 if (predefined_terms
)
538 output ("\tcase %s: /* %s */\n", t
->name
, t
->name
);
540 output ("\tcase %d: /* %s */\n", t
->number
, t
->name
);
542 for (rl
= t
->rules
; rl
; rl
= rl
->next
) {
543 Rule
*rule
= (Rule
*)rl
->data
;
544 Tree
*t
= rule
->tree
;
546 emit_rule_string (rule
, "\t\t");
548 emit_rule_match (rule
);
552 output ("\t\t\tc = ");
556 output ("%s;\n", rule
->cost
);
558 emit_cond_assign (rule
, NULL
, "\t\t\t");
563 output ("\t\tbreak;\n");
566 output ("\tdefault:\n");
567 output ("#ifdef MBGET_OP_NAME\n");
568 output ("\t\tg_error (\"unknown operator: %%s\", MBGET_OP_NAME(MBTREE_OP(tree)));\n");
570 output ("\t\tg_error (\"unknown operator: 0x%%04x\", MBTREE_OP(tree));\n");
575 output ("\tMBTREE_STATE(tree) = p;\n");
576 output ("\treturn p;\n");
581 output ("MBState *\n");
582 output ("mono_burg_label (MBTREE_TYPE *tree, MBCOST_DATA *data)\n{\n");
584 output ("\tMBState *p = MBALLOC_STATE;\n");
585 output ("\tmono_burg_label_priv (tree, data, p);\n");
587 output ("\tMBState *p = mono_burg_label_priv (tree, data);\n");
589 output ("\treturn p->rule_%s ? p : NULL;\n", ((NonTerm
*)nonterm_list
->data
)->name
);
594 compute_kids (char *ts
, Tree
*tree
, int *n
)
599 return g_strdup_printf ("\t\tkids[%d] = %s;\n", (*n
)++, ts
);
600 } else if (tree
->op
&& tree
->op
->arity
) {
604 res
= compute_kids (g_strdup_printf ("%s->left", ts
),
606 if (tree
->op
->arity
== 2)
607 res2
= compute_kids (g_strdup_printf ("%s->right", ts
),
610 res
= compute_kids (g_strdup_printf ("MBTREE_LEFT(%s)", ts
),
612 if (tree
->op
->arity
== 2)
613 res2
= compute_kids (g_strdup_printf ("MBTREE_RIGHT(%s)", ts
),
617 return g_strconcat (res
, res2
, NULL
);
630 output ("mono_burg_rule (MBState *state, int goal)\n{\n");
632 output ("\tg_return_val_if_fail (state != NULL, 0);\n");
633 output ("\tg_return_val_if_fail (goal > 0, 0);\n\n");
635 output ("\tswitch (goal) {\n");
637 for (nl
= nonterm_list
; nl
; nl
= nl
->next
) {
638 NonTerm
*n
= (NonTerm
*)nl
->data
;
639 output ("\tcase MB_NTERM_%s:\n", n
->name
);
640 output ("\t\treturn mono_burg_decode_%s [state->rule_%s];\n",
644 output ("\tdefault: g_assert_not_reached ();\n");
646 output ("\treturn 0;\n");
651 output ("MBState **\n");
652 output ("mono_burg_kids (MBState *state, int rulenr, MBState *kids [])\n{\n");
653 output ("\tg_return_val_if_fail (state != NULL, NULL);\n");
654 output ("\tg_return_val_if_fail (kids != NULL, NULL);\n\n");
657 output ("MBTREE_TYPE **\n");
658 output ("mono_burg_kids (MBTREE_TYPE *tree, int rulenr, MBTREE_TYPE *kids [])\n{\n");
659 output ("\tg_return_val_if_fail (tree != NULL, NULL);\n");
660 output ("\tg_return_val_if_fail (kids != NULL, NULL);\n\n");
663 output ("\tswitch (rulenr) {\n");
665 n
= g_list_length (rule_list
);
666 sa
= g_new0 (char *, n
);
667 si
= g_new0 (int, n
);
669 /* compress the case statement */
670 for (l
= rule_list
, i
= 0, c
= 0; l
; l
= l
->next
) {
671 Rule
*rule
= (Rule
*)l
->data
;
676 k
= compute_kids ("state", rule
->tree
, &kn
);
678 k
= compute_kids ("tree", rule
->tree
, &kn
);
680 for (j
= 0; j
< c
; j
++)
681 if (!strcmp (sa
[j
], k
))
689 for (i
= 0; i
< c
; i
++) {
690 for (l
= rule_list
, j
= 0; l
; l
= l
->next
, j
++)
692 output ("\tcase %d:\n", j
+ 1);
693 output ("%s", sa
[i
]);
694 output ("\t\tbreak;\n");
697 output ("\tdefault:\n\t\tg_assert_not_reached ();\n");
699 output ("\treturn kids;\n");
709 GHashTable
*cache
= g_hash_table_new (g_str_hash
, g_str_equal
);
711 for (l
= rule_list
, i
= 0; l
; l
= l
->next
) {
712 Rule
*rule
= (Rule
*)l
->data
;
716 if ((cases
= g_hash_table_lookup (cache
, rule
->code
))) {
717 cases
= g_list_append (cases
, GINT_TO_POINTER (i
));
719 cases
= g_list_append (NULL
, GINT_TO_POINTER (i
));
721 g_hash_table_insert (cache
, rule
->code
, cases
);
726 output ("void mono_burg_emit (int ern, MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s)\n {\n");
727 output ("\tswitch (ern) {");
728 for (l
= rule_list
, i
= 0; l
; l
= l
->next
) {
729 Rule
*rule
= (Rule
*)l
->data
;
733 cases
= g_hash_table_lookup (cache
, rule
->code
);
734 if (cases
&& i
!= GPOINTER_TO_INT (cases
->data
)) {
738 emit_rule_string (rule
, "");
739 for (tmp
= cases
; tmp
; tmp
= tmp
->next
) {
740 output ("\tcase %d:\n", GPOINTER_TO_INT (tmp
->data
) + 1);
743 output ("%s\n", rule
->code
);
744 output ("\t}\n\treturn;\n");
748 output ("\t}\n}\n\n");
749 g_hash_table_destroy (cache
);
758 for (l
= rule_list
, i
= 0; l
; l
= l
->next
) {
759 Rule
*rule
= (Rule
*)l
->data
;
762 output ("inline static guint16\n");
764 emit_rule_string (rule
, "");
767 output ("mono_burg_cost_%d (MBState *state, MBCOST_DATA *data)\n", i
+ 1);
769 output ("mono_burg_cost_%d (MBTREE_TYPE *tree, MBCOST_DATA *data)\n", i
+ 1);
771 output ("%s\n", rule
->cfunc
);
783 for (l
= nonterm_list
; l
; l
= l
->next
) {
784 NonTerm
*n
= (NonTerm
*)l
->data
;
787 output ("static void closure_%s (MBState *p, int c);\n", n
->name
);
792 for (l
= nonterm_list
; l
; l
= l
->next
) {
793 NonTerm
*n
= (NonTerm
*)l
->data
;
796 output ("static void\n");
797 output ("closure_%s (MBState *p, int c)\n{\n", n
->name
);
798 for (rl
= n
->chain
; rl
; rl
= rl
->next
) {
799 Rule
*rule
= (Rule
*)rl
->data
;
801 emit_rule_string (rule
, "\t");
802 emit_cond_assign (rule
, rule
->cost
, "\t");
810 compute_nonterms (Tree
*tree
)
816 return g_strdup_printf ("MB_NTERM_%s, ", tree
->nonterm
->name
);
818 return g_strconcat (compute_nonterms (tree
->left
),
819 compute_nonterms (tree
->right
), NULL
);
824 count_nonterms (Tree
*tree
)
832 return count_nonterms (tree
->left
) + count_nonterms (tree
->right
);
846 if (predefined_terms
) {
847 output ("#if HAVE_ARRAY_ELEM_INIT\n");
848 output ("const guint8 mono_burg_arity [MBMAX_OPCODES] = {\n");
849 for (l
= term_list
, i
= 0; l
; l
= l
->next
) {
850 Term
*t
= (Term
*)l
->data
;
851 output ("\t [%s] = %d, /* %s */\n", t
->name
, t
->arity
, t
->name
);
854 output ("void\nmono_burg_init (void) {\n");
857 output ("guint8 mono_burg_arity [MBMAX_OPCODES];\n");
859 output ("void\nmono_burg_init (void)\n{\n");
861 for (l
= term_list
, i
= 0; l
; l
= l
->next
) {
862 Term
*t
= (Term
*)l
->data
;
863 output ("\tmono_burg_arity [%s] = %d; /* %s */\n", t
->name
, t
->arity
, t
->name
);
866 output ("#endif /* HAVE_ARRAY_ELEM_INIT */\n");
869 output ("const guint8 mono_burg_arity [] = {\n");
870 for (l
= term_list
, i
= 0; l
; l
= l
->next
) {
871 Term
*t
= (Term
*)l
->data
;
873 while (i
< t
->number
) {
878 output ("\t%d, /* %s */\n", t
->arity
, t
->name
);
884 output ("const char *const mono_burg_term_string [] = {\n");
885 output ("\tNULL,\n");
886 for (l
= term_list
, i
= 0; l
; l
= l
->next
) {
887 Term
*t
= (Term
*)l
->data
;
888 output ("\t\"%s\",\n", t
->name
);
893 output ("#if MONOBURG_LOG\n");
894 output ("const char * const mono_burg_rule_string [] = {\n");
895 output ("\tNULL,\n");
896 for (l
= rule_list
, i
= 0; l
; l
= l
->next
) {
897 Rule
*rule
= (Rule
*)l
->data
;
898 output ("\t\"%s: ", rule
->lhs
->name
);
899 emit_tree_string (rule
->tree
);
903 output ("#endif /* MONOBURG_LOG */\n\n");
905 n
= g_list_length (rule_list
);
906 sa
= g_new0 (char *, n
);
907 si
= g_new0 (int, n
);
908 nts_offsets
= g_new0 (int, n
);
910 /* at offset 0 we store 0 to mean end of list */
912 output ("const guint16 mono_burg_nts_data [] = {\n\t0,\n");
913 /* compress the _nts array */
914 for (l
= rule_list
, i
= 0, c
= 0; l
; l
= l
->next
) {
915 Rule
*rule
= (Rule
*)l
->data
;
916 char *s
= compute_nonterms (rule
->tree
);
918 for (j
= 0; j
< c
; j
++)
919 if (!strcmp (sa
[j
], s
))
924 output ("\t%s0,\n", s
);
925 nts_offsets
[c
] = current_offset
;
927 current_offset
+= count_nonterms (rule
->tree
) + 1;
930 output ("\t0\n};\n\n");
932 output ("const guint8 mono_burg_nts [] = {\n");
934 for (l
= rule_list
, i
= 0; l
; l
= l
->next
) {
935 Rule
*rule
= (Rule
*)l
->data
;
936 output ("\t%d, /* %s */ ", nts_offsets
[si
[i
]], sa
[si
[i
]]);
938 emit_rule_string (rule
, "");
946 output ("extern const char * const mono_burg_term_string [];\n");
947 output ("#if MONOBURG_LOG\n");
948 output ("extern const char * const mono_burg_rule_string [];\n");
949 output ("#endif /* MONOBURG_LOG */\n");
950 output ("extern const guint16 mono_burg_nts_data [];\n");
951 output ("extern const guint8 mono_burg_nts [];\n");
952 output ("extern void mono_burg_emit (int ern, MBState *state, MBTREE_TYPE *tree, MBCGEN_TYPE *s);\n\n");
954 output ("MBState *mono_burg_label (MBTREE_TYPE *tree, MBCOST_DATA *data);\n");
955 output ("int mono_burg_rule (MBState *state, int goal);\n");
958 output ("MBState **mono_burg_kids (MBState *state, int rulenr, MBState *kids []);\n");
960 output ("MBTREE_TYPE **mono_burg_kids (MBTREE_TYPE *tree, int rulenr, MBTREE_TYPE *kids []);\n");
962 output ("extern void mono_burg_init (void);\n");
966 static void check_reach (NonTerm
*n
);
969 mark_reached (Tree
*tree
)
971 if (tree
->nonterm
&& !tree
->nonterm
->reached
)
972 check_reach (tree
->nonterm
);
974 mark_reached (tree
->left
);
976 mark_reached (tree
->right
);
980 check_reach (NonTerm
*n
)
985 for (l
= n
->rules
; l
; l
= l
->next
) {
986 Rule
*rule
= (Rule
*)l
->data
;
987 mark_reached (rule
->tree
);
996 for (l
= term_list
; l
; l
= l
->next
) {
997 Term
*term
= (Term
*)l
->data
;
998 if (term
->arity
== -1)
999 g_warning ("unused terminal \"%s\"",term
->name
);
1002 check_reach (((NonTerm
*)nonterm_list
->data
));
1004 for (l
= nonterm_list
; l
; l
= l
->next
) {
1005 NonTerm
*n
= (NonTerm
*)l
->data
;
1007 g_warning ("unreachable nonterm \"%s\"", n
->name
);
1015 "Usage is: monoburg -d file.h -s file.c [inputfile] \n");
1020 warning_handler (const gchar
*log_domain
,
1021 GLogLevelFlags log_level
,
1022 const gchar
*message
,
1025 (void) fprintf ((FILE *) user_data
, "** WARNING **: %s\n", message
);
1029 main (int argc
, char *argv
[])
1032 char *deffile
= NULL
;
1033 GList
*infiles
= NULL
;
1036 definedvars
= g_hash_table_new (g_str_hash
, g_str_equal
);
1037 g_log_set_handler (NULL
, G_LOG_LEVEL_WARNING
, warning_handler
, stderr
);
1039 for (i
= 1; i
< argc
; i
++){
1040 if (argv
[i
][0] == '-'){
1041 if (argv
[i
][1] == 'h') {
1043 } else if (argv
[i
][1] == 'e') {
1045 } else if (argv
[i
][1] == 'p') {
1046 predefined_terms
= 1;
1047 } else if (argv
[i
][1] == 'd') {
1048 deffile
= argv
[++i
];
1049 } else if (argv
[i
][1] == 's') {
1051 } else if (argv
[i
][1] == 'c') {
1052 default_cost
= atoi (argv
[++i
]);
1053 } else if (argv
[i
][1] == 'D') {
1054 g_hash_table_insert (definedvars
, &argv
[i
][2],
1055 GUINT_TO_POINTER (1));
1060 infiles
= g_list_append (infiles
, argv
[i
]);
1065 if (!(deffd
= fopen (deffile
, "w"))) {
1066 perror ("cant open header output file");
1070 output ("#ifndef _MONO_BURG_DEFS_\n");
1071 output ("#define _MONO_BURG_DEFS_\n\n");
1079 char *infile
= (char *)l
->data
;
1080 if (!(inputfd
= fopen (infile
, "r"))) {
1081 perror ("cant open input file");
1100 g_error ("no start symbol found");
1108 output ("#endif /* _MONO_BURG_DEFS_ */\n");
1114 if (!(cfd
= fopen (cfile
, "w"))) {
1115 perror ("cant open c output file");
1116 (void) remove (deffile
);
1123 output ("#include \"%s\"\n\n", deffile
);
1140 emit_emitter_func ();