Added functions to compare symbols and hash and equal for rules
[cascardo/grammar.git] / grammar.c
index 411cd64..41172e2 100644 (file)
--- a/grammar.c
+++ b/grammar.c
@@ -36,6 +36,23 @@ gboolean symbol_equal (gconstpointer data1, gconstpointer data2)
     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;
@@ -63,6 +80,46 @@ rule_t* rule_copy (rule_t* rule)
   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 (gcontspointer data1, gconstpointer data2)
+{
+  return (rule_cmp (data, 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;