From f524a9e1651b2f23690801c19e432df7cdaff5f7 Mon Sep 17 00:00:00 2001 From: yenru0 Date: Fri, 5 Dec 2025 02:09:12 +0900 Subject: [PATCH] fix parser and semantic v2.2 --- src/analyze.c | 65 ++++++++++++++++++++++++++++++++++++--------------- src/cminus.y | 21 +++++++++++++---- src/main.c | 4 ++-- src/symtab.c | 9 ++++--- src/symtab.h | 2 +- 5 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/analyze.c b/src/analyze.c index 8d65cb2..ec22a10 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -9,11 +9,21 @@ #include "globals.h" #include "symtab.h" + static BucketList func_entry = NULL; static Scope func_scope; static TreeNode *func_params[MAX_PARAM_COUNT]; static int func_param_count = 0; +void gen_random_hex_16(char *buffer) { + char *hex_chars = "0123456789abcdef"; + + for (int i = 0; i < 16; i++) { + buffer[i] = hex_chars[rand() % 16]; + } + buffer[16] = '\0'; +} + /* Procedure traverse is a generic recursive * syntax tree traversal routine: * it applies preProc in preorder and postProc @@ -49,7 +59,6 @@ static void nullProc(TreeNode *t) { * the symbol table */ static void insertNode(TreeNode *t) { - //printf("Insert Node: line %d\n", t->lineno); switch (t->nodekind) { case ExpK: switch (t->kind.exp) { @@ -91,6 +100,7 @@ static void insertNode(TreeNode *t) { switch (t->kind.stmt) { case CompK: if (func_scope != NULL) { + push_scope(func_scope); func_scope = NULL; for (int i = 0; i < func_param_count; i++) { @@ -100,7 +110,7 @@ static void insertNode(TreeNode *t) { func_entry->param_count++; BucketList param_entry = st_lookup_current(param->attr.name); if (param_entry != NULL) { - fprintf(listing, "Error: Symbol \"%s\" is redefined at line %d (already defined at line", t->attr.name, t->lineno); + fprintf(listing, "Error: Symbol \"%s\" is redefined at line %d (already defined at line", func_entry->param_names[i], param->lineno); LineList lines = param_entry->lines; while (lines != NULL) { fprintf(listing, " "); @@ -109,6 +119,7 @@ static void insertNode(TreeNode *t) { } fprintf(listing, ")\n"); Error = TRUE; + st_entry_insert_line(param_entry, param->lineno); } else { st_try_insert(param->attr.name, SymbolParam, param->type, param->lineno); } @@ -142,25 +153,35 @@ static void insertNode(TreeNode *t) { } st_entry_insert_line(entry, t->lineno); fprintf(listing, ")\n"); - + Error = TRUE; + char* random_name = (char *) calloc(1, 20); + gen_random_hex_16(random_name); + + func_entry = st_try_insert(random_name, SymbolFunc, t->type, t->lineno); + t->scope = curr_scope(); + func_scope = scope_new(random_name); } else { func_entry = st_try_insert(t->attr.name, SymbolFunc, t->type, t->lineno); t->scope = curr_scope(); + func_scope = scope_new(t->attr.name); } - func_scope = scope_new(t->attr.name); + + } break; case ArrParamK: case NonArrParamK: { - if (t->type == Void) { - if (t->attr.name != NULL) { - fprintf(listing, "Error: The void-type variable is declared at line %d (name : \"%s\")\n", t->lineno, t->attr.name); - Error = TRUE; - } else { - goto insert_param_exit; + if (func_scope != NULL) { + if (t->type == Void) { + if (t->attr.name != NULL) { + fprintf(listing, "Error: The void-type variable is declared at line %d (name : \"%s\")\n", t->lineno, t->attr.name); + Error = TRUE; + } else { + goto insert_param_exit; + } } + func_params[func_param_count++] = t; } - func_params[func_param_count++] = t; insert_param_exit: } break; @@ -210,7 +231,7 @@ void buildSymtab(TreeNode *syntaxTree) { BucketList entry; entry = st_try_insert("input", SymbolFunc, Integer, 0); entry->param_count = 0; - entry->returnType = Integer; + // entry->returnType = Integer; /* not know */ entry = st_try_insert("output", SymbolFunc, Void, 0); entry->returnType = Void; @@ -247,8 +268,10 @@ static void checkNode(TreeNode *t) { if (left->type != Integer || right->type != Integer) { fprintf(listing, "Error: invalid operation at line %d\n", t->lineno); Error = TRUE; + t->type = Undetermined; + } else { + t->type = Integer; } - t->type = Integer; } break; case ConstK: t->type = Integer; @@ -260,11 +283,11 @@ static void checkNode(TreeNode *t) { case ArrIdK: { BucketList entry = st_lookup_from(t->attr.name, t->scope); if (entry->type != IntegerArray) { - fprintf(listing, "Error: Invalid array indexing at line %d (name : \"%s\"). indexing can only allowed for int[] variables\n", t->lineno, t->attr.name); + fprintf(listing, "Error: Invalid array indexing at line %d (name : \"%s\"). indexing can only be allowed for int[] variables\n", t->lineno, t->attr.name); Error = TRUE; } if (t->child[0]->type != Integer) { - fprintf(listing, "Error: Invalid array indexing at line %d (name : \"%s\"). indices should be integer\n", t->lineno, t->attr.name); + fprintf(listing, "Error: Invalid array indexing at line %d (name : \"%s\"). indicies should be integer\n", t->lineno, t->attr.name); Error = TRUE; } t->type = Integer; @@ -278,7 +301,7 @@ static void checkNode(TreeNode *t) { } else if (left->type == IntegerArray && right->type == IntegerArray) { } else { - fprintf(listing, "Error: invalid assignment at line %d. cannot assign to array variable\n", t->lineno); + fprintf(listing, "Error: invalid assignment at line %d\n", t->lineno); Error = TRUE; } @@ -296,7 +319,11 @@ static void checkNode(TreeNode *t) { TreeNode *arg = t->child[0]; int i = 0;// 파라미터 인덱스 - + if (entry->param_count == -1) { + fprintf(listing, "Error: Invalid function call at line %d (name : \"%s\")\n", t->lineno, t->attr.name); + Error = TRUE; + goto check_callk_after; + } while (arg != NULL && i < entry->param_count) { if (arg->type != entry->param_types[i]) { fprintf(listing, "Error: Invalid function call at line %d (name : \"%s\")\n", t->lineno, t->attr.name); @@ -351,14 +378,14 @@ static void checkNode(TreeNode *t) { case IterK: { TreeNode *condition = t->child[0]; if (condition->type != Integer) { - fprintf(listing, "Error: invalid condition at line %d\n", t->lineno); + fprintf(listing, "Error: invalid condition at line %d\n", t->child[0]->lineno); Error = TRUE; } } break; case IfK: { TreeNode *condition = t->child[0]; if (condition->type != Integer) { - fprintf(listing, "Error: invalid condition at line %d\n", t->lineno); + fprintf(listing, "Error: invalid condition at line %d\n", t->child[0]->lineno); Error = TRUE; } } break; diff --git a/src/cminus.y b/src/cminus.y index 6084fe1..47eba9d 100644 --- a/src/cminus.y +++ b/src/cminus.y @@ -73,7 +73,10 @@ var_declaration : type_specifier name_specifier SEMI { } | type_specifier name_specifier LBRACE number_specifier RBRACE SEMI { $$ = newDeclNode(ArrVarK); $$->lineno = savedLineNo; - $$->type = IntegerArray; + if ($1->type == Integer) + $$->type = IntegerArray; + else + $$->type = Void; $$->attr.name = savedName; free($1); $$->child[0] = newExpNode(ConstK); @@ -219,7 +222,7 @@ var : name_specifier { simple_expression : additive_expression relop additive_expression { $$ = $2; - $$->lineno = lineno; + $$->lineno = $2->lineno; $$->child[0] = $1; $$->child[1] = $3; $$->type = Integer; @@ -227,51 +230,61 @@ simple_expression : additive_expression relop additive_expression { relop : LE { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = LE; } | LT { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = LT; } | GT { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = GT; } | GE { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = GE; } | EQ { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = EQ; } | NE { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = NE; }; additive_expression : additive_expression addop term { $$ = $2; - $$->lineno = lineno; + $$->lineno = $2->lineno; $$->child[0] = $1; $$->child[1] = $3; } | term { $$ = $1; }; addop : PLUS { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = PLUS; } | MINUS { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = MINUS; }; term : term mulop factor { $$ = $2; - $$->lineno = lineno; + $$->lineno = $2->lineno; $$->child[0] = $1; $$->child[1] = $3; } | factor { $$ = $1; }; mulop : TIMES { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = TIMES; } | OVER { $$ = newExpNode(OpK); + $$->lineno = lineno; $$->attr.op = OVER; }; diff --git a/src/main.c b/src/main.c index 98a062a..301806c 100644 --- a/src/main.c +++ b/src/main.c @@ -39,8 +39,8 @@ FILE *code; /* allocate and set tracing flags */ int EchoSource = FALSE; int TraceScan = FALSE; -int TraceParse = TRUE; -int TraceAnalyze = TRUE; +int TraceParse = FALSE; +int TraceAnalyze = FALSE; int TraceCode = FALSE; int Error = FALSE; diff --git a/src/symtab.c b/src/symtab.c index 9393ea1..a5f60f1 100644 --- a/src/symtab.c +++ b/src/symtab.c @@ -45,7 +45,11 @@ Scope scope_new(char *scope_name) {// it new_scope->child = NULL; new_scope->child_last = NULL; new_scope->next_sibling = NULL; - + int i; + for (i = 0; i < SYMTAB_SIZE; ++i) { + new_scope->hashTable[i] = NULL; + } + new_scope->child_count = 0; new_scope->location = 0; return new_scope; } @@ -340,8 +344,7 @@ static void printFunctionTableRecursive(FILE *listing, Scope scope) { entry = entry->next; fprintf(listing, "\n"); continue; - } - else if (entry->param_count == 0) { + } else if (entry->param_count == 0) { fprintf(listing, " "); fprintf(listing, "%-14s", "void"); entry = entry->next; diff --git a/src/symtab.h b/src/symtab.h index cb313a9..901d3c9 100644 --- a/src/symtab.h +++ b/src/symtab.h @@ -16,7 +16,7 @@ #define MAX_SCOPE_DEPTH 1557 -#define MAX_PARAM_COUNT 13 +#define MAX_PARAM_COUNT 32 /* the list of line numbers of the source * code in which a variable is referenced