コード例 #1
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void exp__exp_lb_exp_rb(Node* node){
    if(node == NULL) return;
    Node* exp1 = node->firstChild;
    Node* exp2 = exp1->nextSibling->nextSibling;
    handle(exp1);handle(exp2);

#ifdef _DEBUG
showType(exp1->type);
showType(exp2->type);
#endif
    if(exp2->type != NULL && exp2->type->myType != NULL && exp2->type->myType != BASIC_INT){
        semanticError(node->line, "Index should be integer\n", NULL);
    }
    if(exp1->type != NULL && exp1->type->myType != NULL){
        if(exp1->type->myType->typeTag != type_array){
            semanticError(node->line, "Illegal use of '[]'\n", NULL);
        }else{
            node->type = newType();
            node->type->myType = exp1->type->myType->array.element;
#ifdef _DEBUG
printf("what the elment\n");
showType(node->type->myType);
#endif
        }
    }
}
コード例 #2
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void exp__id_lp_rp(Node* node){
    if(node == NULL) return;
    Node* id = node->firstChild;
    Type* func = findSymbolTable(id->text);
    if(func == NULL){
        semanticError(node->line, "Undefined function '%s'\n", id->text);
    }else if(func->typeTag != type_func){
        semanticError(node->line, "'%s' must be a function\n", id->text);
    }else{
        node->type = func->function.ret;
    }
}
コード例 #3
0
int findType(ASTnode* ID, int isLHS){//tells type of id
	if(ID==NULL)
		return -1;
	SymbolTable *tmp;	
	int z;
	tmp=topSymbolStack(symbolStack);
	while(tmp!=NULL){
	 	z=SearchHashTable(tmp,ID->t.lexeme);
		if(z!=-1)
			break;
		else tmp=tmp->parentTable;
		}
	if(tmp==NULL){
		semanticError(1,ID->t);
		return -1;
	}
	SymbolTableEntryNode *t=findSymbolTableNode(tmp->table[z].next,ID->t.lexeme);
	if(isLHS)
		return t->type.id.type;//do not check for initialization
	switch(t->type.id.type){
		case 57: if(t->type.id.initialized==1)
				return t->type.id.type;
			else{
				semanticError(9,ID->t);
				return -1;
				}
		case 58:if(t->type.id.initialized==1){
				if(t->type.id.length[0]==-1&&t->type.id.length[1]==-1){
						return t->type.id.type;//size can not be pre-determined
						}
				if(firstMatrix){
					firstMatrix=0;
					matrixRow=t->type.id.length[0];
					matrixCol=t->type.id.length[1];
					return t->type.id.type;
				}
				else if(t->type.id.length[0]==matrixRow&&t->type.id.length[1]==matrixCol)
						return t->type.id.type;
					else{
						semanticError(12,ID->t);
						return -1;
					}
				}
			else
				semanticError(11,ID->t);
		default: return t->type.id.type;	
	}	
}
コード例 #4
0
void SemanticAnalysisVisitor::visit(ast::FunctionCall& functionCall) {
    functionCall.visitOperand(*this);
    functionCall.visitArguments(*this);

    // FIXME: try/catch for undefined functions
    auto functionSymbol = symbolTable.findFunction(functionCall.operandSymbol()->getName());

    functionCall.setSymbol(functionSymbol);

    auto& arguments = functionCall.getArgumentList();
    if (arguments.size() == functionSymbol.argumentCount()) {
        auto& declaredArguments = functionSymbol.arguments();
        for (std::size_t i { 0 }; i < arguments.size(); ++i) {
            const auto& declaredArgument = declaredArguments.at(i);
            const auto& actualArgument = arguments.at(i)->getResultSymbol();
            typeCheck(actualArgument->getType(), *declaredArgument, functionCall.getContext());
        }

        auto& returnType = functionSymbol.returnType();
        if (!returnType.isVoid()) {
            functionCall.setResultSymbol(symbolTable.createTemporarySymbol(std::unique_ptr<ast::FundamentalType> {
                    returnType.clone() }));
        }
    } else {
        semanticError("no match for function " + functionSymbol.getType().toString(), functionCall.getContext());
    }
}
コード例 #5
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void dec__vardec(Node* node){
    if(node == NULL) return;
    Node* vardec = node->firstChild;
    vardec->type = node->type;

#ifdef _DEBUG
showType(vardec->type);
#endif

    handle(vardec);

    if(!insertSymbolTableType(vardec->type)){
        semanticError(vardec->line, "Redefined variable '%s'\n", vardec->type->name);
    }
    node->type = vardec->type;

#ifdef _DEBUG
showType(vardec->type);
#endif

    if(inStruct){    // 添加var到struct中
        structElement[elementIndex] = node->type;
        elementIndex++;
    }
}
コード例 #6
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void exp__exp_assignop_exp(Node* node){
    if(node == NULL) return;
    Node* exp1 = node->firstChild;
    Node* exp2 = exp1->nextSibling->nextSibling;
    handle(exp1);
    handle(exp2);
    if(exp1->type != NULL && exp2->type != NULL){
        if(!checkType(exp1->type, exp2->type)){
            semanticError(node->line, "Type mismatched\n", NULL);
        }else if(!isLeftValue(exp1)){
            semanticError(node->line, "The left-hand side of an assignment must be a variable\n", NULL);
        }else{
            node->type = exp1->type;
        }
    }
}
コード例 #7
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void exp__exp_op_exp(Node* node){
    if(node == NULL) return;
    Node* exp1 = node->firstChild;
    Node* exp2 = exp1->nextSibling->nextSibling;
    handle(exp1);
    handle(exp2);
    if(exp1->type != NULL && exp2->type != NULL){
        if(!checkType(exp1->type, exp2->type)){
            semanticError(node->line, "Operands type mismatched\n", NULL);
        }else if(!checkType(exp1->type, BASIC_FLOAT) && !checkType(exp1->type, BASIC_INT)){
            semanticError(node->line, "Type is not allowed in operation '%s'\n", exp1->nextSibling->text);
        }else{
            node->type = exp1->type;    
        }        
    }
}
コード例 #8
0
void MatrixInit(ASTnode* ID,ASTnode* rows){
	ASTnode* rowsMain=rows;
	int colSize,curColSize;
	int n=0;
	token bufToken;
	colSize=computeColSize(rows->array[0]);
	bufToken.lineNumber=rows->array[0]->array[0]->t.lineNumber;
	while(rows!=NULL){
		n++;
		curColSize=computeColSize(rows->array[0]);
		rows=rows->array[1];	
		if(curColSize!=colSize){
			semanticError(4,bufToken);
			return;
			}
	}
	SymbolTableEntryNode* t=getSymbolTableNode(ID);
	SymbolTable* h=getSymbolTable(ID);
	t->type.id.initialized=1;
	t->type.id.length[0]=n;
	t->type.id.length[1]=colSize;
	t->type.id.offset=h->offset;
	populateMatrix(t, rowsMain);
	h->offset+=n*colSize;	
	//printf("Matrix t->lexeme %s, size initialized: %d %d",t->lexeme,t->type.id.length[0],t->type.id.length[1]);
	}
