result test_nfa_copy_1() { int passed = 0; char* description = "nfa_copy() : CASE \"aba\""; NFA first = aba_nfa(); NFA second = nfa_copy(first); nfa_destroy(first); passed = is_true(nfa_eval(second, "aba") && !nfa_eval(second, "a")); nfa_destroy(second); return (result){passed, description}; }
p_dfa dfa_compile_from_string( const char* str ) { p_dfa pdfa; p_regc prc; p_stack ps; p_stack_ele pse; p_nfa pa, pa_x, pa_y, pa_z, pa_w; char *buffer, *ch; int v, i, j, k, x, y, z; prc = regc_compile( str ); if ( prc == NULL ) { return NULL; } regc_print( prc ); ps = stack_new(); buffer = (char*)t_alloc( sizeof(char) * BUFF_SIZE ); ch = (char*)t_alloc( sizeof(char) * CHARACTER_SET_END ); /* TODO: check the str is comfortable */ for (i = 0;i < prc->size; i++ ) { switch ( prc->buffer[i] ) { case REG_NUMBER: //printf( "%s\n", chset_num ); pa = nfa_make_from_stringbranch( chset_num ); stack_push_nfa( ps, pa ); break; case REG_WORDS: //printf( "%s\n", chset_word ); pa = nfa_make_from_stringbranch( chset_word ); stack_push_nfa( ps, pa ); break; case REG_BLACK: //printf( "%s\n", chset_black ); pa = nfa_make_from_stringbranch( chset_black ); stack_push_nfa( ps, pa ); break; case REG_LEFTPAR: stack_push_op( ps, LEFT_PAR ); break; case REG_RIGHTPAR: stack_process( ps, RIGHT_PAR ); break; case REG_LEFTSQUARE: v = 1; if ( prc->buffer[++i] == REG_NOT ) { v = 0; i ++; } for (j = 0; j < CHARACTER_SET_END; j ++ ) ch[j] = 0; do { if ( prc->buffer[i] == REG_RIGHTSQUARE ) break; else if ( prc->buffer[i] == REG_BETWEEN ) { i ++; x = prc->buffer[i++]; y = prc->buffer[i++]; if ( x > y ) { z = x; x = y; y = z; } while ( x <= y ) ch[x++] = 1; } else { x = prc->buffer[i++]; ch[x] = 1; } } while ( i < prc->size ); for (j = CHARACTER_SET_START, k = 0; j < CHARACTER_SET_END; j ++ ) { if ( !( ch[j] ^ v ) ) { buffer[k++] = (char)j; } } if ( !( ch['\t'] ^ v ) ) { buffer[k++] = (char)'\t'; } if ( !( ch['\n'] ^ v ) ) { buffer[k++] = (char)'\n'; } buffer[k] = '\0'; //printf( "%s\n", buffer ); pa = nfa_make_from_stringbranch( buffer ); stack_push_nfa( ps, pa ); break; case REG_RIGHTSQUARE: printf( "FATALERROR: right square\n" ); break; case REG_LEFTBRACE: pse = stack_top( ps ); if ( pse->type != e_nfa ) { printf( "error!" ); break; } i ++; x = prc->buffer[i++]; y = prc->buffer[i++]; pa = pse->value.pa; pa_z = nfa_multiple( pa, x ); if ( y == REG_INFINITE ) { pa_y = nfa_closure( pa ); } else { for (j = 0; j <= y-x; j ++ ) { pa_x = nfa_multiple( pa, j ); if ( j == 0 ) { pa_y = nfa_copy( pa_x ); } else { pa_w = pa_y; pa_y = nfa_branch( pa_w, pa_x ); nfa_del( pa_w ); } nfa_del( pa_x ); } } nfa_del( pa ); pa = nfa_concat( pa_z, pa_y ); nfa_del( pa_z ); nfa_del( pa_y ); stack_pop( ps ); stack_push_nfa( ps, pa ); break; case REG_RIGHTBRACE: printf( "FATALERROR: right brace\n" ); break; case REG_BRANCH: stack_process( ps, BRANCH ); stack_push_op( ps, BRANCH ); break; case REG_CONCAT: stack_process( ps, CONCAT ); stack_push_op( ps, CONCAT ); break; case REG_STAR: pse = stack_top( ps ); if ( pse->type != e_nfa ) { printf( "error!" ); break; } pa = pse->value.pa; pa_x = nfa_closure( pa ); nfa_del( pa ); stack_pop( ps ); stack_push_nfa( ps, pa_x ); break; case REG_PLUS: pse = stack_top( ps ); if ( pse->type != e_nfa ) { printf( "error!" ); break; } pa = pse->value.pa; pa_x = nfa_closure( pa ); pa_y = nfa_copy( pa ); nfa_del( pa ); pa = nfa_concat( pa_y, pa_x ); nfa_del( pa_x ); nfa_del( pa_y ); stack_pop( ps ); stack_push_nfa( ps, pa ); break; case REG_QUESTION: pse = stack_top( ps ); if ( pse->type != e_nfa ) { printf( "error!" ); break; } pa = pse->value.pa; pa_x = nfa_make_from_stringconcat( "" ); pa_y = nfa_branch( pa, pa_x ); nfa_del( pa_x ); nfa_del( pa ); stack_pop( ps ); stack_push_nfa( ps, pa_y ); break; case REG_WILDCAST: for (j = CHARACTER_SET_START, k = 0; j < CHARACTER_SET_END; j ++ ) { buffer[k++] = (char)j; } buffer[k++] = '\t'; buffer[k] = '\0'; //printf( "%s\n", buffer ); pa = nfa_make_from_stringbranch( buffer ); stack_push_nfa( ps, pa ); break; case REG_BOL: pa = nfa_make_from_stringbranch( "\2\n" ); stack_push_nfa( ps, pa ); break; case REG_EOL: pa = nfa_make_from_stringbranch( "\3\n" ); stack_push_nfa( ps, pa ); break; case REG_STRFRAGMENT: i ++; for (j = i; j < prc->size; j ++ ) { if ( prc->buffer[j] <= 0 ) { buffer[j-i] = '\0'; break; } else { buffer[j-i] = (char)prc->buffer[j]; } } if ( j == prc->size ) buffer[j-i] = '\0'; //printf( "%d %s\n", j, buffer ); pa = nfa_make_from_stringconcat( buffer ); stack_push_nfa( ps, pa ); i = j-1; break; default: printf( "FATAL ERROR %s\n", regc_str[ -prc->buffer[i] ] ); } } stack_process( ps, END ); if ( ps->top->next != NULL ) printf( "error!\n" ); pse = stack_top( ps ); pa = pse->value.pa; regc_del( prc ); pdfa = dfa_convert_from_nfa( pa ); nfa_del( pa ); stack_del( ps ); t_free( ch ); t_free( buffer ); return pdfa; }