Generates LR(1) table from Items
[cascardo/grammar.git] / lr1.c
diff --git a/lr1.c b/lr1.c
index d7f2d98..afbc9e0 100644 (file)
--- a/lr1.c
+++ b/lr1.c
@@ -1,5 +1,9 @@
 #include <grammar.h>
 #include <stdlib.h>
+#include <lr1.h>
+#ifdef DEBUG
+#include <stdio.h>
+#endif
 
 enum { PARSER_SHIFT, PARSER_REDUCE, PARSER_ACCEPT };
 
@@ -67,7 +71,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 +107,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 +219,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 +247,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 +257,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;