Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "semantics.h"
- char* type_spec[] = {"char","int","void","short","double","undef"};
- Symbol* new_symbol(char* id,symbol_type s_type){
- Symbol* elem = (Symbol*)malloc(sizeof(Symbol));
- elem->id = id;
- elem->s_type = s_type;
- elem->is_param=0;
- elem->params = (Symbol**)malloc(2000*sizeof(Symbol*));
- elem->type = "undef";
- elem->num_params = 0;
- elem->func_definition = NULL;
- elem->next = NULL;
- return elem;
- }
- char* tolowercase(char* type){
- if(strcmp(type,"Char")==0)
- return "char";
- else if(strcmp(type,"Int")==0)
- return "int";
- else if(strcmp(type,"Void")==0)
- return "void";
- else if(strcmp(type,"Short")==0)
- return "short";
- else if(strcmp(type,"Double")==0)
- return "double";
- return "null";
- }
- Symbol* init_symbol_table(Node* node){
- Symbol* st = new_symbol(node->type,Global);
- Symbol* putchar = new_symbol("putchar",FuncDecl);
- Symbol* getchar = new_symbol("getchar",FuncDecl);
- putchar->type = "int";
- putchar->num_params = 1;
- putchar->params[0] = new_symbol("var",Variable);
- putchar->params[0]->type = "int";
- getchar->type = "int";
- getchar->num_params=1;
- getchar->params[0] = new_symbol("var",Variable);
- getchar->params[0]->type = "void";
- putchar->next = getchar;
- st->next = putchar;
- return st;
- }
- Symbol* search_symbol(char *type,Symbol* function){
- Symbol* symbol = NULL;
- if(function!=NULL){
- Symbol *aux = function->next;
- while(aux != NULL){
- if(strcmp(aux->id, type)==0)
- symbol = aux;
- aux = aux->next;
- }
- }
- if(symbol==NULL || function==NULL){
- Symbol *aux = ST->next;
- while(aux != NULL){
- if(strcmp(aux->id, type)==0)
- symbol = aux;
- aux = aux->next;
- }
- }
- return symbol;
- }
- Symbol* search_function(char *type,Node* node){
- Symbol* symbol = NULL;
- Symbol *aux = ST->next;
- while(aux != NULL){
- if(strcmp(aux->id, type)==0){
- if(aux->num_params == 1 && strcmp(aux->params[0]->type,"void")==0 && node->numChilds==1){
- return aux;
- }
- else if(aux->num_params == node->numChilds-1){
- return aux;
- }
- else
- symbol = aux;
- }
- aux = aux->next;
- }
- return symbol;
- }
- Symbol* search_variable(char *type,Symbol* function){
- Symbol* symbol = NULL;
- if(function!=NULL){
- Symbol *aux = function->next;
- while(aux != NULL){
- if(strcmp(aux->id, type)==0 && aux->num_params==0)
- symbol = aux;
- aux = aux->next;
- }
- }
- if(symbol==NULL || function==NULL){
- Symbol *aux = ST->next;
- while(aux != NULL){
- if(strcmp(aux->id, type)==0 && aux->num_params==0)
- symbol = aux;
- aux = aux->next;
- }
- }
- return symbol;
- }
- Symbol* search_on_function(char *type,Symbol* function){
- if(function!=NULL){
- Symbol *aux = function->next;
- while(aux != NULL){
- if(strcmp(aux->id, type)==0)
- return aux;
- aux = aux->next;
- }
- }
- return NULL;
- }
- int check_params(Node *node,Symbol* ST){
- int i,j;
- char* params1 = (char*)malloc(512*sizeof(char)),*params2 = (char*)malloc(512*sizeof(char));
- sprintf(params1,"%s(",tolowercase(node->childs[0]->type));
- sprintf(params2,"%s(",ST->type);
- for(i = 0;i< node->childs[2]->numChilds;i++){
- Symbol* newsymbol;
- if(node->childs[2]->numChilds>1 && strcmp(tolowercase(node->childs[2]->childs[i]->childs[0]->type),"void")==0){//se for mais do que um parametro, e um deles for void
- error_semantic = 1;
- printf("Line %d, col %d: Invalid use of void type in declaration\n",node->childs[2]->childs[i]->childs[0]->countline,node->childs[2]->childs[i]->childs[0]->countcol);
- return 0;
- }else if(node->childs[2]->numChilds==1 && strcmp(tolowercase(node->childs[2]->childs[i]->childs[0]->type),"void")==0 && node->childs[2]->childs[i]->numChilds>=2){// se for só 1 parametro, mas for void + variavel
- error_semantic = 1;
- printf("Line %d, col %d: Invalid use of void type in declaration\n",node->childs[2]->childs[i]->childs[0]->countline,node->childs[2]->childs[i]->childs[0]->countcol);
- return 0;
- }else if(node->childs[2]->childs[i]->numChilds>=2 && search_on_function(node->childs[2]->childs[i]->childs[1]->value,ST->func_definition)){
- error_semantic = 1;
- printf("Line %d, col %d: Symbol %s already defined\n",node->childs[2]->childs[i]->childs[1]->countline,node->childs[2]->childs[i]->childs[1]->countcol,node->childs[2]->childs[i]->childs[1]->value);
- return 0;
- }else if(i<ST->num_params && strcmp(ST->params[i]->type,tolowercase(node->childs[2]->childs[i]->childs[0]->type))!=0){//se no caso de a funcao ter sido declarada previamente, os tipos dos parametros nao coincidirem
- error_semantic = 1;
- for(j=0;j<ST->num_params;j++){
- if(j>0){
- strcat(params1,",");
- strcat(params1,tolowercase(node->childs[2]->childs[j]->childs[0]->type));
- strcat(params2,",");
- strcat(params2,ST->params[j]->type);
- }
- else{
- strcat(params1,tolowercase(node->childs[2]->childs[j]->childs[0]->type));
- strcat(params2,ST->params[j]->type);
- }
- }
- strcat(params1,")");
- strcat(params2,")");
- printf("Line %d, col %d: Conflicting types (got %s, expected %s)\n",node->childs[1]->countline,node->childs[1]->countcol,params1,params2);
- return 0;
- }else if(strcmp(node->childs[2]->childs[i]->childs[0]->type,"Void")!=0 && node->childs[2]->childs[i]->numChilds>=2){
- newsymbol = new_symbol(node->childs[2]->childs[i]->childs[1]->value,Variable);
- newsymbol->is_param = 1;
- newsymbol->type = (char*)strdup(tolowercase(node->childs[2]->childs[i]->childs[0]->type));
- add_symbol(ST->func_definition,newsymbol);
- }
- }
- return 1;
- }
- void check_funcdefinition(Node* node, Symbol* ST){ //verificar se tem o mesmo nº de parametros
- int i;
- Symbol* aux = search_function(node->childs[1]->value,node->childs[2]);
- Symbol* newsymbol = new_symbol(node->childs[1]->value,FuncTable);
- char* params1 = (char*)malloc(512*sizeof(char)),*params2 = (char*)malloc(512*sizeof(char));
- int checkparam;
- newsymbol->type = tolowercase(node->childs[0]->type);
- if(aux == NULL){
- check_funcdeclaration(node,ST);
- aux = search_function(node->childs[1]->value,node->childs[2]);
- }
- if(aux!=NULL){
- /*aux->func_definition = newsymbol;
- check_return(aux->func_definition);
- checkparam = check_params(node,aux);*/
- checkparam = 1;
- if(checkparam && aux->func_definition !=NULL){
- //error_semantic = 1;
- //printf("Line %d, col %d: Symbol %s already defined\n",node->childs[1]->countline,node->childs[1]->countcol,node->childs[1]->value);
- Node* childs = node->childs[3];
- aux->func_definition = newsymbol;
- for(i = 0; i < childs->numChilds;i++){
- check_variable(childs->childs[i],aux->func_definition);
- }
- }
- if(checkparam && aux->num_params==node->childs[2]->numChilds){
- Node* childs = node->childs[3];
- aux->func_definition = newsymbol;
- check_return(aux->func_definition);
- checkparam = check_params(node,aux);
- for(i = 0; i < childs->numChilds;i++){
- check_variable(childs->childs[i],aux->func_definition);
- }
- }
- if(checkparam && aux->num_params!=node->childs[2]->numChilds){
- error_semantic = 1;
- sprintf(params1,"%s(",newsymbol->type);
- if(aux->num_params ==0)
- sprintf(params2,"%s",aux->type);
- else
- sprintf(params2,"%s(",aux->type);
- for(i=0;i<node->childs[2]->numChilds || i<aux->num_params;i++){
- if(i>0){
- if(i<node->childs[2]->numChilds)
- strcat(params1,",");
- if(aux->num_params>0 && i<aux->num_params)
- strcat(params2,",");
- }
- if(i<node->childs[2]->numChilds)
- strcat(params1,tolowercase(node->childs[2]->childs[i]->childs[0]->type));
- if(aux->num_params>0 && i<aux->num_params)
- strcat(params2,aux->params[i]->type);
- }
- strcat(params1,")");
- if(aux->num_params>0)
- strcat(params2,")");
- printf("Line %d, col %d: Conflicting types (got %s, expected %s)\n",node->childs[1]->countline,node->childs[1]->countcol,params1,params2);
- aux->func_definition =NULL;
- }else if(checkparam && strcmp(aux->type,tolowercase(node->childs[0]->type))!=0){
- sprintf(params1,"%s(",tolowercase(node->childs[0]->type));
- sprintf(params2,"%s(",aux->type);
- error_semantic = 1;
- for(i=0;i<aux->num_params;i++){
- if(i>0){
- strcat(params1,",");
- strcat(params2,",");
- }
- strcat(params1,tolowercase(node->childs[2]->childs[i]->childs[0]->type));
- strcat(params2,aux->params[i]->type);
- }
- strcat(params1,")");
- strcat(params2,")");
- printf("Line %d, col %d: Conflicting types (got %s, expected %s)\n",node->childs[1]->countline,node->childs[1]->countcol,params1,params2);
- aux->func_definition = NULL;
- }
- }
- }
- void check_ifwhile(Node* node, Symbol* ST){
- int i;
- for(i=0;i<node->numChilds;i++){
- check_variable(node->childs[i],ST);
- }
- }
- Node* check_program(Node* node){
- error_semantic = 0;
- int i;
- ST = init_symbol_table(node);
- if(strcmp(node->type,"Program")==0){
- for(i=0;i<node->numChilds;i++){
- if(strcmp(node->childs[i]->type,"Declaration")==0){
- check_declaration(node->childs[i],ST,0);
- }
- else if(strcmp(node->childs[i]->type,"FuncDeclaration")==0){
- check_funcdeclaration(node->childs[i],ST);
- }
- else if(strcmp(node->childs[i]->type,"FuncDefinition")==0){
- check_funcdefinition(node->childs[i],ST);
- }
- }
- }
- return node;
- }
- void check_declaration(Node* node, Symbol* ST,int is_on_function){
- Symbol* newsymbol = new_symbol(node->childs[1]->value,Variable);
- newsymbol->type = tolowercase(node->childs[0]->type);
- Symbol* symb;
- int add = 1;
- if(is_on_function){
- symb = search_on_function(node->childs[1]->value,ST);
- if(strcmp(node->childs[0]->type,"Void")==0){ // se for do tipo void
- add = 0;
- error_semantic = 1;
- printf("Line %d, col %d: Invalid use of void type in declaration\n",node->childs[1]->countline,node->childs[1]->countcol);
- }
- if(symb != NULL){ // se ja tiver sido declarado na funcao
- add = 0;
- error_semantic = 1;
- printf("Line %d, col %d: Symbol %s already defined\n",node->childs[1]->countline,node->childs[1]->countcol,node->childs[1]->value);
- }
- }else{
- if(strcmp(node->childs[0]->type,"Void")==0){ // se for do tipo void
- add = 0;
- error_semantic = 1;
- printf("Line %d, col %d: Invalid use of void type in declaration\n",node->childs[1]->countline,node->childs[1]->countcol);
- }
- else if((symb = search_symbol(node->childs[1]->value,NULL))!=NULL && symb->num_params>=1){ //se existir e for uma funcao
- add = 0;
- error_semantic = 1;
- printf("Line %d, col %d: Symbol %s already defined\n",node->childs[1]->countline,node->childs[1]->countcol,node->childs[1]->value);
- }else if(symb!=NULL && strcmp(symb->type,tolowercase(node->childs[0]->type))!=0){ // se existir e for de tipo diferente
- error_semantic = 1;
- add = 0;
- printf("Line %d, col %d: Symbol %s already defined\n",node->childs[1]->countline,node->childs[1]->countcol,node->childs[1]->value);
- }else if(symb!=NULL) // se existir, não volta a adicionar na tabela de simbolos
- add = 0;
- }
- if(add)
- add_symbol(ST,newsymbol);
- if(node->numChilds>=3)
- check_variable(node->childs[2],ST);
- }
- void check_variable(Node* terminal,Symbol *ST){
- int i;
- if(strcmp(terminal->type,"IntLit")==0){
- terminal->s_type = "int";
- }
- else if(strcmp(terminal->type,"ChrLit")==0)
- terminal->s_type = "int";
- else if(strcmp(terminal->type,"RealLit")==0)
- terminal->s_type = "double";
- else if(strcmp(terminal->type,"Call")==0){
- check_call(terminal,ST);
- }
- else if(strcmp(terminal->type,"Id")==0){
- check_id(terminal,ST);
- }
- else if(strcmp(terminal->type,"Add")==0 || strcmp(terminal->type,"Sub")==0 || strcmp(terminal->type,"Mul")==0 || strcmp(terminal->type,"Div")==0){
- check_addsubmultdiv(terminal,ST);
- }
- else if(strcmp(terminal->type,"Mod")==0){
- check_mod(terminal,ST);
- }
- else if(strcmp(terminal->type,"Eq")==0 || strcmp(terminal->type,"Ne")==0 || strcmp(terminal->type,"Lt")==0 || strcmp(terminal->type,"Le")==0 || strcmp(terminal->type,"Ge")==0 || strcmp(terminal->type,"Gt")==0)
- check_eq_ne_lt_le_ge(terminal,ST);
- else if(strcmp(terminal->type,"Store")==0)
- check_store(terminal,ST);
- else if(strcmp(terminal->type,"Minus")==0 || strcmp(terminal->type,"Not")==0 || strcmp(terminal->type,"Plus")==0)
- check_minusplusnot(terminal,ST);
- else if(strcmp(terminal->type,"Declaration")==0){
- check_declaration(terminal,ST,1);
- }
- else if(strcmp(terminal->type,"Return")==0){
- verify_return(terminal,ST);
- }
- else if(strcmp(terminal->type,"Or")==0 || strcmp(terminal->type,"And")==0)
- check_and_or(terminal,ST);
- else if(strcmp(terminal->type,"BitWiseAnd")==0 || strcmp(terminal->type,"BitWiseOr")==0 || strcmp(terminal->type,"BitWiseXor")==0)
- check_bitwise(terminal,ST);
- else if(strcmp(terminal->type,"StatList")==0){
- for(i=0;i<terminal->numChilds;i++)
- check_variable(terminal->childs[i],ST);
- }
- else if(strcmp(terminal->type,"If")==0 || strcmp(terminal->type,"While")==0){
- check_ifwhile(terminal,ST);
- }
- else if(strcmp(terminal->type,"Comma")==0){
- check_comma(terminal,ST);
- }
- }
- void check_comma(Node* terminal, Symbol* ST){
- int i;
- for(i=0;i<terminal->numChilds;i++)
- check_variable(terminal->childs[i],ST);
- terminal->s_type = terminal->childs[1]->s_type;
- }
- void check_and_or(Node* terminal, Symbol* ST){
- int i;
- for(i=0;i<terminal->numChilds;i++){
- check_variable(terminal->childs[i],ST);
- }
- if(strcmp(terminal->childs[0]->s_type,"void")==0){
- error_semantic = 1;
- if(strcmp(terminal->type,"And")==0)
- printf("Line %d, col %d: Operator && cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol,terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else
- printf("Line %d, col %d: Operator || cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol,terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- }
- else
- terminal->s_type = "int";
- }
- void check_bitwise(Node* terminal, Symbol* ST){
- int i;
- for(i=0;i<terminal->numChilds;i++){
- check_variable(terminal->childs[i],ST);
- }
- if(strcmp(terminal->childs[0]->s_type,"int")==0 && strcmp(terminal->childs[1]->s_type,"int")==0)
- terminal->s_type = "int";
- else{
- error_semantic = 1;
- if(strcmp(terminal->type,"BitWiseAnd")==0)
- printf("Line %d, col %d: Operator & cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol,terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else if(strcmp(terminal->type,"BitWiseOr")==0)
- printf("Line %d, col %d: Operator | cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol,terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else
- printf("Line %d, col %d: Operator ^ cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol,terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- }
- terminal->s_type = "int";
- }
- void verify_return(Node* terminal,Symbol* ST){
- int i;
- for(i=0;i<terminal->numChilds;i++){
- check_variable(terminal->childs[i],ST);
- /*if(i == 0){
- if(strcmp(ST->type,terminal->childs[0]->s_type)!=0){
- error_semantic = 1;
- printf("Line %d, col %d: Conflicting types (got %s, expected %s)\n",terminal->countline,terminal->countcol,terminal->childs[0]->s_type,ST->type);
- }
- }*/
- }
- }
- void check_minusplusnot(Node* terminal,Symbol* ST){
- check_variable(terminal->childs[0],ST);
- if(strcmp(terminal->childs[0]->s_type,"void")==0){
- error_semantic = 1;
- if(strcmp(terminal->type,"Minus")==0)
- printf("Line %d, col %d: Operator - cannot be applied to type %s\n",terminal->childs[0]->countline,terminal->childs[0]->countcol,terminal->childs[0]->s_type);
- else if(strcmp(terminal->type,"Plus")==0)
- printf("Line %d, col %d: Operator + cannot be applied to type %s\n",terminal->childs[0]->countline,terminal->childs[0]->countcol, terminal->childs[0]->s_type);
- else
- printf("Line %d, col %d: Operator ! cannot be applied to type %s\n",terminal->childs[0]->countline,terminal->childs[0]->countcol, terminal->childs[0]->s_type);
- }
- else if(strcmp(terminal->type,"Not")==0)
- terminal->s_type = (char*)strdup("int");
- else
- terminal->s_type = terminal->childs[0]->s_type;
- if(strcmp(terminal->type,"Minus")== 0){
- char aux[100] = "";
- aux[0] = '-';
- strcat((char*)aux,(char*)terminal->childs[0]->value);
- terminal->value = strdup(aux);
- }
- else
- terminal->value = terminal->childs[0]->value;
- }
- void check_store(Node* terminal,Symbol* function){
- int i;
- for(i=0;i<terminal->numChilds;i++){
- check_variable(terminal->childs[i],function);
- }
- if(strcmp(terminal->childs[0]->type,"Id")!=0){
- error_semantic = 1;
- printf("Line %d, col %d: Lvalue required\n",terminal->childs[0]->countline,terminal->childs[0]->countcol);
- }
- else{
- terminal->s_type = terminal->childs[0]->s_type;
- }
- }
- void check_eq_ne_lt_le_ge(Node* terminal, Symbol* function){
- int i;
- for(i=0;i<terminal->numChilds;i++){
- check_variable(terminal->childs[i],function);
- }
- if(strcmp(terminal->childs[0]->s_type,"void")==0 || strcmp(terminal->childs[1]->s_type,"void") == 0){
- error_semantic = 1;
- if(strcmp(terminal->type,"Eq")==0)
- printf("Line %d, col %d: Operator == cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else if(strcmp(terminal->type,"Ne")==0)
- printf("Line %d, col %d: Operator != cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else if(strcmp(terminal->type,"Lt")==0)
- printf("Line %d, col %d: Operator < cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else if(strcmp(terminal->type,"Gt")==0)
- printf("Line %d, col %d: Operator > cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else if(strcmp(terminal->type,"Le")==0)
- printf("Line %d, col %d: Operator <= cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else if(strcmp(terminal->type,"Ge")==0)
- printf("Line %d, col %d: Operator >= cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- }
- else
- terminal->s_type = (char*)strdup("int");
- }
- void check_id(Node* terminal, Symbol* function){
- Symbol* symbol = search_variable(terminal->value,function);
- if(symbol!=NULL){
- terminal->s_type = (char*)strdup(symbol->type);
- }else{
- error_semantic =1;
- printf("Line %d, col %d: Unknown symbol %s\n",terminal->countline,terminal->countcol,terminal->value);
- terminal->s_type = (char*)strdup("undef2");
- }
- }
- void check_mod(Node* terminal,Symbol* ST){
- int i;
- for(i=0;i<terminal->numChilds;i++){
- check_variable(terminal->childs[i],ST);
- }
- if(strcmp(terminal->childs[0]->s_type,"int")==0 && strcmp(terminal->childs[1]->s_type,"int")==0){
- terminal->s_type = (char*)strdup(terminal->childs[0]->s_type);
- }
- else{
- error_semantic = 1;
- printf("Line %d, col %d: Operator %% cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- terminal->s_type = (char*)strdup("int");
- }
- }
- void check_addsubmultdiv(Node* terminal,Symbol* ST){
- int i;
- for(i=0;i<terminal->numChilds;i++){
- check_variable(terminal->childs[i],ST);
- }
- if(strcmp(terminal->childs[0]->s_type,"void")==0 || strcmp(terminal->childs[1]->s_type,"void") == 0){
- error_semantic = 1;
- if(strcmp(terminal->type,"Add")==0)
- printf("Line %d, col %d: Operator + cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else if(strcmp(terminal->type,"Sub")==0)
- printf("Line %d, col %d: Operator - cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- else
- printf("Line %d, col %d: Operator / cannot be applied to types %s, %s\n",terminal->countline,terminal->countcol, terminal->childs[0]->s_type,terminal->childs[1]->s_type);
- }else{
- if(strcmp(terminal->childs[0]->s_type,terminal->childs[1]->s_type)==0){
- terminal->s_type = terminal->childs[0]->s_type;
- }
- else if((strcmp(terminal->childs[0]->s_type,"double")==0 && (strcmp(terminal->childs[1]->s_type,"char")==0 || strcmp(terminal->childs[1]->s_type,"int")==0 || strcmp(terminal->childs[1]->s_type,"short")==0)) || (strcmp(terminal->childs[1]->s_type,"double")==0 && (strcmp(terminal->childs[0]->s_type,"char")==0 || strcmp(terminal->childs[0]->s_type,"int")==0 || strcmp(terminal->childs[0]->s_type,"short")==0)))
- terminal->s_type = "double";
- else if((strcmp(terminal->childs[0]->s_type,"char")==0 && strcmp(terminal->childs[1]->s_type,"int")==0) || (strcmp(terminal->childs[1]->s_type,"char")==0 && strcmp(terminal->childs[0]->s_type,"int")==0))
- terminal->s_type = "int";
- else if((strcmp(terminal->childs[0]->s_type,"short")==0 && strcmp(terminal->childs[1]->s_type,"int")==0) || (strcmp(terminal->childs[1]->s_type,"short")==0 && strcmp(terminal->childs[0]->s_type,"int")==0))
- terminal->s_type = "int";
- else if((strcmp(terminal->childs[0]->s_type,"short")==0 && strcmp(terminal->childs[1]->s_type,"char")==0) || (strcmp(terminal->childs[1]->s_type,"short")==0 && strcmp(terminal->childs[0]->s_type,"char")==0))
- terminal->s_type = "short";
- else
- terminal->s_type = (char*)strdup(terminal->childs[0]->s_type);
- }
- }
- void check_call(Node* call,Symbol* function){
- int i;
- Symbol* symbol = search_function(call->childs[0]->value,call);
- if(symbol!=NULL){
- if(symbol->num_params>0 && ((strcmp(symbol->params[0]->type,"void")==0 && symbol->num_params==call->numChilds) ||(strcmp(symbol->params[0]->type,"void")!=0 && symbol->num_params==call->numChilds-1))){
- call->childs[0]->is_function=1;
- call->childs[0]->s_type = symbol->type;
- call->childs[0]->num_params = symbol->num_params;
- for(i=0;i<symbol->num_params;i++){
- call->childs[0]->params[i] = symbol->params[i]->type;
- }
- for(i=1;i<call->numChilds;i++){
- check_variable(call->childs[i],function);
- }
- call->s_type = symbol->type;
- }else if(symbol->num_params==0){
- error_semantic = 1;
- printf("Line %d, col %d: Symbol %s is not a function\n",call->childs[0]->countline,call->childs[0]->countcol,call->childs[0]->value);
- call->s_type = (char*)strdup(call->childs[0]->s_type);
- }else if(symbol->num_params>0 && strcmp(symbol->params[0]->type,"void")==0){
- error_semantic = 1;
- printf("Line %d, col %d: Wrong number of arguments to function %s (got %d, required %d)\n",call->childs[0]->countline,call->childs[0]->countcol,call->childs[0]->value,call->numChilds-1,symbol->num_params-1);
- }else{
- error_semantic = 1;
- printf("Line %d, col %d: Wrong number of arguments to function %s (got %d, required %d)\n",call->childs[0]->countline,call->childs[0]->countcol,call->childs[0]->value,call->numChilds-1,symbol->num_params);
- }
- }else{
- error_semantic = 1;
- for(i=0;i<call->numChilds;i++){
- check_variable(call->childs[i],function);
- }
- call->s_type = (char*)strdup(call->childs[0]->s_type);
- printf("Line %d, col %d: Symbol %s is not a function\n",call->childs[0]->countline,call->childs[0]->countcol,call->childs[0]->value);
- }
- }
- void check_return(Symbol* ST){
- Symbol* newsymbol = new_symbol("return",Return);
- newsymbol->type = (char*)strdup(ST->type);
- add_symbol(ST,newsymbol);
- }
- void check_funcdeclaration(Node* node,Symbol* ST){
- Symbol* newsymbol = new_symbol(node->childs[1]->value,FuncDecl);
- Symbol* symb;
- int add=1;
- newsymbol->type = (char*)strdup(tolowercase(node->childs[0]->type));
- int i,j,k;
- int errorvoid = 0;
- char* params1=(char*)malloc(512*sizeof(char)),*params2=(char*)malloc(512*sizeof(char));
- newsymbol->num_params = node->childs[2]->numChilds;
- char* var = (char*)malloc(512*sizeof(char));
- for(i=0;i<newsymbol->num_params;i++){
- sprintf(var,"%s%d","var",i);
- if(node->childs[2]->childs[i]->numChilds>=2)
- newsymbol->params[i] = new_symbol(node->childs[2]->childs[i]->childs[1]->value,Variable);
- else
- newsymbol->params[i] = new_symbol(var,Variable);
- for(k=0;k<i;k++){
- if(node->childs[2]->childs[i]->numChilds>=2){
- if(strcmp(newsymbol->params[k]->id,node->childs[2]->childs[i]->childs[1]->value)==0){
- printf("Line %d, col %d: Symbol %s already defined\n",node->childs[2]->childs[i]->childs[1]->countline,node->childs[2]->childs[i]->childs[1]->countcol,node->childs[2]->childs[i]->childs[1]->value);
- error_semantic = 1;
- errorvoid = 1;
- break;
- }
- }
- }
- newsymbol->params[i]->type = tolowercase(node->childs[2]->childs[i]->childs[0]->type);
- if(!errorvoid && newsymbol->num_params>1 && strcmp(newsymbol->params[i]->type,"void")==0){
- add = 0;
- error_semantic = 1;
- printf("Line %d, col %d: Invalid use of void type in declaration\n",node->childs[2]->childs[i]->childs[0]->countline,node->childs[2]->childs[i]->childs[0]->countcol);
- errorvoid = 1;
- }else if(!errorvoid && newsymbol->num_params==1 && strcmp(newsymbol->params[i]->type,"void")==0 && node->childs[2]->childs[i]->numChilds>=2){
- add = 0;
- error_semantic = 1;
- printf("Line %d, col %d: Invalid use of void type in declaration\n",node->childs[2]->childs[i]->childs[0]->countline,node->childs[2]->childs[i]->childs[0]->countcol);
- errorvoid = 1;
- }
- }
- if((symb = search_function(node->childs[1]->value,node->childs[2]))!=NULL && symb->num_params!=newsymbol->num_params){
- add = 0;
- if(!errorvoid){
- error_semantic = 1;
- sprintf(params1,"%s(",newsymbol->type);
- if(symb->num_params ==0)
- sprintf(params2,"%s",symb->type);
- else
- sprintf(params2,"%s",symb->type);
- for(i=0;i<newsymbol->num_params;i++){
- if(i>0){
- strcat(params1,",");
- if(symb->num_params>0)
- strcat(params2,",");
- }
- strcat(params1,newsymbol->params[i]->type);
- if(symb->num_params>0)
- strcat(params2,symb->params[i]->type);
- }
- strcat(params1,")");
- if(symb->num_params>0)
- strcat(params2,")");
- printf("Line %d, col %d: Conflicting types (got %s, expected %s)\n",node->childs[1]->countline,node->childs[1]->countcol,params1,params2);
- }
- }
- else if(symb!=NULL && symb->num_params==newsymbol->num_params){
- add = 0;
- if(!errorvoid){
- sprintf(params1,"%s(",tolowercase(node->childs[0]->type));
- sprintf(params2,"%s(",symb->type);
- for(i=0;i<symb->num_params;i++){
- if(strcmp(symb->params[i]->type,newsymbol->params[i]->type)!=0 || strcmp(symb->type,newsymbol->type)!=0){
- error_semantic = 1;
- for(j=0;j<symb->num_params;j++){
- if(j>0){
- strcat(params1,",");
- strcat(params1,tolowercase(node->childs[2]->childs[j]->childs[0]->type));
- strcat(params2,",");
- strcat(params2,symb->params[j]->type);
- }
- else{
- strcat(params1,tolowercase(node->childs[2]->childs[j]->childs[0]->type));
- strcat(params2,symb->params[j]->type);
- }
- }
- strcat(params1,")");
- strcat(params2,")");
- printf("Line %d, col %d: Conflicting types (got %s, expected %s)\n",node->childs[1]->countline,node->childs[1]->countcol,params1,params2);
- break;
- }
- }
- }
- }
- if(add)
- add_symbol(ST,newsymbol);
- }
- void add_symbol(Symbol* ST, Symbol* new_symbol){
- Symbol* cur_node = ST;
- while(cur_node->next !=NULL){
- cur_node = cur_node->next;
- }
- cur_node->next = new_symbol;
- }
- void printST(){
- Symbol *child_symbols;
- Symbol *cur_symbol = ST;
- while (cur_symbol !=NULL){
- print_element(cur_symbol);
- cur_symbol = cur_symbol->next;
- }
- cur_symbol = ST->next;
- while(cur_symbol !=NULL){
- if(cur_symbol->func_definition !=NULL){
- child_symbols = cur_symbol->func_definition;
- while(child_symbols!=NULL){
- print_element(child_symbols);
- child_symbols = child_symbols->next;
- }
- }
- cur_symbol = cur_symbol->next;
- }
- }
- void print_element(Symbol* symbol){
- int i;
- if(symbol->s_type==Global){
- printf("===== Global Symbol Table =====\n");
- }
- else if(symbol->s_type==FuncDecl){
- printf("%s\t%s(",symbol->id,symbol->type);
- if(symbol->num_params>0){
- printf("%s",symbol->params[0]->type);
- for(i=1;i<symbol->num_params;i++){
- printf(",%s",symbol->params[i]->type);
- }
- }
- printf(")\n");
- }
- else if(symbol->s_type==Variable){
- printf("%s\t%s",symbol->id,symbol->type);
- if(symbol->is_param)
- printf("\tparam");
- printf("\n");
- }
- else if(symbol->s_type==Return){
- printf("return\t%s\n",symbol->type);
- }
- else if(symbol->s_type==FuncTable){
- printf("\n===== Function %s Symbol Table =====\n",symbol->id);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement