From cc1b72c1093dfd3bb0f41802a6a012402fa9717e Mon Sep 17 00:00:00 2001 From: Adam NAILI Date: Wed, 6 Jun 2018 14:30:43 +0200 Subject: Replacement fprintf(stderr...) by yyerror + updating doc --- doc/rapport.md | 7 +++++ src/generator.c | 81 +++++++++++++++++++++++++++++++----------------------- src/symbol_table.c | 42 +++++++++++++--------------- 3 files changed, 72 insertions(+), 58 deletions(-) diff --git a/doc/rapport.md b/doc/rapport.md index d1c0226..28f8446 100644 --- a/doc/rapport.md +++ b/doc/rapport.md @@ -96,6 +96,13 @@ Dans les langages tel que le C, l'associativité se fait à gauche. On déclare donc `%left ,` pour l'indiquer à Bison. +# Analyse sémantique + +Le compilateur gère l'analyse sémantique. +Par exemple l'opération `tab[1] * 3` est légale mais `'a' * 'b'` ne l'est pas. La grammaire l'accepte, mais l'analyse sémantique à parti des attributs interdits. + + + # Génération de code cible ## Gestion de la mémoire diff --git a/src/generator.c b/src/generator.c index bb95e08..601f482 100644 --- a/src/generator.c +++ b/src/generator.c @@ -4,7 +4,7 @@ */ #include "generator.h" - +void yyerror(char *); // ----- GLOBAL FUNCTIONS ----- void gen_prologue() { @@ -21,7 +21,6 @@ void gen_prologue_continue(int *bss_done) { fprintf(output, "format_int_in: db \"%%d\", 0\n"); fprintf(output, "format_char_in: db \"%%c\", 0\n\n"); fprintf(output, "section .bss\n"); - fprintf(output, "globals: resq %d\n", nb_globals); fprintf(output, "section .text\n\nglobal _start\n"); fprintf(output, "\nprinte: ;print needs an argument in rax\n"); @@ -121,8 +120,8 @@ void gen_function_end_declaration(const char name[], int return_type, void gen_function_return(Type expect, Type actual) { if (actual != expect) { - fprintf(stderr, "Return type mismatch at line %d.\n", lineno); - exit(1); + yyerror("Return type mismatch"); + return; } if (actual != VOID_T) fprintf(output, "pop rax\n"); @@ -180,12 +179,12 @@ void gen_check(const char name[], Scope scope) { // ----- READ AND PRINT FUNCTIONS ----- void gen_reade(const char name[], Scope scope) { if (is_read_only(name, scope)) { - fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); - exit(1); + yyerror("Symbol is read only"); + return; } if (loc_lookup(name) != INT) { - fprintf(stderr, "Need to be a INT in the reade() function\n"); + yyerror("Need to be a INT in the reade() function"); return; } int l_addr = loc_get_addr(name); @@ -200,12 +199,12 @@ void gen_reade(const char name[], Scope scope) { void gen_readc(const char name[], Scope scope) { if (is_read_only(name, scope)) { - fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", name, lineno); - exit(1); + yyerror("Symbol is read only"); + return; } if (loc_lookup(name) != CHAR) { - fprintf(stderr, "Need to be a CHAR in the readc() function\n"); + yyerror("Need to be a CHAR in the readc() function"); return; } int l_addr = loc_get_addr(name); @@ -232,7 +231,7 @@ void gen_print(int type) { fprintf(output, "call printe\n"); break; default: - fprintf(stderr, "Error print, supposed to have type CHAR or INT or TAB\n"); + yyerror("Error print, supposed to have type CHAR or INT or TAB"); } } @@ -267,8 +266,8 @@ int gen_assign(const char ident[], Scope scope) { int g_addr = glo_get_addr(ident); if (is_read_only(ident, scope)) { - fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno); - exit(1); + yyerror("Symbol is read only"); + return loc_lookup(ident); } switch (scope) { @@ -293,20 +292,26 @@ int gen_assign_tab(const char ident[], Scope scope) { int g_addr = glo_get_addr(ident); if (is_read_only(ident, scope)) { - fprintf(stderr, "Symbol \"%s\" at line %d is read only.\n", ident, lineno); - exit(1); + yyerror("Symbol is read only"); + return loc_lookup(ident); } switch (scope) { case GLOBAL: - fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n", g_addr, ident); + fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov " + "rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n", + g_addr, ident); return glo_lookup(ident); case LOCAL: if (l_addr != -1) { - fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov rax,rbp\nsub rax,rcx\npop QWORD [rax - %d] ;%s\n", l_addr, ident); + fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov " + "rax,rbp\nsub rax,rcx\npop QWORD [rax - %d] ;%s\n", + l_addr, ident); return loc_lookup(ident); } else { - fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n", g_addr, ident); + fprintf(output, "pop r8 ;EXP\npop rcx ;offset\npush r8\nimul rcx,8\nmov " + "rax,globals\n add rax,rcx\npop QWORD [rax + %d] ;%s\n", + g_addr, ident); return glo_lookup(ident); } default: @@ -315,8 +320,8 @@ int gen_assign_tab(const char ident[], Scope scope) { } void gen_or(int left, int right, int idx) { - check_expected_types(left, INT,TAB); - check_expected_types(right, INT,TAB); + check_expected_types(left, INT, TAB); + check_expected_types(right, INT, TAB); fprintf(output, ";a OR c\n"); fprintf(output, "pop rax\n"); @@ -333,8 +338,8 @@ void gen_or(int left, int right, int idx) { } void gen_and(int left, int right, int idx) { - check_expected_types(left, INT,TAB); - check_expected_types(right, INT,TAB); + check_expected_types(left, INT, TAB); + check_expected_types(right, INT, TAB); fprintf(output, ";a AND c\n"); fprintf(output, "pop rax\n"); @@ -351,8 +356,8 @@ void gen_and(int left, int right, int idx) { } void gen_eq(const char op[], int left, int right, int idx) { - check_expected_types(left, INT,TAB); - check_expected_types(right, INT,TAB); + check_expected_types(left, INT, TAB); + check_expected_types(right, INT, TAB); fprintf(output, ";a EQ c\npop rax\npop rcx\ncmp rax,rcx\n"); @@ -368,8 +373,8 @@ void gen_eq(const char op[], int left, int right, int idx) { } void gen_order(const char op[], int left, int right, int idx) { - check_expected_types(left, INT,TAB); - check_expected_types(right, INT,TAB); + check_expected_types(left, INT, TAB); + check_expected_types(right, INT, TAB); fprintf(output, ";a ORDER c\npop rcx\npop rax\ncmp rax,rcx\n"); @@ -389,8 +394,8 @@ void gen_order(const char op[], int left, int right, int idx) { } void gen_addsub(char op, int left, int right) { - check_expected_types(left, INT,TAB); - check_expected_types(right, INT,TAB); + check_expected_types(left, INT, TAB); + check_expected_types(right, INT, TAB); switch (op) { case '+': @@ -405,8 +410,8 @@ void gen_addsub(char op, int left, int right) { } void gen_divstar(char op, int left, int right) { - check_expected_types(left, INT,TAB); - check_expected_types(right, INT,TAB); + check_expected_types(left, INT, TAB); + check_expected_types(right, INT, TAB); switch (op) { case '*': @@ -423,7 +428,7 @@ void gen_divstar(char op, int left, int right) { } int gen_signed_expr(char op, int type) { - check_expected_types(type, INT,TAB); + check_expected_types(type, INT, TAB); switch (op) { case '+': fprintf(output, ";+F\n"); @@ -439,7 +444,7 @@ int gen_signed_expr(char op, int type) { } int gen_negate_expr(int type) { - check_expected_types(type, INT,TAB); + check_expected_types(type, INT, TAB); fprintf(output, ";!F\npop rax\nxor rax,1\npush rax\n"); return type; } @@ -472,14 +477,20 @@ int gen_value_tab(const char ident[], Scope scope) { int g_addr = glo_get_addr(ident); switch (scope) { case GLOBAL: - fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,globals\n add rax,rcx\npush QWORD [rax + %d] ;%s\n", g_addr, ident); + fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,globals\n add " + "rax,rcx\npush QWORD [rax + %d] ;%s\n", + g_addr, ident); return glo_lookup(ident); case LOCAL: if (l_addr != -1) { - fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,rbp\nsub rax,rcx\npush QWORD [rax - %d] ;%s\n", l_addr, ident); + fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,rbp\nsub " + "rax,rcx\npush QWORD [rax - %d] ;%s\n", + l_addr, ident); return loc_lookup(ident); } else { - fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,globals\n add rax,rcx\npush QWORD [rax + %d] ;%s\n", g_addr, ident); + fprintf(output, "pop rcx ;offset\nimul rcx,8\nmov rax,globals\n add " + "rax,rcx\npush QWORD [rax + %d] ;%s\n", + g_addr, ident); return glo_lookup(ident); } default: diff --git a/src/symbol_table.c b/src/symbol_table.c index cff675a..b522929 100644 --- a/src/symbol_table.c +++ b/src/symbol_table.c @@ -7,6 +7,7 @@ #include "generator.h" extern int lineno; /* from lexical analyser */ +void yyerror(char *); SymbolTable glo_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; SymbolTable loc_symbol_table = {{{{0}, 0}}, MAXSYMBOLS, 0}; @@ -57,12 +58,14 @@ int fun_lookup(const char name[], int nb_param) { int count; for (count = 0; count < fun_table.size; count++) { - if (!strcmp(fun_table.entries[count].name, name) && (fun_table.entries[count].nb_parameters == nb_param)) { + if (!strcmp(fun_table.entries[count].name, name) && + (fun_table.entries[count].nb_parameters == nb_param)) { return fun_table.entries[count].return_type; } } - fprintf(stderr, "No definition of the function %s (or wrong number of parameters) near line %d\n", name, - lineno); + fprintf(stderr, "No definition of the function %s (or wrong number of " + "parameters) near line %d\n", + name, lineno); return -1; } @@ -82,17 +85,14 @@ static void glo_add(const char name[], int type, bool read_only) { } strcpy(glo_symbol_table.entries[glo_symbol_table.size - 1].name, name); glo_symbol_table.entries[glo_symbol_table.size - 1].type = type; - glo_symbol_table.entries[glo_symbol_table.size - 1].addr = (glo_symbol_table.size - 1) * 8; + glo_symbol_table.entries[glo_symbol_table.size - 1].addr = + (glo_symbol_table.size - 1) * 8; glo_symbol_table.entries[glo_symbol_table.size - 1].read_only = read_only; } -void glo_addVar(const char name[], int type) { - glo_add(name, type, false); -} +void glo_addVar(const char name[], int type) { glo_add(name, type, false); } -void glo_addConst(const char name[]) { - glo_add(name, INT, true); -} +void glo_addConst(const char name[]) { glo_add(name, INT, true); } // Verifies that the variable exists and returns the type int glo_lookup(const char name[]) { @@ -149,17 +149,14 @@ static void loc_add(const char name[], int type, bool read_only) { } strcpy(loc_symbol_table.entries[loc_symbol_table.size - 1].name, name); loc_symbol_table.entries[loc_symbol_table.size - 1].type = type; - loc_symbol_table.entries[loc_symbol_table.size - 1].addr = (loc_symbol_table.size - 1) * 8 + 8; + loc_symbol_table.entries[loc_symbol_table.size - 1].addr = + (loc_symbol_table.size - 1) * 8 + 8; loc_symbol_table.entries[loc_symbol_table.size - 1].read_only = read_only; } -void loc_addVar(const char name[], int type) { - loc_add(name, type, false); -} +void loc_addVar(const char name[], int type) { loc_add(name, type, false); } -void loc_addConst(const char name[]) { - loc_add(name, INT, true); -} +void loc_addConst(const char name[]) { loc_add(name, INT, true); } int loc_lookup(const char name[]) { int count; @@ -205,9 +202,7 @@ void loc_display_table() { fprintf(output, "\n"); } -void loc_clean_table() { - loc_symbol_table.size = 0; -} +void loc_clean_table() { loc_symbol_table.size = 0; } static char *string_of_type(int type) { switch (type) { @@ -230,11 +225,12 @@ void check_expected_type(Type type_to_check, Type type_expected) { string_of_type(type_expected), string_of_type(type_to_check), lineno); } -void check_expected_types(Type type_to_check, Type type_expected1, Type type_expected2) { +void check_expected_types(Type type_to_check, Type type_expected1, + Type type_expected2) { if (type_to_check != type_expected1 && type_to_check != type_expected2) fprintf(stderr, "Expected type : %s OR %s-> Got type : %s (near line %d)\n", - string_of_type(type_expected1), string_of_type(type_expected2), string_of_type(type_to_check), - lineno); + string_of_type(type_expected1), string_of_type(type_expected2), + string_of_type(type_to_check), lineno); } /* returns false if symbol can't be found too */ -- cgit v1.2.3