fix parser and semantic v2.2
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -144,23 +155,33 @@ static void insertNode(TreeNode *t) {
|
||||
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;
|
||||
|
||||
21
src/cminus.y
21
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user