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 "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;

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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