fix parser and semantic v2.2
This commit is contained in:
@@ -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,14 +155,23 @@ 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 (func_scope != NULL) {
|
||||||
if (t->type == Void) {
|
if (t->type == Void) {
|
||||||
if (t->attr.name != NULL) {
|
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);
|
fprintf(listing, "Error: The void-type variable is declared at line %d (name : \"%s\")\n", t->lineno, t->attr.name);
|
||||||
@@ -161,6 +181,7 @@ static void insertNode(TreeNode *t) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
|||||||
19
src/cminus.y
19
src/cminus.y
@@ -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;
|
||||||
|
if ($1->type == Integer)
|
||||||
$$->type = IntegerArray;
|
$$->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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user