b73cd399640c74c508e6b9373b017938b9dba1d0
[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 rule_t* rule_new ()
18 {
19   rule_t* rule;
20   rule = g_malloc (sizeof (rule_t));
21   rule->right = NULL;
22   return rule;
23 }
24
25 void rule_append (rule_t* rule, symbol_t* right)
26 {
27   rule->right = g_list_append (rule->right, right);
28 }
29
30 guint symbol_hash (gconstpointer data)
31 {
32   symbol_t* symbol;
33   symbol = (symbol_t*) data;
34   return g_direct_hash ((gpointer)symbol->value);
35 }
36
37 gboolean symbol_equal (gconstpointer data1, gconstpointer data2)
38 {
39   symbol_t* symbol1;
40   symbol_t* symbol2;
41   symbol1 = (symbol_t*) data1;
42   symbol2 = (symbol_t*) data2;
43   return symbol1->value == symbol2->value &&
44     symbol1->terminal == symbol2->terminal;
45 }
46
47 static void grammar_init (GTypeInstance* instance, gpointer g_class)
48 {
49   Grammar* self = GRAMMAR(instance);
50   self->grammar = g_hash_table_new_full (symbol_hash, symbol_equal,
51                                          g_free, g_free);
52 }
53
54 static void grammar_finalize (GObject* obj)
55 {
56   GrammarClass* klass;
57   GObject* parent_class;
58   Grammar* self;
59   self = GRAMMAR(obj);
60   g_hash_table_destroy (self->grammar);
61   klass = GRAMMAR_GET_CLASS(obj);
62   parent_class = g_type_class_peek_parent (klass);
63   G_OBJECT_CLASS(parent_class)->finalize (obj);
64 }
65
66 static void grammar_class_init (GrammarClass* klass)
67 {
68   GObjectClass* gobj_class = G_OBJECT_CLASS(klass);
69   gobj_class->finalize = grammar_finalize;
70 }
71
72 GType grammar_get_type ()
73 {
74   static GType type = 0;
75   if (type == 0)
76     {
77       static const GTypeInfo info =
78         {
79           sizeof (GrammarClass),
80           NULL,
81           NULL,
82           (GClassInitFunc)grammar_class_init,
83           NULL,
84           NULL,
85           sizeof (Grammar),
86           0,
87           grammar_init
88         };
89       type = g_type_register_static (G_TYPE_OBJECT, "GrammarType", &info, 0);
90     }
91   return type;
92 }
93
94 rule_t* grammar_rule_new (Grammar* grammar, symbol_t* left)
95 {
96
97   GList** l;
98   rule_t* rule;
99
100   if (!g_hash_table_lookup_extended (grammar->grammar,
101                                      left, NULL, (gpointer*)&l))
102     {
103       l = g_malloc (sizeof (GList**));
104       g_hash_table_insert (grammar->grammar, left, l);
105     }
106
107   rule = rule_new ();
108
109   *l = g_list_append (*l, rule);
110
111   return rule;
112
113 }
114
115 void grammar_rule_append (rule_t* rule, symbol_t* right)
116 {
117   rule_append (rule, right);
118 }