X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fgrammar.git;a=blobdiff_plain;f=lr1.c;h=f5c4a102f67a80e1e2549c6f4f18b4c40926104d;hp=d7f2d9821e2e43f5e68366f2b0e66b447c521b03;hb=HEAD;hpb=b1a65b0f36eca06bcc88db6f4cecee76b78c3177 diff --git a/lr1.c b/lr1.c index d7f2d98..f5c4a10 100644 --- a/lr1.c +++ b/lr1.c @@ -1,5 +1,29 @@ +/* + * Copyright (C) 2005 Thadeu Lima de Souza Cascardo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + + + #include #include +#include +#ifdef DEBUG +#include +#endif enum { PARSER_SHIFT, PARSER_REDUCE, PARSER_ACCEPT }; @@ -67,7 +91,7 @@ void transition_delete (transition_t* transition) g_free (transition); } -static void lr1_push (lr1_t* parser, gint st, gpointer attrib) +void lr1_push (lr1_t* parser, gint st, gpointer attrib) { state_t* state; state = g_malloc (sizeof (state_t)); @@ -103,7 +127,6 @@ lr1_t* lr1_new (nextcb cb, gpointer data) parser->data = data; parser->stack = NULL; - lr1_push (parser, 0, NULL); parser->table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_hash_table_destroy); @@ -216,9 +239,17 @@ gpointer lr1_build (lr1_t* parser) if (!lr1_lookup (parser, state->state, symbol, &transition)) return NULL; +#ifdef DEBUG + printf ("State: %x, Symbol: %s\n", state->state, + g_quark_to_string (symbol->value)); +#endif + if (transition->action == PARSER_SHIFT) { gint st; +#ifdef DEBUG + printf ("SHIFT: %x\n", transition->state); +#endif lr1_push (parser, transition->state, leaf_new (attrib)); symbol->value = parser->cb (parser->data, &attrib); symbol->terminal = TRUE; @@ -236,7 +267,7 @@ gpointer lr1_build (lr1_t* parser) for (l = grammar_get_rule (transition->right); l != NULL; - l = g_list_previous (l)) + l = g_list_next (l)) { gpointer attr; if (!lr1_pop (parser, &attr)) @@ -246,13 +277,26 @@ gpointer lr1_build (lr1_t* parser) l = g_list_first (parser->stack); state = (state_t*) l->data; + +#ifdef DEBUG + printf ("REDUCE: back to %x, ", state->state); +#endif + lr1_lookup (parser, state->state, transition->left, &trans); + +#ifdef DEBUG + printf ("%x\n", trans->state); +#endif + lr1_push (parser, trans->state, attrib); } else if (transition->action == PARSER_ACCEPT) { +#ifdef DEBUG + printf ("ACCEPT\n"); +#endif l = g_list_first (parser->stack); state = (state_t*) l->data; return state->attrib;