Provide functions to retrieve rules from Grammar
[cascardo/grammar.git] / grammar.c
1 #include <grammar.h>
2
3 struct _rule
4 {
5   GList* right;
6 };
7
8 symbol_t* symbol_new (gboolean terminal, gint value)
9 {
10   symbol_t* symbol;
11   symbol = g_malloc (sizeof (symbol_t));
12   symbol->terminal = terminal;
13   symbol->value = value;
14   return symbol;
15 }
16
17 guint symbol_hash (gconstpointer data)
18 {
19   symbol_t* symbol;
20   symbol = (symbol_t*) data;
21   return g_direct_hash ((gpointer)symbol->value);
22 }
23
24 gboolean symbol_equal (gconstpointer data1, gconstpointer data2)
25 {
26   symbol_t* symbol1;
27   symbol_t* symbol2;
28   symbol1 = (symbol_t*) data1;
29   symbol2 = (symbol_t*) data2;
30   return symbol1->value == symbol2->value &&
31     symbol1->terminal == symbol2->terminal;
32 }
33
34 rule_t* rule_new ()
35 {
36   rule_t* rule;
37   rule = g_malloc (sizeof (rule_t));
38   rule->right = NULL;
39   return rule;
40 }
41
42 void rule_append (rule_t* rule, symbol_t* right)
43 {
44   rule->right = g_list_append (rule->right, right);
45 }
46
47 void rule_delete (rule_t* rule)
48 {
49   GList* l;
50   for (l = g_list_first (rule->right); l != NULL; l = g_list_next (l))
51     {
52       g_free (l->data);
53     }
54   g_list_free (rule->right);
55   g_free (rule);
56 }
57
58 void rules_delete (GList** list)
59 {
60   GList* l;
61   for (l = g_list_first (*list); l != NULL; l = g_list_next (l))
62     {
63       rule_delete (l->data);
64     }
65   g_list_free (*list);
66   g_free (list);
67 }
68
69 static void grammar_init (GTypeInstance* instance, gpointer g_class)
70 {
71   Grammar* self = GRAMMAR(instance);
72   self->grammar = g_hash_table_new_full (symbol_hash, symbol_equal,
73                                          g_free,
74                                          (GDestroyNotify) rules_delete);
75 }
76
77 static void grammar_finalize (GObject* obj)
78 {
79   GrammarClass* klass;
80   GObject* parent_class;
81   Grammar* self;
82   self = GRAMMAR(obj);
83   g_hash_table_destroy (self->grammar);
84   klass = GRAMMAR_GET_CLASS(obj);
85   parent_class = g_type_class_peek_parent (klass);
86   G_OBJECT_CLASS(parent_class)->finalize (obj);
87 }
88
89 static void grammar_class_init (GrammarClass* klass)
90 {
91   GObjectClass* gobj_class = G_OBJECT_CLASS(klass);
92   gobj_class->finalize = grammar_finalize;
93 }
94
95 GType grammar_get_type ()
96 {
97   static GType type = 0;
98   if (type == 0)
99     {
100       static const GTypeInfo info =
101         {
102           sizeof (GrammarClass),
103           NULL,
104           NULL,
105           (GClassInitFunc)grammar_class_init,
106           NULL,
107           NULL,
108           sizeof (Grammar),
109           0,
110           grammar_init
111         };
112       type = g_type_register_static (G_TYPE_OBJECT, "GrammarType", &info, 0);
113     }
114   return type;
115 }
116
117 rule_t* grammar_rule_new (Grammar* grammar, symbol_t* left)
118 {
119
120   GList** l;
121   rule_t* rule;
122
123   if (!g_hash_table_lookup_extended (grammar->grammar,
124                                      left, NULL, (gpointer*)&l))
125     {
126       l = g_malloc (sizeof (GList**));
127       *l = NULL;
128       g_hash_table_insert (grammar->grammar, left, l);
129     }
130
131   rule = rule_new ();
132
133   *l = g_list_append (*l, rule);
134
135   return rule;
136
137 }
138
139 void grammar_rule_append (rule_t* rule, symbol_t* right)
140 {
141   rule_append (rule, right);
142 }
143
144 GList* grammar_get_rules (Grammar* grammar, symbol_t* left)
145 {
146   GList** l;
147   if (!g_hash_table_lookup_extended (grammar->grammar,
148                                      left, NULL, (gpointer*)&l))
149     {
150       return NULL;
151     }
152   return g_list_first (*l);
153 }
154
155 GList* grammar_get_rule (rule_t* rule)
156 {
157   return rule->right;
158 }