Beispiel #1
0
void destroy_itemset( struct itemset * this_itemset ) {
    int i;
    char * key;
    struct list * key_list = new_list();
    list_keys_in_hash( this_itemset->items, key_list, "" );
    for ( i = 0; i < key_list->next_index; i++ ) {
        key = listlookup( key_list, i );
        struct item * data = hashlookup( this_itemset->items, key )->data;
        free( data );
    }
    destroy_key_list( key_list );
    destroy_hash( this_itemset->items );
    key_list = new_list();
    list_keys_in_hash( this_itemset->ready_for, key_list, "" );
    for ( i = 0; i < key_list->next_index; i++ ) {
        key = listlookup( key_list, i );
        struct list * ready_items = hashlookup( this_itemset->ready_for, key )->data;
        destroy_list( ready_items );
    }
    destroy_key_list( key_list );
    destroy_hash( this_itemset->ready_for );
    destroy_list( this_itemset->complete );
    free( this_itemset );
    return;
}
char * print_hash_key_set( struct hash * current ) {
    struct list * var_list = new_list();
    list_keys_in_hash( current, var_list, "" );
    int var_list_len = 0;
    int i = var_list->next_index;
    while ( i-- ) {
        var_list_len += strlen(listlookup( var_list, i ));
    }
    int brace_len = BRACE_LEN;
    int comma_len = COMMA_LEN;
    char * key_set_str = malloc(
                             ( var_list->next_index  * comma_len
                               + var_list_len
                               + 2 * brace_len
                               + 1
                             ) * sizeof(char)
                         );

    *key_set_str = '\0';
    sprintf( key_set_str, "{" );
    i = var_list->next_index;
    while ( i-- ) {
        strcat( key_set_str, listlookup( var_list, i ));
        if ( i ) {
            strcat( key_set_str, "," );
        }
    }
    strcat( key_set_str, "}" );
    destroy_key_list(var_list);
    return key_set_str;
}
Beispiel #3
0
void fill_FIRST() {
    FIRST = new_hash();
    int i;
    int j;
    char * symbol;
    char * lhs;
    char * left_corner;
    struct list * key_list = new_list();
    list_keys_in_hash( IS_TERMINAL, key_list, "" );
    for ( i = 0; i < key_list->next_index; i++ ) {
        symbol = listlookup( key_list, i );
        struct hash * symbol_firsts = new_hash();
         if ( ( (int *) hashlookup( IS_TERMINAL, symbol )->data ) == &TRUE ) { // Terminals self-derive.
            add_to_hash( symbol_firsts, symbol, (void *) (long int) 1 );
        }
        add_to_hash( FIRST, symbol, (void *) symbol_firsts );
    }
    destroy_key_list( key_list );
    int change = 1;
    while ( change ) {
        change = 0;
        for ( i = 0; i < NUM_PRODUCTIONS; i++ ) {
            struct list * production = GRAMMAR[i].production;
            lhs = listlookup( production, 0 );
            left_corner = listlookup( production, 1 );
            key_list = new_list();
            list_keys_in_hash( hashlookup( FIRST, left_corner )->data, key_list, "" );
            for ( j = 0; j <  key_list->next_index; j++ ) { // Go through all the firsts of left_corner.
                symbol = listlookup( key_list, j );
                struct hash * lhs_firsts = hashlookup( FIRST, lhs )->data;
                struct hash * looked_up = hashlookup( lhs_firsts, symbol );
                if ( ! looked_up ) {
                    add_to_hash( lhs_firsts, symbol, (void *) &TRUE ); // Add them to firsts of lhs.
                    change = 1;
                }
            }
            destroy_key_list( key_list );
        }
    }
}
Beispiel #4
0
void fill_FOLLOW() {
    FOLLOW = new_hash();
    char * symbol;
    char * next_symbol;
    char * lhs;
    int i;
    int j;
    struct list * production;
    int change;
    struct hash * symbol_followers;

    struct list * key_list = new_list();
    list_keys_in_hash( IS_TERMINAL, key_list, "" );
    for ( i = 0; i < key_list->next_index; i++ ) {
        symbol = listlookup( key_list, i );
        if ( ( (int *) hashlookup( IS_TERMINAL, symbol )->data ) == &FALSE ) {
            symbol_followers = new_hash();
            add_to_hash( FOLLOW, symbol, (void *) symbol_followers );
        }
    }
    destroy_key_list( key_list );
    change = 1;
    while ( change ) {
        change = 0;
        for ( i = 0; i < NUM_PRODUCTIONS; i++ ) {
            production = GRAMMAR[i].production;
            lhs = listlookup( production, 0 );
            for ( j = 1; j < production->next_index; j++ ) { // Loop RHS symbols.
                symbol = listlookup( production, j );
                if ( ( (int *) hashlookup( IS_TERMINAL, symbol )->data ) == &TRUE ) { // No FOLLOW for terminals.
                    continue;
                }
                symbol_followers = hashlookup( FOLLOW, symbol )->data;
                if ( j + 1 < production->next_index ) { // There is an adjacent symbol.
                    next_symbol = listlookup( production, j + 1 );
                    struct hash * next_symbol_firsts = hashlookup( FIRST, next_symbol )->data;

                    // Everything in FIRST{next_symbol} should be in FOLLOW{symbol}.
                    change = expand_hash( symbol_followers, next_symbol_firsts ) || change;
                    continue;
                }
                else { // Last symbol in production is nonterminal.
                    struct hash * lhs_followers = hashlookup( FOLLOW, lhs )->data;

                    // Everything in FOLLOW{lhs} should be in FOLLOW{symbol}.
                    change = expand_hash( symbol_followers, lhs_followers ) || change;
                    continue;
                }
            }
        }
    }
}
struct hash * copy_shallow_hash( struct hash * original ) {
    struct hash * copy = new_hash();
    struct list * key_list = new_list();
    list_keys_in_hash( original, key_list, "" );
    char * key = NULL;
    int i = key_list->next_index;
    while ( i-- ) {
        key = listlookup( key_list, i );
        add_to_hash( copy, key, hashlookup( original, key ) );
    }
    destroy_key_list( key_list );
    return copy;
}
Beispiel #6
0
void fill_TRIE( struct hash * token_types ) {
    int i;
    char * path;
    char * accepting_type;
    TRIE = new_trie_node();
    struct list * key_list = new_list();
    list_keys_in_hash( token_types, key_list, "" );
    for ( i = 0; i < key_list->next_index; i++ ) {
        path = listlookup( key_list, i );
        accepting_type = hashlookup( token_types, path )->data;
        add_to_trie( TRIE, path, accepting_type );
    }
    destroy_key_list( key_list );
    return;
}
Beispiel #7
0
void install_complete_transitions( int i, struct itemset * current_itemset, struct parser_generator * self ) {
    struct list * table = self->TABLE;
    struct list * complete_items = current_itemset->complete;
    char * lhs;
    struct item * complete_item;
    struct list * complete_production;
    int j; int k;
    struct hash * table_row = listlookup( self->TABLE, i );
    for ( j = 0; j < complete_items->next_index; j++ ) {
        complete_item = listlookup( complete_items, j );
        int prod_num = complete_item->prod_num;
        complete_production = GRAMMAR[prod_num].production;
        lhs = listlookup( complete_production, 0 );

        // Loop all terminals which can follow this lhs.
        struct list * key_list = new_list();
        list_keys_in_hash( hashlookup( FOLLOW, lhs )->data, key_list, "" );
        for ( k = 0; k < key_list->next_index; k++ ) {
            struct list * trans_list;
            char * follower = listlookup( key_list, k );

            // Add a reduce transition on each follower token.
            struct hash * looked_up = hashlookup( table_row, follower );
            if ( ! looked_up ) {
                trans_list = new_list();
                add_to_hash( table_row, follower, (void *) trans_list );
            }
            else {
                trans_list = looked_up->data;
            }
            struct transition * reduce_transition = new_transition();
            reduce_transition->action = "reduce";
            reduce_transition->arg = prod_num;
            append_to_list( trans_list, reduce_transition );
        }
        destroy_key_list( key_list );
    }
}
Beispiel #8
0
void wtls_pdu_destroy(wtls_PDU *pdu) {
        if (pdu == NULL)
                return;

        switch (pdu->type) {
        case ChangeCipher_PDU:
				/* no memory was allocated for ChangeCipher_PDU */
 				break;
        case Alert_PDU:
				octstr_destroy(pdu->u.alert.chksum	);
				break;
        case Handshake_PDU:
                switch (pdu->u.handshake.msg_type) {
                case hello_request:
						break;
                case client_hello:
						destroy_random(pdu->u.handshake.client_hello->random);
						octstr_destroy(pdu->u.handshake.client_hello->session_id);
						destroy_key_list(pdu->u.handshake.client_hello->client_key_ids);
						destroy_key_list(pdu->u.handshake.client_hello->trusted_key_ids);
						destroy_ciphersuite_list(pdu->u.handshake.client_hello->ciphersuites);
						destroy_compression_method_list(pdu->u.handshake.client_hello->comp_methods);
						/* destroy the client_hello struct */
						gw_free(pdu->u.handshake.client_hello);
						break;
                case server_hello:
						destroy_random(pdu->u.handshake.server_hello->random);
						octstr_destroy(pdu->u.handshake.server_hello->session_id);
						/* destroy the server_hello struct */
						gw_free(pdu->u.handshake.server_hello);
						break;
                case certificate:
                        switch (pdu->u.handshake.certificate->certificateformat) {
                        case WTLSCert:
								destroy_wtls_certificate(pdu->u.handshake.certificate->wtls_certificate);
                                break;
                        case X509Cert:
								octstr_destroy(pdu->u.handshake.certificate->x509_certificate);
                                break;
                        case X968Cert:
								octstr_destroy(pdu->u.handshake.certificate->x968_certificate);
                                break;
                        }
						gw_free(pdu->u.handshake.certificate);
						break;
                case server_key_exchange:
						destroy_param_spec(pdu->u.handshake.server_key_exchange->param_spec);
                        switch (client_key_exchange_algo) {
                        case rsa_anon:
								destroy_rsa_pubkey(pdu->u.handshake.server_key_exchange->rsa_params);
								break;
                        case dh_anon:
                                destroy_dh_pubkey(pdu->u.handshake.server_key_exchange->dh_params);
								break;
                        case ecdh_anon:
                                destroy_ec_pubkey(pdu->u.handshake.server_key_exchange->ecdh_params);
								break;
						}
						gw_free(pdu->u.handshake.server_key_exchange);
						break;
                case client_key_exchange:
                        switch (client_key_exchange_algo) {
                        case rsa:
                        case rsa_anon:
                                destroy_rsa_encrypted_secret(pdu->u.handshake.client_key_exchange->rsa_params);
                                break;
                        case dh_anon:
                                destroy_dh_pubkey(pdu->u.handshake.client_key_exchange->dh_anon_params);
                                break;
                        case ecdh_anon:
                        case ecdh_ecdsa:
                                destroy_ec_pubkey(pdu->u.handshake.client_key_exchange->ecdh_params);
								break;
						}
						gw_free(pdu->u.handshake.client_key_exchange);
						break;
                case server_hello_done:
						/* nothing to do here */
                    	break;
                }
				break;
        case Application_PDU:
				octstr_destroy(pdu->u.application.data);
				break;
        }

        gw_free(pdu);
}
Beispiel #9
0
char * create_closure_key( struct itemset * current_itemset ) {
    struct item * current_item;
    struct hash * looked_up;
    struct list * production;
    int p;
    int d;
    int i;

    // Push all the items in the itemset onto the unchecked stack.
    struct list * unchecked = new_list();
    struct hash * current_items = current_itemset->items;
    struct list * key_list = new_list();
    list_keys_in_hash( current_items, key_list, "" );
    for ( i = 0; i < key_list->next_index; i++ ) {
        char * key = listlookup( key_list, i );
        append_to_list( unchecked, (void *) hashlookup( current_items, key )->data );
    }
    destroy_key_list( key_list );

    // Now process unchecked items, possibly adding more along the way.
    while ( unchecked->next_index ) {
        current_item = pop_from_list( unchecked );
        p = current_item->prod_num;
        d = current_item->dot;
        production = GRAMMAR[p].production;
        if ( d == production->next_index - 1 ) { // This item is complete.
            append_to_list( current_itemset->complete, (void *) current_item );
            continue; // Nothing more to do here.
        }
        
        // Otherwise, this item is incomplete, 
        // so record it in the appropriate ready_for slot for this itemset.
        char * predicted = listlookup( production, d + 1 );
        struct list * items_ready_for = NULL;
        struct hash * looked_up = hashlookup( current_itemset->ready_for, predicted );
        if ( ! looked_up ) {
            items_ready_for = new_list();
            add_to_hash( current_itemset->ready_for, predicted, (void *) items_ready_for );
        }
        else {
            items_ready_for = looked_up->data;
        }
        append_to_list( items_ready_for, (void *) current_item );
        
        // If the predicted symbol is terminal, this item is done processing.
        if ( ( (int *) hashlookup( IS_TERMINAL, predicted )->data ) == &TRUE ) {
            continue; // Can't expand terminals.
        }
        
        // Otherwise, the predicted symbol is nonterminal, 
        // so expand the itemset using all applicable productions.
        struct list * predicted_productions = hashlookup( PRODUCTIONS_FOR, predicted )->data;
        for ( i = 0; i < predicted_productions->next_index; i++ ) {
            int predicted_p = (long int) listlookup( predicted_productions, i );
            struct item * predicted_item = new_item();
            predicted_item->prod_num = predicted_p;
            char * predicted_key = create_item_key( predicted_item );
            if ( looked_up = hashlookup( current_items, predicted_key ) ) { // Item unneeded.
                free( predicted_item );
                free( predicted_key );
                continue;
            }

            // Otherwise, add the new item to the itemset, and to the unchecked stack.
            add_to_hash( current_items, predicted_key, (void *) predicted_item );
            free( predicted_key );
            append_to_list( unchecked, (void *) predicted_item );
        }
    }

    // Now that the itemset has been filled out, create and return its identifying string.
    key_list = new_list();
    list_keys_in_hash( current_items, key_list, "" );
    char * closure_key = join_key_list( key_list, "_" );
    destroy_key_list( key_list );
    return closure_key;
}