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 } } }
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; } }
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; } }
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()); } }
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++; } }
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; } } }
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; } } }
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]); }
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); } }
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); } } }
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()); } }
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() }; } }
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()); } }
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; }
void SemanticAnalysisVisitor::visit(ast::PrefixExpression& expression) { expression.visitOperand(*this); expression.setType(expression.operandType()); if (!expression.isLval()) { semanticError("lvalue required as increment operand", expression.getContext()); } }
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); } }
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); } }
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; } }
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; }
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); } } }
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()); } }
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; }
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); } }
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); }
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; } }
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); } }
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()); } }
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); } }
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()); } }
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; }