/*---------------------------------------------------------------------------\ | GCLASS.C | \---------------------------------------------------------------------------*/ /* Este programa dada uma string do tipo lex(pal_ori, class_ori, class_pre, class_suf, class_suf2) retorna uma nova class. que e' a juncao das da class_ori com class_pre com class_suf com class_suf2 */ #include #include #include typedef struct feature { char name[20]; char value[20]; } feature; #define MAX_FEATURES 20 #define ACCENTS "áéíóúçãõâêôûàñ" /*---------------------------------------------------------------------------*/ static void remove_spaces(char *st_in, char *st_lex) { int i; i = 0; while (*st_in != '\0') { if (*st_in != ' ') { st_lex[i] = *st_in; i++; } st_in++; } st_lex[i] = '\0'; } /*---------------------------------------------------------------------------*/ static char *advance_begin(char *st_lex) { while (*st_lex != '[' && *st_lex != '\0') st_lex++; return st_lex; } #if 0 static char *advance_pre(char *st_lex) { st_lex++; /* advance_comma */ while (*st_lex != ',' && *st_lex != '\0') /* advance [] do pre*/ st_lex++; st_lex++; /* advance_comma */ return st_lex; } #endif /*---------------------------------------------------------------------------*/ static char *new_var(char *st_lex, feature *table, int i_table) { int i; i = 0; while (isalnum(*st_lex)) { table[i_table].name[i] = *st_lex; i++; st_lex++; } table[i_table].name[i] = '\0'; if (i == 0 || (*st_lex != '=')) { fprintf(stderr, "Invalid situation in new_var() in gclass module(%c%c)\n",*st_lex,*(st_lex+1)); return NULL; } return st_lex; } static char *new_value(char *st_lex, feature *table, int i_table) { int i; i = 0; while (isalnum(*st_lex) || (*st_lex == '_') || strchr(ACCENTS,*st_lex)) { table[i_table].value[i] = *st_lex; i++; st_lex++; } if (i == 0 || (*st_lex != ',' && *st_lex != ']')) { fprintf(stderr, "Invalid value in new_value() in gclass module\n"); } table[i_table].value[i] = '\0'; /* mark end of table */ return st_lex; } static char *advance_eq(char *st_lex) { if (*st_lex == '=') { st_lex++; return st_lex; } else { fprintf(stderr, "= sign not found in gclass module\n"); return 0; } } /*---------------------------------------------------------------------------*/ static char *build_table(char *st_lex, feature *table, int *it) { int i_table; i_table = 0; st_lex += 1; /* advance [ */ while (st_lex && *st_lex != ']' && *st_lex != '\0') { if (!(st_lex = new_var(st_lex, table, i_table))) return 0; if (!(st_lex = advance_eq(st_lex))) return 0; if (!(st_lex = new_value(st_lex, table, i_table))) return 0; i_table++; /* indi'ce do pro'ximo slot a preencher */ if (*st_lex == ',') st_lex++; } if (*st_lex == ']') st_lex++; /* advance ']' */ table[i_table].name[0] = '\0'; *it = i_table; return st_lex; } /*---------------------------------------------------------------------------*/ static int in(char *find, feature *table, int it1) { int i; i = 0; while (i < it1 && strcmp(table[i].name, find)) i++; if (i == it1) /* not found */ return -1; else return i; } static int merge_tables(feature *table1, feature *table2, int it1, int it2) { int i, pos; for (i = 0; i < it2; i++) { /* for each member of it2: */ if ((pos = in(table2[i].name, table1, it1)) != -1) /* found */ table1[pos] = table2[i]; else { /* new feature */ table1[it1] = table2[i]; it1++; } } table1[it1].name[0] = '\0'; /* mark end of table */ return it1; } /*---------------------------------------------------------------------------*/ static void build_resp(feature *table, char *st_glob, int it1) { int i; char aux[40]; st_glob[0] = '['; st_glob[1] = '\0'; for (i = 0; i < it1; i++) { sprintf(aux, "%s=%s", table[i].name, table[i].value); strcat(st_glob, aux); if (i < it1-1) { strcat(st_glob, ","); } } strcat(st_glob, "]"); } /*---------------------------------------------------------------------------*/ int gclass(char *st_in, char *st_glob) { int it1, it2; char st_aux[80]; char *st_lex; feature table[MAX_FEATURES]; /* tabela com as features da class_ori */ feature table2[MAX_FEATURES]; /* tabela com as features da class_dest */ remove_spaces(st_in, st_aux); st_lex = st_aux; st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table, &it1))) { fprintf(stderr, "-1 %s\n", st_aux); return 0; } st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table2, &it2))) { fprintf(stderr, "-2 %s\n", st_aux); return 0; } it1 = merge_tables(table, table2, it1, it2); st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table2, &it2))) { fprintf(stderr, "-2 %s\n", st_aux); return 0; } it1 = merge_tables(table, table2, it1, it2); st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table2, &it2))) { fprintf(stderr, "-2 %s\n", st_aux); return 0; } it1 = merge_tables(table, table2, it1, it2); build_resp(table, st_glob, it1); return 1; } /*---------------------------------------------------------------------------*/ int jclass(char *st_in) { int it1, it2; char *st_lex = st_in; char *st_mid; feature table[MAX_FEATURES]; /* tabela com as features da class_ori */ feature table2[MAX_FEATURES]; /* tabela com as features da class_dest */ remove_spaces(st_in, st_lex); st_mid = st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table, &it1))) { fprintf(stderr, "-1 %s\n", st_in); return 0; } st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table2, &it2))) { fprintf(stderr, "-2 %s\n", st_in); return 0; } it1 = merge_tables(table, table2, it1, it2); st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table2, &it2))) { fprintf(stderr, "-2 %s\n", st_in); return 0; } it1 = merge_tables(table, table2, it1, it2); st_lex = advance_begin(st_lex); if (!(st_lex = build_table(st_lex, table2, &it2))) { fprintf(stderr, "-2 %s\n", st_in); return 0; } it1 = merge_tables(table, table2, it1, it2); build_resp(table, st_mid, it1); strcat(st_mid,")"); return 1; } /* main() { char st_new[255]; char ex[]="lex(ABANDONEI, [CL=v,SCL=tr,T=inf], [Fsem=inv], [T=pp,N=s,P=1], [P=2])"; gclass(ex, st_new); printf("Velha=%s\nnova string= %s\n", ex,st_new); } */