X-Git-Url: http://git.cascardo.info/?p=cascardo%2Fgrammar.git;a=blobdiff_plain;f=first.c;h=cd3f5245a6208ebd1217b98988966d3916778b27;hp=e79d98de30a8f6bf847d7dc2bc31ff2e1fd2022f;hb=46aa6d5736bdf555d9388b631ebb0965f33dd39d;hpb=e251a60592ec3f646039ddc2812982ea6601521f diff --git a/first.c b/first.c index e79d98d..cd3f524 100644 --- a/first.c +++ b/first.c @@ -497,3 +497,48 @@ GList* first_get (GHashTable* first, symbol_t* symbol) return l; } + +GList* first_rule (GHashTable* first, rule_t* rule) +{ + + GHashTable* terminals; + GList* symbols; + GList* l; + + l = NULL; + + symbols = grammar_get_rule (rule); + + terminals = g_hash_table_new_full (symbol_hash, symbol_equal, g_free, NULL); + + while (symbols != NULL) + { + first_set_t* first_set; + symbol_t* symbol; + symbol = (symbol_t*) symbols->data; + if (symbol->terminal) + { + g_hash_table_insert (terminals, symbol_copy (symbol), NULL); + break; + } + if (!g_hash_table_lookup_extended (first, symbol, NULL, + (gpointer*) &first_set)) + { + g_hash_table_destroy (terminals); + return NULL; + } + first_set_union (terminals, first_set->terminals); + if (first_set->has_empty == FALSE) + break; + symbols = g_list_next (symbols); + } + + if (symbols == NULL) + l = g_list_prepend (l, symbol_new (TRUE, 0)); + g_hash_table_foreach (terminals, put_key_on_list, &l); + + g_hash_table_destroy (terminals); + + return l; + +}