static int rdp_check_nullable(void * base) { int bad = 0; rdp_data * temp =(rdp_data *) symbol_next_symbol_in_scope(base); set_ work = SET_NULL; while (temp != NULL) { if (temp->contains_null &&(temp->kind != K_CODE)) { set_assign_set(& work, & temp->first); set_intersect_set(& work, & temp->follow); if (set_cardinality(& work)!= 0) { text_message(TEXT_ERROR, "LL(1) violation - rule\n %s ::= ", temp->id); rdp_print_sub_item(temp, 1); text_printf(".\n contains null but first and follow sets both include: "); set_print_set(& work, rdp_token_string, 78); text_printf("\n"); temp->ll1_violation = 1; bad = 1; } } temp =(rdp_data *) symbol_next_symbol_in_scope(temp); } return bad; }
/* scan a sequence production for follow set changes */ static void rdp_follow_sequence(rdp_data * prod) { rdp_list * check = prod->list; /* pointer to sequence list */ while (check != NULL) /* scan entire sequence and add to follow sets */ { rdp_list * following = check; /* temporary to look at followers */ unsigned old_cardinality = check->production->follow_cardinality; do /* scan up list adding first sets of trailing productions */ { following = following->next; if (following == NULL) /* We hit end of sequence */ set_unite_set(& check->production->follow, & prod->follow); else set_unite_set(& check->production->follow, & following->production->first); } while (following != NULL && following->production->contains_null); /* Update cardinality changed flag */ rdp_follow_changed |=((check->production->follow_cardinality = set_cardinality(& check->production->follow) )!= old_cardinality); check = check->next; /* step to next item in sequence */ } }
static int rdp_check_disjoint(void * base) { int bad = 0; set_ work = SET_NULL; rdp_data * temp =(rdp_data *) symbol_next_symbol_in_scope(base); while (temp != NULL) { if (set_includes_element(& rdp_production_set, temp->kind)&& temp->kind != K_SEQUENCE) { rdp_list * left = temp->list; while (left != NULL) { rdp_list * right = left->next; while (right != NULL) { /* First check for disjoint on epsilon */ if (left->production->contains_null && right->production->contains_null) { text_message(TEXT_ERROR, "LL(1) violation - rule \'%s\'\n", temp->id); text_printf(" productions %s ::= ", left->production->id); rdp_print_sub_item(left->production, 1); text_printf(".\n and %s ::= ", right->production->id); rdp_print_sub_item(right->production, 1); text_printf(".\n are both nullable \n"); left->production->ll1_violation = 1; right->production->ll1_violation = 1; bad = 1; } set_assign_set(& work, & left->production->first); set_intersect_set(& work, & right->production->first); if (set_cardinality(& work)!= 0) { text_message(TEXT_ERROR, "LL(1) violation - rule \'%s\'\n", temp->id); text_printf(" productions %s ::= ", left->production->id); rdp_print_sub_item(left->production, 1); text_printf(".\n and %s ::= ", right->production->id); rdp_print_sub_item(right->production, 1); text_printf(".\n share these start tokens: "); set_print_set(& work, rdp_token_string, 78); text_printf("\n"); left->production->ll1_violation = 1; right->production->ll1_violation = 1; bad = 1; } right = right->next; } left = left->next; } } temp =(rdp_data *) symbol_next_symbol_in_scope(temp); } return bad; }
/* * db_seq_cardinality() - This function returns only the number of non-null * elements in the sequence. * return : number of non-null elements in the sequence * set(in): sequence descriptor */ int db_seq_cardinality (DB_SET * set) { int retval; CHECK_CONNECT_MINUSONE (); CHECK_1ARG_MINUSONE (set); retval = (set_cardinality (set)); return (retval); }
/* * db_col_cardinality() - This function returns the number of elements in the * collection that have non-NULL values. * return: the cardinality of the collection * col(in): collection * * note : This is different than db_col_size which returns the total * number of elements in the collection, including those with NULL * values. Use of db_col_cardinality is discouraged since it is * almost always the case that the API programmer really should be * using db_col_size. */ int db_col_cardinality (DB_COLLECTION * col) { int card; CHECK_CONNECT_MINUSONE (); CHECK_1ARG_MINUSONE (col); card = set_cardinality (col); return card; }
static void rdp_update_follow_sets(void * base) { rdp_data * temp =(rdp_data *) symbol_next_symbol_in_scope(base); while (temp != NULL) { if (temp->kind == K_LIST && temp->hi != 1 && temp->supplementary_token == NULL) { set_unite_set(& temp->follow, & temp->first); temp->follow_cardinality = set_cardinality(& temp->follow); } temp =(rdp_data *) symbol_next_symbol_in_scope(temp); } }
/* scan an alternate for follow set changes */ static void rdp_follow_alternate(rdp_data * prod) { rdp_list * check = prod->list; /* pointer to alternate list */ while (check != NULL) { unsigned old_cardinality = check->production->follow_cardinality; set_unite_set(& check->production->follow, & prod->follow); rdp_follow_changed |=((check->production->follow_cardinality = set_cardinality(& check->production->follow) )!= old_cardinality); check = check->next; } }
static void rdp_first(rdp_data * prod) { if (prod->in_use) /* something has gone wrong */ { text_message(TEXT_ERROR, "LL(1) violation - rule \'%s\' is left recursive\n", prod->id); /* and return */ prod->ll1_violation = 1; return; } if (!prod->first_done) /* something to do */ { rdp_list * list = prod->list; /* set up alternates pointer */ prod->in_use = 1; /* mark this production as being processed */ if (prod->kind == K_SEQUENCE) /* sequences are treated differently */ { prod->contains_null = 1; /* set up list flag */ while (list != NULL && prod->contains_null) /* scan until non-empty alternate is found */ { if (!list->production->first_done) /* do first */ rdp_first(list->production); set_unite_set(& prod->first, & list->production->first); /* add alternate first set to production first set */ prod->contains_null = list->production->contains_null; /* set contains_null flag */ list = list->next; } } else while (list != NULL) /* scan all alternates */ { if (!list->production->first_done) /* do first */ rdp_first(list->production); set_unite_set(& prod->first, & list->production->first); /* add alternate first set to production first set */ prod->contains_null |= list->production->contains_null; /* OR in contains_null flag */ list = list->next; } prod->in_use = 0; /* production is no longer in use */ prod->first_done = 1; /* first set is now complete */ /* and set cardinality */ prod->first_cardinality = set_cardinality(& prod->first); } }
int scan_test_set(const char * production, set_ * valid, set_ * stop) { if (!set_includes_element(valid, SCAN_CAST->token)) { if (stop != NULL) { if (production != NULL) text_message(TEXT_ERROR_ECHO, "In rule \'%s\', scanned ", production); else text_message(TEXT_ERROR_ECHO, "Scanned "); set_print_element(SCAN_CAST->token, scan_token_names); text_printf(" whilst expecting %s", set_cardinality(valid)== 1 ? "": "one of "); set_print_set(valid, scan_token_names, 60); text_printf("\n"); scan_skip(stop); } return 0; } else return 1; }