fix parser and semantic v2.2

This commit is contained in:
2025-12-05 02:09:12 +09:00
parent d46fd36bcb
commit f524a9e165
5 changed files with 72 additions and 29 deletions

View File

@@ -9,11 +9,21 @@
#include "globals.h" #include "globals.h"
#include "symtab.h" #include "symtab.h"
static BucketList func_entry = NULL; static BucketList func_entry = NULL;
static Scope func_scope; static Scope func_scope;
static TreeNode *func_params[MAX_PARAM_COUNT]; static TreeNode *func_params[MAX_PARAM_COUNT];
static int func_param_count = 0; 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 /* Procedure traverse is a generic recursive
* syntax tree traversal routine: * syntax tree traversal routine:
* it applies preProc in preorder and postProc * it applies preProc in preorder and postProc
@@ -49,7 +59,6 @@ static void nullProc(TreeNode *t) {
* the symbol table * the symbol table
*/ */
static void insertNode(TreeNode *t) { static void insertNode(TreeNode *t) {
//printf("Insert Node: line %d\n", t->lineno);
switch (t->nodekind) { switch (t->nodekind) {
case ExpK: case ExpK:
switch (t->kind.exp) { switch (t->kind.exp) {
@@ -91,6 +100,7 @@ static void insertNode(TreeNode *t) {
switch (t->kind.stmt) { switch (t->kind.stmt) {
case CompK: case CompK:
if (func_scope != NULL) { if (func_scope != NULL) {
push_scope(func_scope); push_scope(func_scope);
func_scope = NULL; func_scope = NULL;
for (int i = 0; i < func_param_count; i++) { for (int i = 0; i < func_param_count; i++) {
@@ -100,7 +110,7 @@ static void insertNode(TreeNode *t) {
func_entry->param_count++; func_entry->param_count++;
BucketList param_entry = st_lookup_current(param->attr.name); BucketList param_entry = st_lookup_current(param->attr.name);
if (param_entry != NULL) { 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; LineList lines = param_entry->lines;
while (lines != NULL) { while (lines != NULL) {
fprintf(listing, " "); fprintf(listing, " ");
@@ -109,6 +119,7 @@ static void insertNode(TreeNode *t) {
} }
fprintf(listing, ")\n"); fprintf(listing, ")\n");
Error = TRUE; Error = TRUE;
st_entry_insert_line(param_entry, param->lineno);
} else { } else {
st_try_insert(param->attr.name, SymbolParam, param->type, param->lineno); st_try_insert(param->attr.name, SymbolParam, param->type, param->lineno);
} }
@@ -144,23 +155,33 @@ static void insertNode(TreeNode *t) {
fprintf(listing, ")\n"); fprintf(listing, ")\n");
Error = TRUE; 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 { } else {
func_entry = st_try_insert(t->attr.name, SymbolFunc, t->type, t->lineno); func_entry = st_try_insert(t->attr.name, SymbolFunc, t->type, t->lineno);
t->scope = curr_scope(); t->scope = curr_scope();
func_scope = scope_new(t->attr.name);
} }
func_scope = scope_new(t->attr.name);
} break; } break;
case ArrParamK: case ArrParamK:
case NonArrParamK: { case NonArrParamK: {
if (t->type == Void) { if (func_scope != NULL) {
if (t->attr.name != NULL) { if (t->type == Void) {
fprintf(listing, "Error: The void-type variable is declared at line %d (name : \"%s\")\n", t->lineno, t->attr.name); if (t->attr.name != NULL) {
Error = TRUE; fprintf(listing, "Error: The void-type variable is declared at line %d (name : \"%s\")\n", t->lineno, t->attr.name);
} else { Error = TRUE;
goto insert_param_exit; } else {
goto insert_param_exit;
}
} }
func_params[func_param_count++] = t;
} }
func_params[func_param_count++] = t;
insert_param_exit: insert_param_exit:
} break; } break;
@@ -210,7 +231,7 @@ void buildSymtab(TreeNode *syntaxTree) {
BucketList entry; BucketList entry;
entry = st_try_insert("input", SymbolFunc, Integer, 0); entry = st_try_insert("input", SymbolFunc, Integer, 0);
entry->param_count = 0; entry->param_count = 0;
entry->returnType = Integer; // entry->returnType = Integer; /* not know */
entry = st_try_insert("output", SymbolFunc, Void, 0); entry = st_try_insert("output", SymbolFunc, Void, 0);
entry->returnType = Void; entry->returnType = Void;
@@ -247,8 +268,10 @@ static void checkNode(TreeNode *t) {
if (left->type != Integer || right->type != Integer) { if (left->type != Integer || right->type != Integer) {
fprintf(listing, "Error: invalid operation at line %d\n", t->lineno); fprintf(listing, "Error: invalid operation at line %d\n", t->lineno);
Error = TRUE; Error = TRUE;
t->type = Undetermined;
} else {
t->type = Integer;
} }
t->type = Integer;
} break; } break;
case ConstK: case ConstK:
t->type = Integer; t->type = Integer;
@@ -260,11 +283,11 @@ static void checkNode(TreeNode *t) {
case ArrIdK: { case ArrIdK: {
BucketList entry = st_lookup_from(t->attr.name, t->scope); BucketList entry = st_lookup_from(t->attr.name, t->scope);
if (entry->type != IntegerArray) { 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; Error = TRUE;
} }
if (t->child[0]->type != Integer) { 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; Error = TRUE;
} }
t->type = Integer; t->type = Integer;
@@ -278,7 +301,7 @@ static void checkNode(TreeNode *t) {
} else if (left->type == IntegerArray && right->type == IntegerArray) { } else if (left->type == IntegerArray && right->type == IntegerArray) {
} else { } 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; Error = TRUE;
} }
@@ -296,7 +319,11 @@ static void checkNode(TreeNode *t) {
TreeNode *arg = t->child[0]; TreeNode *arg = t->child[0];
int i = 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) { while (arg != NULL && i < entry->param_count) {
if (arg->type != entry->param_types[i]) { if (arg->type != entry->param_types[i]) {
fprintf(listing, "Error: Invalid function call at line %d (name : \"%s\")\n", t->lineno, t->attr.name); 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: { case IterK: {
TreeNode *condition = t->child[0]; TreeNode *condition = t->child[0];
if (condition->type != Integer) { 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; Error = TRUE;
} }
} break; } break;
case IfK: { case IfK: {
TreeNode *condition = t->child[0]; TreeNode *condition = t->child[0];
if (condition->type != Integer) { 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; Error = TRUE;
} }
} break; } break;

View File

@@ -73,7 +73,10 @@ var_declaration : type_specifier name_specifier SEMI {
} | type_specifier name_specifier LBRACE number_specifier RBRACE SEMI { } | type_specifier name_specifier LBRACE number_specifier RBRACE SEMI {
$$ = newDeclNode(ArrVarK); $$ = newDeclNode(ArrVarK);
$$->lineno = savedLineNo; $$->lineno = savedLineNo;
$$->type = IntegerArray; if ($1->type == Integer)
$$->type = IntegerArray;
else
$$->type = Void;
$$->attr.name = savedName; $$->attr.name = savedName;
free($1); free($1);
$$->child[0] = newExpNode(ConstK); $$->child[0] = newExpNode(ConstK);
@@ -219,7 +222,7 @@ var : name_specifier {
simple_expression : additive_expression relop additive_expression { simple_expression : additive_expression relop additive_expression {
$$ = $2; $$ = $2;
$$->lineno = lineno; $$->lineno = $2->lineno;
$$->child[0] = $1; $$->child[0] = $1;
$$->child[1] = $3; $$->child[1] = $3;
$$->type = Integer; $$->type = Integer;
@@ -227,51 +230,61 @@ simple_expression : additive_expression relop additive_expression {
relop : LE { relop : LE {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = LE; $$->attr.op = LE;
} | LT { } | LT {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = LT; $$->attr.op = LT;
} | GT { } | GT {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = GT; $$->attr.op = GT;
} | GE { } | GE {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = GE; $$->attr.op = GE;
} | EQ { } | EQ {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = EQ; $$->attr.op = EQ;
} | NE { } | NE {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = NE; $$->attr.op = NE;
}; };
additive_expression : additive_expression addop term { additive_expression : additive_expression addop term {
$$ = $2; $$ = $2;
$$->lineno = lineno; $$->lineno = $2->lineno;
$$->child[0] = $1; $$->child[0] = $1;
$$->child[1] = $3; $$->child[1] = $3;
} | term { $$ = $1; }; } | term { $$ = $1; };
addop : PLUS { addop : PLUS {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = PLUS; $$->attr.op = PLUS;
} | MINUS { } | MINUS {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = MINUS; $$->attr.op = MINUS;
}; };
term : term mulop factor { term : term mulop factor {
$$ = $2; $$ = $2;
$$->lineno = lineno; $$->lineno = $2->lineno;
$$->child[0] = $1; $$->child[0] = $1;
$$->child[1] = $3; $$->child[1] = $3;
} | factor { $$ = $1; }; } | factor { $$ = $1; };
mulop : TIMES { mulop : TIMES {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = TIMES; $$->attr.op = TIMES;
} | OVER { } | OVER {
$$ = newExpNode(OpK); $$ = newExpNode(OpK);
$$->lineno = lineno;
$$->attr.op = OVER; $$->attr.op = OVER;
}; };

View File

@@ -39,8 +39,8 @@ FILE *code;
/* allocate and set tracing flags */ /* allocate and set tracing flags */
int EchoSource = FALSE; int EchoSource = FALSE;
int TraceScan = FALSE; int TraceScan = FALSE;
int TraceParse = TRUE; int TraceParse = FALSE;
int TraceAnalyze = TRUE; int TraceAnalyze = FALSE;
int TraceCode = FALSE; int TraceCode = FALSE;
int Error = FALSE; int Error = FALSE;

View File

@@ -45,7 +45,11 @@ Scope scope_new(char *scope_name) {// it
new_scope->child = NULL; new_scope->child = NULL;
new_scope->child_last = NULL; new_scope->child_last = NULL;
new_scope->next_sibling = 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; new_scope->location = 0;
return new_scope; return new_scope;
} }
@@ -340,8 +344,7 @@ static void printFunctionTableRecursive(FILE *listing, Scope scope) {
entry = entry->next; entry = entry->next;
fprintf(listing, "\n"); fprintf(listing, "\n");
continue; continue;
} } else if (entry->param_count == 0) {
else if (entry->param_count == 0) {
fprintf(listing, " "); fprintf(listing, " ");
fprintf(listing, "%-14s", "void"); fprintf(listing, "%-14s", "void");
entry = entry->next; entry = entry->next;

View File

@@ -16,7 +16,7 @@
#define MAX_SCOPE_DEPTH 1557 #define MAX_SCOPE_DEPTH 1557
#define MAX_PARAM_COUNT 13 #define MAX_PARAM_COUNT 32
/* the list of line numbers of the source /* the list of line numbers of the source
* code in which a variable is referenced * code in which a variable is referenced