/*---------------------------------------------------------------------------\
| 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 <ctype.h>
#include <stdio.h>
#include <string.h>
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);
}
*/