2 * Copyright (C) 2005 Thadeu Lima de Souza Cascardo <cascardo@holoscopio.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 symbol_t* symbol_new (gboolean terminal, GQuark value)
31 symbol = g_malloc (sizeof (symbol_t));
32 symbol->terminal = terminal;
33 symbol->value = value;
37 symbol_t* symbol_copy (symbol_t* symbol)
39 return symbol_new (symbol->terminal, symbol->value);
42 guint symbol_hash (gconstpointer data)
45 symbol = (symbol_t*) data;
46 return g_direct_hash ((gpointer)symbol->value);
49 gboolean symbol_equal (gconstpointer data1, gconstpointer data2)
53 symbol1 = (symbol_t*) data1;
54 symbol2 = (symbol_t*) data2;
55 return symbol1->value == symbol2->value &&
56 symbol1->terminal == symbol2->terminal;
59 gint symbol_cmp (symbol_t* a, symbol_t* b)
61 if (a->terminal == b->terminal)
63 if (a->value < b->value)
65 else if (a->value > b->value)
69 else if (a->terminal == FALSE)
79 rule = g_malloc (sizeof (rule_t));
84 void rule_append (rule_t* rule, symbol_t* right)
86 rule->right = g_list_append (rule->right, right);
89 rule_t* rule_copy (rule_t* rule)
93 new_rule = rule_new ();
97 rule_append (new_rule, symbol_copy (r->data));
103 gint rule_cmp (rule_t* a, rule_t* b)
107 la = grammar_get_rule (a);
108 lb = grammar_get_rule (b);
109 while (la != NULL && lb != NULL)
112 if ((c = symbol_cmp (la->data, lb->data)) != 0)
114 la = g_list_next (la);
115 lb = g_list_next (lb);
124 gboolean rule_equal (gconstpointer data1, gconstpointer data2)
126 return (rule_cmp (data1, data2) == 0);
129 guint rule_hash (gconstpointer data)
133 l = grammar_get_rule (data);
137 hash = 37 * hash + symbol_hash (l->data);
143 symbol_t* rule_pop (rule_t* rule)
146 if ((r = g_list_first (rule->right)) == NULL)
148 rule->right = g_list_remove_link (r, r);
151 if (rule->right == NULL)
153 return rule->right->data;
156 void rule_delete (rule_t* rule)
159 for (l = g_list_first (rule->right); l != NULL; l = g_list_next (l))
163 g_list_free (rule->right);
167 void rules_delete (GList** list)
170 for (l = g_list_first (*list); l != NULL; l = g_list_next (l))
172 rule_delete (l->data);
178 grammar_t* grammar_new ()
181 grammar = g_malloc (sizeof (grammar_t*));
182 grammar->grammar = g_hash_table_new_full (symbol_hash, symbol_equal,
184 (GDestroyNotify) rules_delete);
188 void grammar_delete (grammar_t* grammar)
190 g_hash_table_destroy (grammar->grammar);
194 rule_t* grammar_rule_new (grammar_t* grammar, symbol_t* left)
200 if (!g_hash_table_lookup_extended (grammar->grammar,
201 left, NULL, (gpointer*)&l))
203 l = g_malloc (sizeof (GList**));
205 g_hash_table_insert (grammar->grammar, left, l);
210 *l = g_list_append (*l, rule);
216 GList* grammar_get_rules (grammar_t* grammar, symbol_t* left)
219 if (!g_hash_table_lookup_extended (grammar->grammar,
220 left, NULL, (gpointer*)&l))
224 return g_list_first (*l);
227 GList* grammar_get_rule (rule_t* rule)