コード例 #9
0
void SemanticAnalysisVisitor::typeCheck(const ast::FundamentalType& typeFrom, const ast::FundamentalType& typeTo,
        const translation_unit::Context& context)
{
    if (!typeFrom.canConvertTo(typeTo)) {
        semanticError("type mismatch: can't convert " + typeFrom.toString() + " to " + typeTo.toString(), context);
    }
}
コード例 #10
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void exp__id(Node* node){
    if(node == NULL) return;
    Node* id = node->firstChild;
    Type* t = findSymbolTable(id->text);
    if(t == NULL){
        semanticError(node->line, "Undefined variable '%s'\n", id->text);
    }else if(t->typeTag == define_struct){
        semanticError(node->line, "'%s' is name of structure\n", id->text);
    }else{
        if(t->typeTag == type_general){
            node->type = t;
        }else{
            assert(0);
        }   
    }
}
コード例 #11
0
void SemanticAnalysisVisitor::visit(ast::FormalArgument& argument) {
    argument.visitSpecifiers(*this);
    argument.visitDeclarator(*this);
    if (argument.getType()->isVoid()) {
        semanticError("function argument ‘" + argument.getName() + "’ declared void", argument.getDeclarationContext());
    }
}
コード例 #12
0
void SemanticAnalysisVisitor::visit(ast::UnaryExpression& expression) {
    expression.visitOperand(*this);

    switch (expression.getOperator()->getLexeme().front()) {
    case '&':
        expression.setResultSymbol(symbolTable.createTemporarySymbol(
                std::make_unique<ast::PointerType>(
                        std::unique_ptr<ast::FundamentalType>(expression.operandType().clone()))));
        break;
    case '*':
        if (expression.operandType().isPointer()) {
            expression.setResultSymbol(symbolTable.createTemporarySymbol(expression.operandType().dereference()));
            expression.setLvalueSymbol(symbolTable.createTemporarySymbol(
                    std::unique_ptr<ast::FundamentalType> { expression.operandType().clone() }));
        } else {
            semanticError("invalid type argument of ‘unary *’ :" + expression.operandType().toString(),
                    expression.getContext());
        }
        break;
    case '+':
        break;
    case '-':
        expression.setResultSymbol(
                symbolTable.createTemporarySymbol(
                        std::unique_ptr<ast::FundamentalType>(expression.operandType().clone())));
        break;
    case '!':
        expression.setResultSymbol(symbolTable.createTemporarySymbol(ast::IntegralType::newSignedInteger()));
        expression.setTruthyLabel(symbolTable.newLabel());
        expression.setFalsyLabel(symbolTable.newLabel());
        break;
    default:
        throw std::runtime_error { "Unidentified increment operator: " + expression.getOperator()->getLexeme() };
    }
}
コード例 #13
0
void SemanticAnalysisVisitor::visit(ast::IdentifierExpression& identifier) {
    if (symbolTable.hasSymbol(identifier.getIdentifier())) {
        identifier.setResultSymbol(symbolTable.lookup(identifier.getIdentifier()));
    } else {
        semanticError("symbol `" + identifier.getIdentifier() + "` is not defined", identifier.getContext());
    }
}
コード例 #14
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void structspecifier__struct_id_lc_deflist_rc(Node* node){
    if(node == NULL) return;
    inStruct = true;

    Node* id = node->firstChild->nextSibling;

    Type* tmp = newType();
    tmp->name = id->text;
    tmp->typeTag = define_struct;

    Node* deflist = id->nextSibling->nextSibling;
    if(deflist->tag == _DefList){
        structElement = (Type**)malloc(sizeof(Type*) * maxElement);
        memset(structElement, 0, sizeof(Type*) * maxElement);
        elementIndex = 0;

        handle(deflist);//将数据成员的指针存到tmp->element中

        tmp->structure.elementCount = elementIndex;
        tmp->structure.element = structElement;
    }else{
        tmp->structure.elementCount = 0;
        tmp->structure.element = NULL;        
    }
    if(!insertSymbolTableType(tmp)){
        semanticError(id->line, "Duplicated definition of '%s'\n", tmp->name);
    }
    node->type = tmp;
    inStruct = false;
}
コード例 #15
0
void SemanticAnalysisVisitor::visit(ast::PrefixExpression& expression) {
    expression.visitOperand(*this);

    expression.setType(expression.operandType());
    if (!expression.isLval()) {
        semanticError("lvalue required as increment operand", expression.getContext());
    }
}
コード例 #16
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void stmt__return_exp_semi(Node* node){
    if(node == NULL) return;
    Node* exp = node->firstChild->nextSibling;
    handle(exp);
    if(!checkType(exp->type, node->type)){
        semanticError(node->line, "The return type mismatched\n", NULL);
    }
}   
コード例 #17
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void args__exp(Node* node){
    if(node == NULL) return;
    Node* exp = node->firstChild;
    handle(exp);
    Type* t = exp->type;
    bool good = true;
    if(node->funcArgIndex >= node->funcArgCount){
        good = false;
        semanticError(node->line, "Number of arguments mismatched 2\n", NULL);
    }else if(!checkType(t, node->funcStdArgv[node->funcArgIndex])){
        semanticError(node->line, "Type of argument mismatched\n", NULL);
    }
    node->funcArgIndex++;
    if(good && node->funcArgCount != node->funcArgIndex){
        semanticError(node->line, "Number of arguments mismatched 3 \n", NULL);        
    }
}
コード例 #18
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void exp__id_lp_args_rp(Node* node){
    if(node == NULL) return;
    Node* id = node->firstChild;
    Node* args = id->nextSibling->nextSibling;
    Type* func = findSymbolTable(id->text);
    if(func == NULL){
        semanticError(node->line, "Undefined function '%s'\n", id->text);
    }else if(func->typeTag != type_func){
        semanticError(node->line, "'%s' must be a function\n", id->text);
    }else{
        args->funcStdArgv = func->function.argv;
        args->funcArgCount = func->function.argc;
        args->funcArgIndex = 0;
        handle(args);
        node->type = func->function.ret;
    }
}
コード例 #19
0
ファイル: symtab.c プロジェクト: doniexun/compiler-18
SymTabESP sym_insert_var(IdentSP idp)
{
	SymBucketSP p;
	SymTabESP e;
	e = NULL;
	int h = hash(idp->name);
	if (TOP == NULL) 
		fprintf(tiplist, "SYMTAB BUG:121\n");
	for (p = *(TOP->sbp + h); p != NULL; p = p->next) {
		if ((p->ep != NULL) && (!strcmp(idp->name, p->ep->name)) ) 
				break;
	}
	if (p == NULL) {
		ENTRY(SymTabES, e);
		e->name = copyString(idp->name);
		e->label = Nappend(idp->name);
		e->lineno = idp->line;
		e->level = LEVEL;
		e->posi = TOP->posi_var;
		switch (idp->type) {
		case Int_Var_Ident_t:
			e->type = Int_Type_t;
			e->obj = Var_Obj_t;
			e->val = -1;
			TOP->posi_var++;
			break;
		case Char_Var_Ident_t:
			e->type = Char_Type_t;
			e->obj = Var_Obj_t;
			e->val = -1;
			TOP->posi_var++;
			break;
		case IntArr_Var_Ident_t:
			e->type = Int_Type_t;
			e->obj = Array_Obj_t;
			e->val = idp->length;
			TOP->posi_var += e->val;
			break;
		case CharArr_Var_Ident_t:
			e->type = Char_Type_t;
			e->obj = Array_Obj_t;
			e->val = idp->length;
			TOP->posi_var += e->val;
			break;
		default:
			fprintf(tiplist, "SYMTAB BUG: 143\n");
		}
		e->stp = TOP;
		ENTRY(SymBucketS, p);
		p->ep = e;
		p->next = NULL;
		sym_insert(p, TOP);
	} else {
		--runlevel;
		semanticError(DUPSYM, idp->line, FALSE, idp->name);
	}
	return e;
}
コード例 #20
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void dec__vardec_assignop_exp(Node* node){
    if(node == NULL) return;
    dec__vardec(node);
    if(inStruct){
        semanticError(node->line, "Initialization in the structure definition is not allowed\n", NULL);
    }
    else{
        Node* exp = node->firstChild->nextSibling->nextSibling;
        handle(exp);
#ifdef _DEBUG
showType(node->type);
showType(exp->type);
#endif
        if(!checkType(exp->type, node->type)){
            semanticError(node->line, "Type mismatched\n", NULL);
        }
    }
}
コード例 #21
0
void SemanticAnalysisVisitor::visit(ast::DeclarationSpecifiers& declarationSpecifiers) {
    // FIXME: this would look so much better
    /*for (std::string error : declarationSpecifiers.getSemanticErrors()) {
     semanticError(error, globalContext);
     }*/
    if (declarationSpecifiers.getStorageSpecifiers().size() > 1) {
        semanticError("multiple storage classes in declaration specifiers",
                declarationSpecifiers.getStorageSpecifiers().at(1).getContext());
    }
}
コード例 #22
0
int outputCheck1(ASTnode* leaf){//listVar
	if(!isDeclared(leaf)){
		semanticError(1,leaf->t);
		return 0;
		}
	typeCounter++;
	type[typeCounter]=findType(leaf,1);
	SymbolTableEntryNode* t=getSymbolTableNode(leaf);
	t->type.id.initialized=1;
	}
