X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fgrammar.git;a=blobdiff_plain;f=grammar.c;h=411cd64cc8c3da11b04790a05286570215f6eceb;hp=b73cd399640c74c508e6b9373b017938b9dba1d0;hb=a84befe7a74aef0b745dc72b49788fd9ed6900b0;hpb=2da4a1b6506f7eb6949b504ac1f93c393f4f7302 diff --git a/grammar.c b/grammar.c index b73cd39..411cd64 100644 --- a/grammar.c +++ b/grammar.c @@ -5,7 +5,7 @@ struct _rule GList* right; }; -symbol_t* symbol_new (gboolean terminal, gint value) +symbol_t* symbol_new (gboolean terminal, GQuark value) { symbol_t* symbol; symbol = g_malloc (sizeof (symbol_t)); @@ -14,17 +14,9 @@ symbol_t* symbol_new (gboolean terminal, gint value) return symbol; } -rule_t* rule_new () +symbol_t* symbol_copy (symbol_t* symbol) { - rule_t* rule; - rule = g_malloc (sizeof (rule_t)); - rule->right = NULL; - return rule; -} - -void rule_append (rule_t* rule, symbol_t* right) -{ - rule->right = g_list_append (rule->right, right); + return symbol_new (symbol->terminal, symbol->value); } guint symbol_hash (gconstpointer data) @@ -44,11 +36,74 @@ gboolean symbol_equal (gconstpointer data1, gconstpointer data2) symbol1->terminal == symbol2->terminal; } +rule_t* rule_new () +{ + rule_t* rule; + rule = g_malloc (sizeof (rule_t)); + rule->right = NULL; + return rule; +} + +void rule_append (rule_t* rule, symbol_t* right) +{ + rule->right = g_list_append (rule->right, right); +} + +rule_t* rule_copy (rule_t* rule) +{ + rule_t* new_rule; + GList* r; + new_rule = rule_new (); + r = rule->right; + while (r != NULL) + { + rule_append (new_rule, symbol_copy (r->data)); + r = g_list_next (r); + } + return new_rule; +} + +symbol_t* rule_pop (rule_t* rule) +{ + GList* r; + if ((r = g_list_first (rule->right)) == NULL) + return NULL; + rule->right = g_list_remove_link (r, r); + g_free (r->data); + g_list_free (r); + if (rule->right == NULL) + return NULL; + return rule->right->data; +} + +void rule_delete (rule_t* rule) +{ + GList* l; + for (l = g_list_first (rule->right); l != NULL; l = g_list_next (l)) + { + g_free (l->data); + } + g_list_free (rule->right); + g_free (rule); +} + +void rules_delete (GList** list) +{ + GList* l; + for (l = g_list_first (*list); l != NULL; l = g_list_next (l)) + { + rule_delete (l->data); + } + g_list_free (*list); + g_free (list); +} + static void grammar_init (GTypeInstance* instance, gpointer g_class) { Grammar* self = GRAMMAR(instance); self->grammar = g_hash_table_new_full (symbol_hash, symbol_equal, - g_free, g_free); + g_free, + (GDestroyNotify) rules_delete); } static void grammar_finalize (GObject* obj) @@ -101,6 +156,7 @@ rule_t* grammar_rule_new (Grammar* grammar, symbol_t* left) left, NULL, (gpointer*)&l)) { l = g_malloc (sizeof (GList**)); + *l = NULL; g_hash_table_insert (grammar->grammar, left, l); } @@ -112,7 +168,18 @@ rule_t* grammar_rule_new (Grammar* grammar, symbol_t* left) } -void grammar_rule_append (rule_t* rule, symbol_t* right) +GList* grammar_get_rules (Grammar* grammar, symbol_t* left) +{ + GList** l; + if (!g_hash_table_lookup_extended (grammar->grammar, + left, NULL, (gpointer*)&l)) + { + return NULL; + } + return g_list_first (*l); +} + +GList* grammar_get_rule (rule_t* rule) { - rule_append (rule, right); + return rule->right; }