#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
// <==== Constantes e tipos ====>
// Boleanas
#define TRUE 1
#define FALSE 0
// Tokens
#define TOKEN_NUM 0
#define TOKEN_OP 1
#define TOKEN_PONT 2
#define TOKEN_PONTA 3
#define TOKEN_PONTB 4
#define TOKEN_PONTC 5
// Operadores
#define SOMA 0
#define SUBTRACAO 1
#define MULTIPLICACAO 2
#define DIVISAO 3
#define IGUALDADE 4
#define MAIORQUE 5
#define MENORQUE 6
#define X 7
#define Y 8
#define Z 9
// Pontuacao
#define PAR_ESQUERDO 0
#define PAR_DIREITO 1
#define CHAVE_ES 2
#define CHAVE_DI 3
#define COLCHETE_ES 4
#define COLCHETE_DI 5
#define POTENCIA 6
typedef struct
{
int tipo;
int valor;
} Token;
const char *ops = "+-*/=>< x y z";
char *codigo;
int tamanho;
// Posicao de analise
int pos;
char ler_caractere(void)
{
char c;
if (pos < tamanho)
{
c = codigo[pos];
pos++;
}
else
c = -1;
return c;
}
// Compara o caractere aos operadores definidos
int operador(char c)
{
int res;
switch (c){
case '+':
res = SOMA;
break;
case '-':
res = SUBTRACAO;
break;
case '*':
res = MULTIPLICACAO;
break;
case '/':
res = DIVISAO;
break;
case '=':
res = IGUALDADE;
break;
case '>':
res = MAIORQUE;
break;
case '<':
res = MENORQUE;
break;
case 'x':
res = X;
break;
case 'y':
res = Y;
break;
case 'z':
res = Z;
break;
default:
res = -1;
break;
}
return res;
}
void inicializa_analize(char *prog)
{
codigo = prog;
tamanho = strlen(codigo);
pos = 0;
}
Token *proximo_token(Token *tok)
{
char c;
char valor[200];
int vpos = 0;
c = ler_caractere();
// Ignora espacos em branco
while (isspace(c))
{
c = ler_caractere();
}
if (isdigit(c))
{
tok->tipo = TOKEN_NUM;
valor[vpos++] = c;
c = ler_caractere();
while (isdigit(c))
{
valor[vpos++] = c;
}
// Retornar o primeiro valor que nao seja um digito
pos--;
// Termina a string com o caractere 0 (zero)
valor[vpos] = '\0';
// Converte para num
tok->valor = atoi(valor);
}
else if (strchr(ops, c) != NULL)
{
tok->tipo = TOKEN_OP;
tok->valor = operador(c);
}
else if (c == '(' || c == ')')
{
tok->tipo = TOKEN_PONT;
tok->valor = (c == '(' ? PAR_ESQUERDO : PAR_DIREITO);
}
else if(c =='[' || c == ']')
{
tok->tipo = TOKEN_PONTA;
tok->valor = (c == '[' ? COLCHETE_ES : COLCHETE_DI);
}
else if(c =='{' || c == '}')
{
tok->tipo = TOKEN_PONTB;
tok->valor = (c == '{' ? CHAVE_ES: CHAVE_DI);
}
else if(c =='^')
{
tok->tipo = TOKEN_PONTC;
tok->valor = (c == '^' ? POTENCIA : POTENCIA);
}
else {
return NULL;
}
return tok;
}
// Converte e imprime
char *operador_str(int op){
char *res;
switch (op)
{
case SOMA:
res = "SOMA";
break;
case SUBTRACAO:
res = "SUBTRACAO";
break;
case MULTIPLICACAO:
res = "MULTIPLICACAO";
break;
case DIVISAO:
res = "DIVISAO";
break;
case IGUALDADE:
res = "IGUALDADE";
break;
case MAIORQUE:
res = "MAIORQUE";
break;
case MENORQUE:
res = "MENORQUE";
break;
case X:
res = "x";
break;
case Y:
res = "y";
break;
case Z:
res = "z";
break;
default:
res = "NENHUM";
break;
}
return res;
}
void imprime_token(Token *tok){
printf("Tipo: ");
switch(tok->tipo){
case TOKEN_PONT:
printf("Pontuacao valor: %s\n ", (tok->valor == PAR_ESQUERDO ? "PAR_ESQUERDO" : "PAR_DIREITO"));
break;
case TOKEN_PONTB:
printf("Pontuacao valor: %s\n ", (tok->valor == CHAVE_ES ? "CHAVE_ES" : "CHAVE_DI"));
break;
case TOKEN_PONTA:
printf("Pontuacao valor: %s\n ", (tok->valor == COLCHETE_ES ? "COLCHETE_ES" : "COLCHETE_DI"));
break;
case TOKEN_PONTC:
printf("Pontuacao valor: %s\n ", (tok->valor == POTENCIA ? "POTENCIA" : "POTENCIA"));
break;
case TOKEN_OP:
printf("Operador \t -- Valor: %s\n ", (operador_str(tok->valor)));
break;
case TOKEN_NUM:
printf("Numero \t -- Valor: %d\n", tok->valor);
break;
default:
printf("Token Desconhecido\n");
break;
}
}
// Funcao principal
int main(void)
{
char entrada[200];
Token tok;
printf("\nAnalise\n");
printf("Digite a expressao aritmetica (ex: ((2*3)/3) ): ");
fgets(entrada, 200, stdin);
inicializa_analize(entrada);
printf("\n=================== Analise ===================\n");
while (proximo_token(&tok) != NULL)
{
imprime_token(&tok);
}
printf("\n=================== FIM da Analise ===================\n");
return 0;
}
// <==== FIM - Funcoes =====>