Skip to content

Instantly share code, notes, and snippets.

@asm95
Created May 29, 2019 11:57
Show Gist options
  • Save asm95/1ef025c5d51481ec31d618d5ec3ac1d0 to your computer and use it in GitHub Desktop.
Save asm95/1ef025c5d51481ec31d618d5ec3ac1d0 to your computer and use it in GitHub Desktop.
Analisador Semântico V1 (Tradutores 2019/1)
%{
# include "sintatico.tab.h"
# include <string.h>
%}
%%
([0-9]{1,})((\.)?[0-9]{1,})? {return NUM;}
("var") {return VAR;}
("leia") {return LEIA;}
("escreva") {return ESCREVA;}
("int"|"float") {yylval.id = (char *) strdup(yytext); return TIPO;}
[a-zA-Z][a-zA-Z0-9]* {yylval.id = (char *) strdup(yytext); return ID;}
\"(\\.|[^"])*\ {return STRING;}
[ \t\n]+ {;}
. {return yytext[0];}
%%
int yywrap() {
return 1;
}
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define YYDEBUG 1
#define KNRM "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"
extern int yydebug;
extern FILE *yyin;
int yyerror (char *s);
int yylex ();
typedef struct symbol {
char type[30];
char name[200];
int used;
struct symbol *next;
} symbol;
typedef struct error {
char name[400];
struct error* next;
} error;
char* currentType;
symbol *symbol_table = (symbol*)0;
error *errors= (error*)0;
error *warnings= (error*)0;
void push_symbol(char* sym_name);
symbol* find_symbol(char *sym_name);
void print_color_red(){
printf("%s", KRED);
};
void print_color_yellow(){
printf("%s", KYEL);
};
void print_color_end(){
printf("%s", KNRM);
};
void push_error(error **list, char* error_name);
void print_errors(error **list);
int list_length(error **list);
void print_symbol_table();
void push_symbol_table (char * sym_name);
void verify_variables_not_used();
void verify_symbol_table (char * sym_name);
%}
%union {
char *id;
}
%token NUM
%token <id> ID
%token LEIA
%token ESCREVA
%token OPA
%token OPM
%token STRING
%token <id> TIPO
%token VAR
%%
programa: bloco_var
'{' lista_cmds '}' {;}
;
bloco_var: /*empty*/
| VAR '{' lista_decl_var '}' {;}
;
lista_decl_var: decl_var {;}
| decl_var ';' lista_decl_var {;}
;
decl_var: TIPO {currentType = $1;} lista_var {;}
;
lista_cmds: cmd {;}
| cmd ';' lista_cmds {;}
;
cmd: ID '=' exp { verify_symbol_table($1); }
| leia {;}
| escreva {;}
;
leia: LEIA '(' lista_args ')' {;} /*Perguntar se "leia" é um token ou se eh definido na gramatica */
;
escreva: ESCREVA '(' lista_output ')' {;}
;
lista_args: ID { verify_symbol_table($1); }
| ID ',' lista_args { verify_symbol_table($1); }
;
lista_var: ID { push_symbol_table($1); }
| ID ',' lista_var { push_symbol_table($1); }
;
lista_output: output {;}
| output ',' lista_output {;}
;
output: exp {;}
/*| '"' STRING '"' {;} */
;
exp:
termo {;}
| exp opa termo {;}
// | exp '-' termo {;}
;
termo:
fator {;}
| termo '*' fator {;}
| termo '/' fator {;}
;
opa:
'+' {;}
| '-' {;}
;
fator:
NUM {;}
| opa NUM {;}
| ID { verify_symbol_table($1); }
| '(' exp ')' {;}
;
%%
int main (int argc, char *argv[])
{
yydebug = 0;
if (argc == 1) {
yyin = fopen("entrada.txt", "r");
}
else{
yyin = fopen(argv[1], "r");
}
if(yyin == NULL) {
printf("Arquivo invalido\n");
return 0;
}
if(!(yyparse ())) {
if(list_length(&errors) > 0){
print_color_red();
print_errors(&errors);
print_color_end();
}else{
verify_variables_not_used();
print_color_yellow();
print_errors(&warnings);
print_color_end();
// print_symbol_table();
}
}
}
int yyerror (char *s) /* Called by yyparse on error */
{
print_color_red();
printf ("Problema com a analise sintatica!\n");
print_color_end();
return 0;
}
void push_symbol(char *sym_name){
symbol *aux = (symbol*) malloc(sizeof(symbol));
strcpy(aux->name, sym_name);
strcpy(aux->type,currentType);
aux->used = 0;
aux->next = symbol_table;
symbol_table = aux;
}
symbol* find_symbol( char * sym_name){
symbol *aux = symbol_table;
while(aux!= NULL){
if(strcmp(aux->name, sym_name) == 0)
return aux;
aux = aux->next;
}
return 0;
}
void push_error(error **list, char *error_name){
error *aux = (error*) malloc(sizeof(error));
strcpy(aux->name,error_name);
aux->next = (*list);
(*list) = aux;
}
void print_errors(error **list){
error *aux = *list;
while(aux!= NULL){
printf("%s\n", aux->name);
aux = aux->next;
}
printf("\n");
}
int list_length(error **list){
int length = 0;
error *aux = *list;
while(aux!= NULL){
aux = aux->next;
length++;
}
return length;
}
void push_symbol_table (char * sym_name){
symbol* s = find_symbol(sym_name);
if(!s){
push_symbol (sym_name);
}else{
char message[400];
snprintf(message, 400, "ERROR: Variable `%s` has already been defined!", sym_name);
push_error(&errors, message);
}
}
void verify_symbol_table(char * sym_name){
symbol* aux = find_symbol(sym_name);
if(aux == 0){
char message[400];
snprintf(message, 400, "ERROR: Variable `%s` has not been declared.", sym_name);
push_error(&errors, message);
}else{
aux->used = 1;
}
}
void verify_variables_not_used(){
symbol *table = symbol_table;
while(table!= NULL){
if(table->used == 0){
char message[400];
snprintf(message, 400, "WARNING: Variable `%s` declared, but not used.", table->name);
push_error(&warnings, message);
}
table = table->next;
}
}
void print_symbol_table(){
symbol *aux = symbol_table;
printf("Type\t Name\t\t\tUSED\n");
while(aux!= NULL){
printf("%s\t %s \t\t\t%s\n", aux->type, aux->name, (aux->used == 0) ? "NO" : "YES");
aux = aux->next;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment