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.
38 static gint bnf_scanner_next (scanner_t* scanner, GString** val)
51 buffer = malloc (256);
53 for (i = 0; stop == 0; i++)
58 if (scanner->buffer->len == i)
61 r = scanner->cb (scanner->data, buffer, 256);
63 g_string_append_c (scanner->buffer, 0);
65 g_string_append_len (scanner->buffer, buffer, r);
68 c = scanner->buffer->str[i];
73 if (g_ascii_isalpha (c))
79 else if (g_ascii_isspace (c))
106 if (g_ascii_isalnum (c))
110 else if (g_ascii_isspace (c) || c == 0)
129 g_string_erase (scanner->buffer, 0, start);
130 lexeme = g_string_new_len (scanner->buffer->str, stop - start);
131 g_string_erase (scanner->buffer, 0, stop - start);
139 g_string_free (lexeme, TRUE);
158 void grammar_tree (grammar_t* grammar, GNode* tree)
166 GNode* child_nonterminal;
167 GNode* child_terminal;
174 assert (G_NODE_IS_LEAF(tree) == FALSE);
176 assert (symbol->value == BNF_GRAMMAR);
178 child_rules = tree->children;
180 while (child_rules->children != NULL)
183 assert (G_NODE_IS_LEAF(child_rules) == FALSE);
184 symbol = child_rules->data;
185 assert (symbol->value == BNF_RULES);
187 child_rule = child_rules->children;
188 assert (G_NODE_IS_LEAF(child_rule) == FALSE);
189 symbol = child_rule->data;
190 assert (symbol->value == BNF_RULE);
192 child_left = child_rule->children;
193 assert (G_NODE_IS_LEAF (child_left) == FALSE);
194 symbol = child_left->data;
195 assert (symbol->value == BNF_LEFT);
197 child_nonterminal = child_left->children;
198 assert (G_NODE_IS_LEAF (child_nonterminal) == FALSE);
199 symbol = child_nonterminal->data;
200 assert (symbol->value == BNF_NONTERMINAL);
201 assert (child_nonterminal->next == NULL);
203 child = child_nonterminal->children;
204 assert (G_NODE_IS_LEAF (child));
207 /* Create new rule */
208 value = g_quark_from_string (sym->str);
209 rule = grammar_rule_new (grammar, symbol_new (FALSE, value));
211 child_right = child_left->next->next;
212 while (child_right->children != NULL)
215 assert (G_NODE_IS_LEAF(child_right) == FALSE);
216 symbol = child_right->data;
217 assert (symbol->value == BNF_RIGHT);
219 child_symbol = child_right->children;
220 assert (G_NODE_IS_LEAF(child_symbol) == FALSE);
221 symbol = child_symbol->data;
222 assert (symbol->value == BNF_SYMBOL);
224 child = child_symbol->children;
225 symbol = child->data;
226 if (symbol->value == BNF_NONTERMINAL)
228 child_nonterminal = child;
229 assert (G_NODE_IS_LEAF (child_nonterminal) == FALSE);
230 assert (child_nonterminal->next == NULL);
231 child = child_nonterminal->children;
232 assert (G_NODE_IS_LEAF (child));
234 /* Append nonterminal to rule */
235 value = g_quark_from_string (sym->str);
236 rule_append (rule, symbol_new (FALSE, value));
238 else if (symbol->value == BNF_TERMINAL)
240 child_terminal = child;
241 assert (G_NODE_IS_LEAF (child_terminal) == FALSE);
242 assert (child_terminal->next == NULL);
243 child = child_terminal->children;
244 assert (G_NODE_IS_LEAF (child));
246 /* Append terminal to rule */
247 value = g_quark_from_string (sym->str);
248 rule_append (rule, symbol_new (TRUE, value));
255 child_right = child_symbol->next;
259 child_rules = child_rule->next;
265 grammar_t* grammar_load (char* filename)
277 fd = open (filename, O_RDONLY);
279 scanner = scanner_new (read, fd);
281 grammar = grammar_new ();
282 parser = rdp_new (bnf_scanner_next, scanner, BNF_GRAMMAR, grammar);
284 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_GRAMMAR));
285 rule_append (rule, symbol_new (FALSE, BNF_RULES));
286 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_RULES));
287 rule_append (rule, symbol_new (FALSE, BNF_RULE));
288 rule_append (rule, symbol_new (FALSE, BNF_RULES));
289 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_RULES));
290 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_RULE));
291 rule_append (rule, symbol_new (FALSE, BNF_LEFT));
292 rule_append (rule, symbol_new (TRUE, EQUAL));
293 rule_append (rule, symbol_new (FALSE, BNF_RIGHT));
294 rule_append (rule, symbol_new (TRUE, EOL));
295 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_LEFT));
296 rule_append (rule, symbol_new (FALSE, BNF_NONTERMINAL));
297 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_RIGHT));
298 rule_append (rule, symbol_new (FALSE, BNF_SYMBOL));
299 rule_append (rule, symbol_new (FALSE, BNF_RIGHT));
300 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_RIGHT));
301 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_SYMBOL));
302 rule_append (rule, symbol_new (FALSE, BNF_TERMINAL));
303 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_SYMBOL));
304 rule_append (rule, symbol_new (FALSE, BNF_NONTERMINAL));
305 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_TERMINAL));
306 rule_append (rule, symbol_new (TRUE, STRING));
307 rule = grammar_rule_new (grammar, symbol_new (FALSE, BNF_NONTERMINAL));
308 rule_append (rule, symbol_new (TRUE, ID));
310 tree = rdp_build (parser);
313 scanner_delete (scanner);
315 grammar_delete (grammar);
325 grammar_tree (gr, tree);