コード例 #23
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void extdeclist__vardec(Node* node){
    if(node == NULL) return;
    Node* vardec = node->firstChild;
    vardec->type = node->type;
    handle(vardec);

    if(!insertSymbolTableType(vardec->type)){
        semanticError(vardec->line, "Duplicated definition of '%s'\n", vardec->text);
    }
}
コード例 #24
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void stmt__while_lp_exp_rp_stmt(Node* node){
    if(node == NULL) return;
    Node* exp = node->firstChild->nextSibling->nextSibling;
    Node* stmt = exp->nextSibling->nextSibling;
    handle(exp);
    if(!checkType(exp->type, BASIC_INT)){
        semanticError(node->line, "The condition expression must return int\n", NULL);
    }
    handle(stmt);
}
コード例 #25
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void structspecifier__struct_id(Node* node){
    if(node == NULL) return;
    Node* id = node->firstChild->nextSibling;
    Symbol* tmp = findSymbolTable(id->text);
    if(tmp == NULL || (tmp != NULL && tmp->typeTag != define_struct)){
        semanticError(id->line, "Undefined struct '%s'\n", id->text);
        node->type = BASIC_UNKNOWN_TYPE;
    }else{
        node->type = tmp;
    }
}
コード例 #26
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void args__exp_comma_args(Node* node){
    if(node == NULL) return;

    Node* exp = node->firstChild;
    Node* args = exp->nextSibling->nextSibling;
    handle(exp);
    Type* t = exp->type;
    if(node->funcArgIndex >= node->funcArgCount){
        semanticError(node->line, "Number of arguments mismatched 1\n", NULL);
    }else if(!checkType(t, node->funcStdArgv[node->funcArgIndex])){
        semanticError(node->line, "Type of argument mismatched\n", NULL);
    }else{
        node->funcArgIndex++;
        args->funcStdArgv = node->funcStdArgv;
        args->funcArgCount = node->funcArgCount;
        args->funcArgIndex = node->funcArgIndex;
        handle(args);
    }

}
コード例 #27
0
void SemanticAnalysisVisitor::visit(ast::ShiftExpression& expression) {
    expression.visitLeftOperand(*this);
    expression.visitRightOperand(*this);

    if (expression.rightOperandType().isNumeric()) {
        expression.setResultSymbol(
                symbolTable.createTemporarySymbol(
                        std::unique_ptr<ast::FundamentalType> { expression.leftOperandType().clone() }));
    } else {
        semanticError("argument of type int required for shift expression", expression.getContext());
    }
}
コード例 #28
0
ファイル: semantic.c プロジェクト: moreOver0/c_compiler
static void specifier__type(Node* node){
    if(node == NULL) return;
    Node* type = node->firstChild;
    if(strcmp(type->text, "int") == 0){
        node->type = BASIC_INT;
    }else if(strcmp(type->text, "float") == 0){
        node->type = BASIC_FLOAT;
    }else{
        node->type = BASIC_UNKNOWN_TYPE;
        semanticError(type->line, "Unknown type '%s'\n", type->text);
    }
}
コード例 #29
0
void SemanticAnalysisVisitor::visit(ast::ArrayAccess& arrayAccess) {
    arrayAccess.visitLeftOperand(*this);
    arrayAccess.visitRightOperand(*this);

    auto& type = arrayAccess.leftOperandType();
    if (type.isPointer()) {
        arrayAccess.setLvalue(symbolTable.createTemporarySymbol(type.dereference()));
        arrayAccess.setResultSymbol(symbolTable.createTemporarySymbol(type.dereference()));
    } else {
        semanticError("invalid type for operator[]\n", arrayAccess.getContext());
    }
}
コード例 #30
0
ファイル: symtab.c プロジェクト: doniexun/compiler-18
SymTabESP sym_insert_para(IdentSP idp)
{
	SymBucketSP p;
	SymTabESP e;
	e = NULL;
	int h = hash(idp->name);
	if (TOP == NULL) 
		fprintf(tiplist, "SYMTAB BUG:263\n");
	for (p = *(TOP->sbp + h); p != NULL; p = p->next) {
		if ((p->ep != NULL) && (!strcmp(idp->name, p->ep->name)) ) 
				break;
	}
	if (p == NULL) {
		ENTRY(SymTabES, e);
		e->name = copyString(idp->name);
		e->label = Nappend(idp->name); 
		e->val = -1;
		e->lineno = idp->line;
		e->level = LEVEL;
		e->posi = TOP->posi_para++;
		switch (idp->type) {
		case Int_Para_Val_Ident_t:
			e->obj = Para_Val_Obj_t;
			e->type = Int_Type_t;
			break;
		case Int_Para_Ref_Ident_t:
			e->obj = Para_Ref_Obj_t;
			e->type = Int_Type_t;
			break;
		case Char_Para_Val_Ident_t:
			e->obj = Para_Val_Obj_t;
			e->type = Char_Type_t;
			break;
		case Char_Para_Ref_Ident_t:
			e->obj = Para_Ref_Obj_t;
			e->type = Char_Type_t;
			break;
		default:
			fprintf(tiplist, "SYMTAB BUG: 291\n");
		}
		e->stp = TOP;
		recParaInfo(e);
		ENTRY(SymBucketS, p);
		p->ep = e;
		p->next = NULL;
		sym_insert(p, TOP);
	} else {
		--runlevel;
		semanticError(DUPSYM, idp->line, FALSE, idp->name);
	}
	return e;
}