8 symbol_t* symbol_new (gboolean terminal, GQuark value)
11 symbol = g_malloc (sizeof (symbol_t));
12 symbol->terminal = terminal;
13 symbol->value = value;
17 symbol_t* symbol_copy (symbol_t* symbol)
19 return symbol_new (symbol->terminal, symbol->value);
22 guint symbol_hash (gconstpointer data)
25 symbol = (symbol_t*) data;
26 return g_direct_hash ((gpointer)symbol->value);
29 gboolean symbol_equal (gconstpointer data1, gconstpointer data2)
33 symbol1 = (symbol_t*) data1;
34 symbol2 = (symbol_t*) data2;
35 return symbol1->value == symbol2->value &&
36 symbol1->terminal == symbol2->terminal;
39 gint symbol_cmp (symbol_t* a, symbol_t* b)
41 if (a->terminal == b->terminal)
43 if (a->value < b->value)
45 else if (a->value > b->value)
49 else if (a->terminal == FALSE)
59 rule = g_malloc (sizeof (rule_t));
64 void rule_append (rule_t* rule, symbol_t* right)
66 rule->right = g_list_append (rule->right, right);
69 rule_t* rule_copy (rule_t* rule)
73 new_rule = rule_new ();
77 rule_append (new_rule, symbol_copy (r->data));
83 gint rule_cmp (rule_t* a, rule_t* b)
87 la = grammar_get_rule (a);
88 lb = grammar_get_rule (b);
89 while (la != NULL && lb != NULL)
92 if ((c = symbol_cmp (la->data, lb->data)) != 0)
94 la = g_list_next (la);
95 lb = g_list_next (lb);
104 gboolean rule_equal (gconstpointer data1, gconstpointer data2)
106 return (rule_cmp (data1, data2) == 0);
109 guint rule_hash (gconstpointer data)
113 l = grammar_get_rule (data);
117 hash = 37 * hash + symbol_hash (l->data);
123 symbol_t* rule_pop (rule_t* rule)
126 if ((r = g_list_first (rule->right)) == NULL)
128 rule->right = g_list_remove_link (r, r);
131 if (rule->right == NULL)
133 return rule->right->data;
136 void rule_delete (rule_t* rule)
139 for (l = g_list_first (rule->right); l != NULL; l = g_list_next (l))
143 g_list_free (rule->right);
147 void rules_delete (GList** list)
150 for (l = g_list_first (*list); l != NULL; l = g_list_next (l))
152 rule_delete (l->data);
158 static void grammar_init (GTypeInstance* instance, gpointer g_class)
160 Grammar* self = GRAMMAR(instance);
161 self->grammar = g_hash_table_new_full (symbol_hash, symbol_equal,
163 (GDestroyNotify) rules_delete);
166 static void grammar_finalize (GObject* obj)
169 GObject* parent_class;
172 g_hash_table_destroy (self->grammar);
173 klass = GRAMMAR_GET_CLASS(obj);
174 parent_class = g_type_class_peek_parent (klass);
175 G_OBJECT_CLASS(parent_class)->finalize (obj);
178 static void grammar_class_init (GrammarClass* klass)
180 GObjectClass* gobj_class = G_OBJECT_CLASS(klass);
181 gobj_class->finalize = grammar_finalize;
184 GType grammar_get_type ()
186 static GType type = 0;
189 static const GTypeInfo info =
191 sizeof (GrammarClass),
194 (GClassInitFunc)grammar_class_init,
201 type = g_type_register_static (G_TYPE_OBJECT, "GrammarType", &info, 0);
206 rule_t* grammar_rule_new (Grammar* grammar, symbol_t* left)
212 if (!g_hash_table_lookup_extended (grammar->grammar,
213 left, NULL, (gpointer*)&l))
215 l = g_malloc (sizeof (GList**));
217 g_hash_table_insert (grammar->grammar, left, l);
222 *l = g_list_append (*l, rule);
228 GList* grammar_get_rules (Grammar* grammar, symbol_t* left)
231 if (!g_hash_table_lookup_extended (grammar->grammar,
232 left, NULL, (gpointer*)&l))
236 return g_list_first (*l);
239 GList* grammar_get_rule (rule_t* rule)