4 transition_t* transition_new (gint action, gint state)
6 transition_t* transition;
7 transition = g_malloc (sizeof (transition_t));
8 transition->action = action;
9 transition->state = state;
13 static void lr0_push (lr0_t* parser, gint st, gpointer attrib)
16 state = g_malloc (sizeof (state_t));
18 state->attrib = attrib;
19 parser->stack = g_list_prepend (parser->stack, state);
22 static gboolean lr0_pop (lr0_t* parser, gpointer* attrib)
27 if ((l = g_list_first (parser->stack)) == NULL)
29 parser->stack = g_list_remove_link (l, l);
30 state = (state_t*) l->data;
32 *attrib = state->attrib;
39 lr0_t* lr0_new (nextcb cb, gpointer data)
44 parser = g_malloc (sizeof (lr0_t));
49 parser_push (parser, 0, NULL);
50 parser->table = g_hash_table_new_full (g_direct_hash, g_direct_equal,
51 NULL, g_hash_table_destroy);
58 void lr0_delete (lr0_t* parser)
63 for (l = g_list_first (parser->stack); l != NULL; l = g_list_next (l))
68 g_list_free (parser->stack);
70 g_hash_table_destroy (parser->table);
76 void lr0_add (lr0_t* parser, gint state, symbol_t* symbol,
77 transition_t* transition)
82 if (!g_hash_table_lookup_extended (parser->table, state,
83 NULL, (gpointer*) &table))
85 table = g_hash_table_new_full (symbol_hash, symbol_equal,
87 g_hash_table_insert (parser->table, state, table);
90 g_hash_table_insert (table, symbol, transition);
94 gboolean lr0_lookup (lr0_t* parser, gint state, symbol_t* symbol,
95 transition_t** transition)
101 if (!g_hash_table_lookup_extended (parser->table, state,
102 NULL, (gpointer*) &table))
107 if (!g_hash_table_lookup_extended (table, symbol,
108 NULL, (gpointer*) &trans))
120 gpointer leaf_new (gpointer data)
122 return g_node_new (data);
125 gpointer tree_new (rule_t* rule)
127 return g_node_new (rule);
130 gpointer tree_add (gpointer tree, gpointer data)
132 return g_node_prepend (tree, data);
135 gpointer lr0_build (lr0_t* parser)
140 transition_t* transition;
144 symbol = g_malloc (sizeof (symbol_t));
146 symbol->value = parser->cb (parser->data, &attrib);
147 symbol->terminal = FALSE;
152 l = g_list_first (parser->stack);
153 state = (state_t*) l->data;
154 if (!lr0_lookup (parser, state->state, symbol, &transition))
157 if (transition->action == PARSER_SHIFT)
159 lr0_push (parser, transition->state, leaf_new (attrib));
160 symbol->value = parser->cb (parser->data, &attrib);
161 symbol->terminal = FALSE;
164 else if (transition->action == PARSER_REDUCE)
173 rule = g_list_nth_data (parser->rules, transition->state);
174 attrib = tree_new (rule);
176 for (l = g_list_last (rule->right);
178 l = g_list_previous (l))
181 if (!lr0_pop (parser, &attr))
183 tree_add (attrib, attr);
186 l = g_list_first (parser->stack);
187 state = (state_t*) l->data;
188 lr0_lookup (parser, state->state, rule->left, &trans);
189 lr0_push (parser, trans->state, attrib);
193 else if (transition->action == PARSER_ACCEPT)
195 l = g_list_first (parser->stack);
196 state = (state_t*) l->data;
197 return state->attrib;