#include enum classe { c_nl, c_perc, c_barra, c_ast, c_mais, c_menos, c_abrpar, c_fecpar, c_arroba, c_maior, c_menor, c_igual, c_digito, c_letra, c_espaco, c_tab, c_outros }; #define NCLASSES 17 enum token { k_nl, k_mod, k_div, k_mult, k_mais, k_menos, k_abrpar, k_fecpar, k_maior, k_menor, k_maiorigu, k_menorigu, k_difer, k_atrib, k_igual, k_int, k_var, k_erro, k_fim }; #define NTOKEN 19 int estado[NCLASSES][6] = { /*1000*/ /*1001*/ /*1002*/ /*1003*/ /*1004*/ /*1005*/ /*inicio*/ /*maior*/ /*menor*/ /*igual*/ /*letra*/ /*digito*/ /* c_nl */ { k_nl, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_perc */ { k_mod, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_barra */ { k_div, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_ast */ { k_mult, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_mais */ { k_mais, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_menos */ { k_menos, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_abrpar */ { k_abrpar, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_fecpar */ { k_fecpar, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_arroba */ { k_fim, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_maior */ { 1001, k_maior, k_difer, k_atrib, k_var, k_int }, /* c_menor */ { 1002, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_igual */ { 1003, k_maiorigu, k_menorigu, k_igual, k_var, k_int }, /* c_digito */ { 1005, k_maior, k_menor, k_atrib, 1004, 1005 }, /* c_letra */ { 1004, k_maior, k_menor, k_atrib, 1004, k_int }, /* c_espaco */ { 1000, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_tab */ { 1000, k_maior, k_menor, k_atrib, k_var, k_int }, /* c_outros */ { k_erro, k_maior, k_menor, k_atrib, k_var, k_int } }; char *strtoken[] = { "k_nl", "k_mod", "k_div", "k_mult", "k_mais", "k_menos", "k_abrpar", "k_fecpar", "k_maior", "k_menor", "k_maiorigual", "k_menorigual", "k_difer", "k_atrib", "k_igual", "k_int", "k_var", "k_erro", "k_fim" }; char linha[2000]; int posicao; int token; char tokenval[2000]; int tokenvalp; int getclasse(void) { int c; c = linha[posicao++]; tokenval[ tokenvalp++ ] = c; if( c>='0' && c<='9' ) return c_digito; if( c>='a' && c<='z' ) return c_letra; if( c>='A' && c<='Z' ) return c_letra; switch( c ){ case '\0': return c_nl; case '\n': return c_nl; case '%': return c_perc; case '/': return c_barra; case '*': return c_ast; case '+': return c_mais; case '-': return c_menos; case '(': return c_abrpar; case ')': return c_fecpar; case '@': return c_arroba; case '>': return c_maior; case '<': return c_menor; case '=': return c_igual; case ' ': return c_espaco; case '\t': return c_tab; }; return c_outros; } void putclasse(void) { --posicao; --tokenvalp; } void printtoken( int tk, char *val) { printf("Token <%s>", strtoken[tk]); if( tk == k_var || tk == k_int ) printf(", valor <%s>\n", val); else printf("\n"); } void gettoken() { int atual = 1000; /* estado inicial */ int x; tokenvalp = 0; do{ x = getclasse(); /*printf("char %d, classe %d, atual %d, proximo %d\n", linha[posicao-1], x, atual, estado[x][atual-1000] ); getchar();*/ atual = estado[x][atual-1000]; }while( atual >= 1000 ); if( atual==k_maior || atual==k_menor || atual==k_atrib || atual==k_var || atual==k_int ) putclasse(); token = atual; tokenval[tokenvalp] = '\0'; } int main( int argc, char *argv[]) { do{ gets(linha); posicao = 0; do{ gettoken(); printtoken( token, tokenval); }while( token != k_nl && token != k_fim ); }while( token != k_fim ); }