+/*
+ * Copyright (C) 2005 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+
+
#include <grammar.h>
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));
return symbol;
}
+symbol_t* symbol_copy (symbol_t* symbol)
+{
+ return symbol_new (symbol->terminal, symbol->value);
+}
+
guint symbol_hash (gconstpointer data)
{
symbol_t* symbol;
symbol1->terminal == symbol2->terminal;
}
+gint symbol_cmp (symbol_t* a, symbol_t* b)
+{
+ if (a->terminal == b->terminal)
+ {
+ if (a->value < b->value)
+ return -1;
+ else if (a->value > b->value)
+ return 1;
+ return 0;
+ }
+ else if (a->terminal == FALSE)
+ {
+ return -1;
+ }
+ return 1;
+}
+
rule_t* rule_new ()
{
rule_t* rule;
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;
+}
+
+gint rule_cmp (rule_t* a, rule_t* b)
+{
+ GList* la;
+ GList* lb;
+ la = grammar_get_rule (a);
+ lb = grammar_get_rule (b);
+ while (la != NULL && lb != NULL)
+ {
+ int c;
+ if ((c = symbol_cmp (la->data, lb->data)) != 0)
+ return c;
+ la = g_list_next (la);
+ lb = g_list_next (lb);
+ }
+ if (la == lb)
+ return 0;
+ else if (la == NULL)
+ return -1;
+ return 1;
+}
+
+gboolean rule_equal (gconstpointer data1, gconstpointer data2)
+{
+ return (rule_cmp (data1, data2) == 0);
+}
+
+guint rule_hash (gconstpointer data)
+{
+ GList* l;
+ guint hash;
+ l = grammar_get_rule (data);
+ hash = 0;
+ while (l != NULL)
+ {
+ hash = 37 * hash + symbol_hash (l->data);
+ l = g_list_next (l);
+ }
+ return hash;
+}
+
+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;
g_free (list);
}
-static void grammar_init (GTypeInstance* instance, gpointer g_class)
+grammar_t* grammar_new ()
{
- Grammar* self = GRAMMAR(instance);
- self->grammar = g_hash_table_new_full (symbol_hash, symbol_equal,
- g_free,
- (GDestroyNotify) rules_delete);
+ grammar_t* grammar;
+ grammar = g_malloc (sizeof (grammar_t*));
+ grammar->grammar = g_hash_table_new_full (symbol_hash, symbol_equal,
+ g_free,
+ (GDestroyNotify) rules_delete);
+ return grammar;
}
-static void grammar_finalize (GObject* obj)
+void grammar_delete (grammar_t* grammar)
{
- GrammarClass* klass;
- GObject* parent_class;
- Grammar* self;
- self = GRAMMAR(obj);
- g_hash_table_destroy (self->grammar);
- klass = GRAMMAR_GET_CLASS(obj);
- parent_class = g_type_class_peek_parent (klass);
- G_OBJECT_CLASS(parent_class)->finalize (obj);
+ g_hash_table_destroy (grammar->grammar);
+ g_free (grammar);
}
-static void grammar_class_init (GrammarClass* klass)
-{
- GObjectClass* gobj_class = G_OBJECT_CLASS(klass);
- gobj_class->finalize = grammar_finalize;
-}
-
-GType grammar_get_type ()
-{
- static GType type = 0;
- if (type == 0)
- {
- static const GTypeInfo info =
- {
- sizeof (GrammarClass),
- NULL,
- NULL,
- (GClassInitFunc)grammar_class_init,
- NULL,
- NULL,
- sizeof (Grammar),
- 0,
- grammar_init
- };
- type = g_type_register_static (G_TYPE_OBJECT, "GrammarType", &info, 0);
- }
- return type;
-}
-
-rule_t* grammar_rule_new (Grammar* grammar, symbol_t* left)
+rule_t* grammar_rule_new (grammar_t* grammar, symbol_t* left)
{
GList** l;
}
-void grammar_rule_append (rule_t* rule, symbol_t* right)
-{
- rule_append (rule, right);
-}
-
-GList* grammar_get_rules (Grammar* grammar, symbol_t* left)
+GList* grammar_get_rules (grammar_t* grammar, symbol_t* left)
{
GList** l;
if (!g_hash_table_lookup_extended (grammar->grammar,