1 Star 4 Fork 0

red1y/SimpleC-Compiler

Create your Gitee Account
Explore and code with more than 14 million developers,Free private repositories !:)
Sign up
文件
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
semantic_utils.c 14.14 KB
Copy Edit Raw Blame History
red1y authored 2022-04-24 00:06 +08:00 . compiler 1.0
#ifndef SEMANTIC
#include "semantic_utils.h"
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int scnt = 0, ucnt = 0;
char* symbols[MAX_SYMBOL_COUNT];
char* unqsybs[MAX_SYMBOL_COUNT];
Symbol* symbolTable[MAX_SYMBOL_COUNT];
int filled[MAX_SYMBOL_COUNT];
void serror(int type, int lineno, char *msg, char* sym) {
if (strlen(sym) != 0) {
printf("Error type %d at line %d: %s \"%s\"\n", type, lineno, msg, sym);
} else {
printf("Error type %d at line %d: %s\n", type, lineno, msg);
}
}
void prepareForSemanticAnalysis(Node* node) {
/* insert into symbol table for declarations */
switch (node->elem) {
case 6: // OptTag
insertSymbol(node->ch[0]->strval);
break;
case 8: // VarDec
if (node->ch[0]->elem == 27) { // ID
insertSymbol(node->ch[0]->strval);
}
break;
case 9: // FunDec
insertSymbol(node->ch[0]->strval);
break;
default:
break;
}
// allocate memory for attribute node
SNode* snode = malloc(sizeof(SNode));
node->snode = snode;
snode->node = node;
int i;
for (i = 0; i < node->cnt; i++) {
if (node->ch[i] != NULL) {
prepareForSemanticAnalysis(node->ch[i]);
}
}
}
void insertSymbol(char* name) {
symbols[scnt] = malloc(sizeof(char) * strlen(name));
strcpy(symbols[scnt++], name);
}
void createSymbolTable() {
sortSymbols();
getUnqSymbol();
}
int cmp(const void *s1, const void *s2) {
return strcmp(*(char **)s1, *(char **)s2);
}
void sortSymbols() {
qsort(symbols, scnt, sizeof(char *), cmp);
}
void getUnqSymbol() {
int i;
unqsybs[ucnt++] = symbols[0];
for (i = 1; i < scnt; i++) {
if (strcmp(symbols[i], symbols[i - 1])) {
unqsybs[ucnt++] = symbols[i];
}
}
}
int getSymbolIndex(char* name) {
int l = 0, r = ucnt, mid;
int cmpres;
while (l < r) {
mid = (l + r) >> 1;
// printf("mid %d %s, %s\n", mid, unqsybs[mid], name);
cmpres = strcmp(name, unqsybs[mid]);
if (!cmpres) {
break;
} else {
if (cmpres < 0) r = mid;
else l = mid + 1;
}
}
return l >= r ? -1 : mid;
}
void fillError(int status, SNode* snode) {
switch (status) {
case SYMBOL_FILL_DONE : break;
case SYMBOL_ALREADY_DECLARED : serror(3, snode->node->lineno, "Redefined variable", snode->name); break;
case FUNCTION_ALREADY_DEFINED : serror(4, snode->node->lineno, "Redefined function", snode->name); break;
case FIELD_ALREADY_DECLARED : snode->fieldErr = 1; serror(15, snode->node->lineno, "Redefined field", snode->name); break;
case DUPLICATED_STRUCT_NAME : serror(16, snode->node->lineno, "Duplicated name", snode->name); break;
case STRUCTTURE_NAME : serror(96, snode->node->lineno, "Name used as structure", snode->name); break;
default : break;
}
}
void fillSymbols(SNode* specifier, SNode* extdeclist) {
int fillres;
while(extdeclist != NULL) {
typeAssign(specifier, extdeclist);
fillError(fillSymbol(extdeclist->name, extdeclist->type, 0), extdeclist);
extdeclist = extdeclist->nexDec;
}
}
int fillSymbol(char* name, Type* type, int address) {
// printf("fill symbol: %s\n", name);
int index = getSymbolIndex(name);
if (filled[index]) {
if (!address) {
if (symbolTable[index]->type->kind == STRUCTTURE) return STRUCTTURE_NAME;
else return SYMBOL_ALREADY_DECLARED;
}
else if (address == 1)return FIELD_ALREADY_DECLARED;
else if (address == 2) return DUPLICATED_STRUCT_NAME;
}
symbolTable[index] = malloc(sizeof(Symbol));
symbolTable[index]->name = name;
symbolTable[index]->type = type;
filled[index] = 1;
return SYMBOL_FILL_DONE;
}
// TODO same with FillSymbols
void fillStructSymbols(SNode* specifier, SNode* extdeclist) {
// printf("fill struct symbols\n");
int fillres;
while(extdeclist != NULL) {
typeAssign(specifier, extdeclist);
fillError(fillSymbol(extdeclist->name, extdeclist->type, 1), extdeclist);
extdeclist = extdeclist->nexDec;
}
}
void fillStruct(SNode* snode) {
fillError(fillSymbol(snode->name, snode->type, 2), snode);
}
// TODO function paramlist
void fillFunctions(SNode* specifier, SNode* func) {
fillError(fillFunction(specifier, func), func);
// SNode* param = func->nexPar;
}
// TODO move typeAssign into main process;
// funciton paramlist
// return struct ???
int fillFunction(SNode* specifier, SNode* func) {
typeAssign(specifier, func);
int index = getSymbolIndex(func->name);
if (filled[index]) return FUNCTION_ALREADY_DEFINED;
symbolTable[index] = malloc(sizeof(Symbol));
symbolTable[index]->name = func->name;
symbolTable[index]->type = func->type;
symbolTable[index]->args = func->nexPar;
if (func->type->kind == BASIC) func->type->kind = FUNC_BASIC;
else printf("error return type\n");
filled[index] = 1;
return SYMBOL_FILL_DONE;
}
void typeAssign(SNode* specifier, SNode* var) {
if(var->type == NULL) { // common
var->type = specifier->type;
} else { // array
Type* arrayType = var->type;
while(arrayType->info.array.type != NULL) {
arrayType = arrayType->info.array.type;
}
arrayType->info.array.type = specifier->type;
}
}
void synAssign(SNode* pa, SNode* ch, int type) {
switch (type) {
case NAMEVAL:
pa->name = ch->name;
break;
case DATATYPE :
pa->type = ch->type;
break;
case ARRAYTYPE :
pa->type->info.array.type = ch->type;
break;
case ARGUMTYPE :
pa->nexPar = ch;
break;
default:
break;
}
}
void lexAssign(SNode* snode, Node* node, int type) {
switch (type) {
case NAMEVAL :
snode->name = malloc(sizeof(char) * strlen(node->strval));
strcpy(snode->name, node->strval);
break;
case BASICTYPE :
snode->type = malloc(sizeof(Type));
snode->type->kind = BASIC;
if (node->strval[0] == 'i') {
snode->type->info.basic = BASIC_INT;
} else {
snode->type->info.basic = BASIC_FLOAT;
}
break;
case ARRAYTYPE :
snode->type = malloc(sizeof(Type));
snode->type->kind = ARRAY;
snode->type->info.array.size = node->intval;
break;
case CONSTANTINT :
snode->type = malloc(sizeof(Type));
snode->type->kind = BASIC;
snode->type->constant.intval = node->intval;
snode->type->info.basic = BASIC_INT;
break;
case CONSTANTFLOAT :
snode->type = malloc(sizeof(Type));
snode->type->kind = BASIC;
snode->type->constant.floatval = node->floatval;
snode->type->info.basic = BASIC_FLOAT;
break;
default :
break;
}
}
void udfAssign(SNode* snode) {
snode->type = malloc(sizeof(Type));
snode->type->kind = UNDEFINED;
}
void tabAssign(SNode* snode, int index, int type) {
switch (type) {
case DATATYPE :
snode->type = symbolTable[index]->type;
break;
default :
break;
}
}
// MODIFIED
void stuAssign(SNode* snode, Node* node) {
snode->type = malloc(sizeof(Type));
snode->name = node->ch[1]->snode->name;
// snode->name = snode->ch[1]->name;
snode->type->kind = STRUCTTURE;
snode->type->info.struc.field = node->ch[3]->snode;
// snode->type->info.struc.field = snode->ch[3];
}
int isVarStructure(SNode* snode) {
return snode->type->kind == STRUCTTURE;
}
// TODO
int isFieldDefined(SNode* snode, SNode *field) {
int index = getSymbolIndex(snode->name);
if (index == -1 || !filled[index]) {
return 0;
}
SNode* field1 = symbolTable[index]->type->info.struc.field;
SNode* field2;
while (field1 != NULL) {
field2 = field1->nexDec;
while (field2 != NULL) {
// printf("field: %s", field2->name);
if (!strcmp(field2->name, field->name)) {
field->type = field2->type;
return 1;
}
field2 = field2->nexDec;
}
field1 = field1->nexField;
}
return 0;
}
int checkField(SNode* opt1, SNode* opt2) {
SNode* fieldx1 = opt1->type->info.struc.field;
SNode* fieldy1 = opt2->type->info.struc.field;
SNode *fieldx2, *fieldy2;
while (fieldx1 != NULL && fieldy1 != NULL) {
fieldx2 = fieldx1->nexDec;
fieldy2 = fieldy1->nexDec;
while (fieldx2 != NULL && fieldy2 != NULL) {
if (fieldx2->type->info.basic != fieldy2->type->info.basic) return 0;
fieldx2 = fieldx2->nexDec;
fieldy2 = fieldy2->nexDec;
}
fieldx1 = fieldx1->nexField;
fieldy1 = fieldy1->nexField;
}
if (fieldx1 != NULL || fieldy1 != NULL) return 0;
return 1;
}
int checkFuncArgs(int index, SNode* cargs) {
SNode* args = symbolTable[index]->args;
if (args == NULL) return 0;
while (args != NULL && cargs != NULL) {
if (!isOptrandTypeSame(args, cargs)) return 0;
args = args->nexPar;
cargs = cargs->nexPar;
}
if (args != NULL || cargs != NULL) return 0;
return 1;
}
/*******************************************************
* operand chceker
* 1. not support function return structure
* 2. return true(no check) when operand is undefined
*******************************************************/
int isOptrandTypeSame(SNode* opt1, SNode* opt2) {
if (opt1->type->kind == UNDEFINED || opt2->type->kind == UNDEFINED) return 1;
if (opt1->type->kind != opt2->type->kind && opt2->type->kind != FUNC_BASIC) return 0;
switch (opt1->type->kind) {
case BASIC :
return checkBasic(opt1, opt2);
break;
case STRUCTTURE :
return checkField(opt1, opt2);
break;
}
return 0;
}
int checkBasic(SNode* opt1, SNode* opt2) {
return opt1->type->info.basic == opt2->type->info.basic;
}
int isOperandBasicType(SNode* opt) {
if (opt->type->kind == UNDEFINED) return 1;
return opt->type->kind == BASIC;
}
int isOperandTypeInt(SNode* opt) {
if (opt->type->kind == UNDEFINED) return 1;
return opt->type->kind == BASIC && opt->type->info.basic == BASIC_INT;
}
int isLeftHandVar(SNode* opt) {
return opt->type->constant.intval == 0 && opt->type->constant.floatval == 0;
}
/*******************************************************
* operator checker
*******************************************************/
int isAlgOperator(Node* node) {
return (
node->elem == SybPLUS ||
node->elem == SybMINUS ||
node->elem == SybSTAR ||
node->elem == SybDIV
);
}
int isLogOperator(Node* node) {
return (
node->elem == SybAND ||
node->elem == SybOR ||
node->elem == SybNOT ||
node->elem == SybRELOP
);
}
int isAsnOperator(Node* node) {
return (
node->elem == SybASSIGNOP
);
}
/*******************************************************
* printer
* @showSymbols show symbols
* @showSymblos show symbol table
* @showSymbol show info of a symbol in the table
// * @println divider printer
* @showStructField show fileds of structure
* @showArrayType show array info
* @showArgs show arguments of function
*******************************************************/
void showSymbols(char* sybs[], int cnt) {
println();
int i;
for (i = 0; i < cnt; i++) {
printf("%s\n", sybs[i]);
}
}
void showSymblos() {
int i;
for (i = 0; i < ucnt; i++) {
if(symbolTable[i] != NULL && filled[i]) {
showSymbol(i);
}
}
}
void showSymbol(int index) {
Symbol* symbol = symbolTable[index];
printf("symbol name: %s\nsymbol type: ", symbol->name);
switch (symbol->type->kind) {
case BASIC : printf("basic %d\n", symbol->type->info.basic); break;
// case ARRAY : printf("array "); showArrayType(symbol->type); printf("\n"); break;
case FUNC_BASIC : printf("function %d ", symbol->type->info.basic); showArgs(symbol->args); printf("\n"); break;
// case STRUCTTURE : printf("structure "); showStructField(symbol->name); printf("\n"); break;
default : break;
}
}
void println() {
printf("----------------------------------\n");
}
void showStructField(char* name) {
int index = getSymbolIndex(name);
if (index == -1 || !filled[index]) {
// printf("undefined\n");
return ;
}
printf("{");
SNode* field1 = symbolTable[index]->type->info.struc.field;
SNode* field2;
while (field1 != NULL) {
field2 = field1->nexDec;
while (field2 != NULL) {
// printf("%x\n", field2);
if (field2->fieldErr) {
field2 = field2->nexDec;
continue;
}
printf("type %d %s", field2->type->info.basic, field2->name);
field2 = field2->nexDec;
if (field2 != NULL) printf(" ");
}
field1 = field1->nexField;
if (field1 != NULL) printf(" ");
}
printf("}");
}
void showArrayType(Type* type) {
while(type->kind != BASIC) {
printf("[%d]", type->info.array.size);
type = type->info.array.type;
}
printf(" %d", type->info.basic);
}
void showArgs(SNode* arg) {
printf("(");
while(arg != NULL) {
switch (arg->type->kind) {
case BASIC :
// printf("basic %d %s ", arg->type->info.basic, arg->name);
if (arg->type->info.basic == 0) printf("int");
else printf("float");
break;
// case ARRAY : printf("array "); showArrayType(arg->type); printf(" "); break;
default : break;
}
arg = arg->nexPar;
if (arg != NULL) printf(", ");
}
printf(")");
}
int isSymbolArray(char* name) {
int index = getSymbolIndex(name);
return symbolTable[index]->type->kind == ARRAY;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/red1y/simplec-compiler.git
git@gitee.com:red1y/simplec-compiler.git
red1y
simplec-compiler
SimpleC-Compiler
master

Search