📄 semanticchecker.c
字号:
}}static void CheckStatement(NodePtr classNodePtr, NodePtr statementNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr argListNodePtr = NULL; int i; if (statementNodePtr == NULL) { return; } switch (statementNodePtr->type) { case NODE_TYPE_ASGN_STMT: CheckAssignmentStatement(classNodePtr, statementNodePtr, symbolTablePtr); break; case NODE_TYPE_FUNC_STMT: CheckFunctionCall(classNodePtr, statementNodePtr, symbolTablePtr); break; case NODE_TYPE_PRINT_STMT: argListNodePtr = statementNodePtr->children[0]; CheckArgList(classNodePtr, argListNodePtr, NULL, FALSE, symbolTablePtr); for (i = 0; i < argListNodePtr->numberOfChildren - 1; i ++) { if (argListNodePtr->children[i]->typePtr != intTypePtr) { ReportError(ERROR_NON_INT_EXP, STRING_PRINT, argListNodePtr->children[i]->lineNumber, argListNodePtr->children[i]->columnNumber); } } break; case NODE_TYPE_IF_STMT: if (CheckExpression(classNodePtr, statementNodePtr->children[0], symbolTablePtr) != intTypePtr) { ReportError(ERROR_NON_INT_EXP, STRING_IF, statementNodePtr->children[0]->lineNumber, statementNodePtr->children[0]->columnNumber); } CheckStatement(classNodePtr, statementNodePtr->children[1], symbolTablePtr); CheckStatement(classNodePtr, statementNodePtr->children[2], symbolTablePtr); break; case NODE_TYPE_WHILE_STMT: if (CheckExpression(classNodePtr, statementNodePtr->children[0], symbolTablePtr) != intTypePtr) { ReportError(ERROR_NON_INT_EXP, STRING_WHILE, statementNodePtr->children[0]->lineNumber, statementNodePtr->children[0]->columnNumber); } CheckStatement(classNodePtr, statementNodePtr->children[1], symbolTablePtr); break; case NODE_TYPE_RETURN_STMT: /* if (statementNodePtr->children[0] == NULL) { if (currentMethodReturnTypePtr != voidTypePtr) { ReportError(ERROR_CONFLICTING_RETURN_TYPE, voidTypePtr->id, statementNodePtr->lineNumber, statementNodePtr->columnNumber); } } else { */ if (statementNodePtr->children[0] != NULL) { if (CheckExpression(classNodePtr, statementNodePtr->children[0], symbolTablePtr) != currentMethodReturnTypePtr) { ReportError(ERROR_CONFLICTING_RETURN_TYPE, statementNodePtr->children[0]->typePtr->id, statementNodePtr->lineNumber, statementNodePtr->columnNumber); } } break; case NODE_TYPE_BLOCK_STMT: CheckBlock(classNodePtr, statementNodePtr); break; default: break; }}static void CheckAssignmentStatement(NodePtr classNodePtr, NodePtr statementNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr nameNodePtr = NULL; NodePtr expNodePtr = NULL; if (statementNodePtr == NULL) { return; } nameNodePtr = statementNodePtr->children[0]; expNodePtr = statementNodePtr->children[1]; if (CheckName(classNodePtr, nameNodePtr, TRUE, symbolTablePtr) == classNodePtr->typePtr) { if (strcmp(lastNameNodePtr->children[0]->info.lexeme, STRING_THIS) == 0) { ReportError(ERROR_L_VALUE_THIS, STRING_THIS, nameNodePtr->lineNumber, nameNodePtr->columnNumber); } } CheckExpression(classNodePtr, expNodePtr, symbolTablePtr); #ifdef DEBUG printf("name's type is %x\n", nameNodePtr->typePtr); printf("exp's type is %x\n", expNodePtr->typePtr); #endif if (IsEquivalentType(nameNodePtr->typePtr, expNodePtr->typePtr) == FALSE) { if (expNodePtr->type == NODE_TYPE_FUNCTION_EXP) { if ((currentMethodDecNodePtr != NULL) && (currentMethodDecNodePtr->lineNumber > expNodePtr->lineNumber)) { ReportError( ERROR_CONFLICTING_METHOD_DEC, currentMethodDecNodePtr->children[1]->info.lexeme, currentMethodDecNodePtr->lineNumber, currentMethodDecNodePtr->columnNumber); } } ReportError(ERROR_INCOMPATIBLE_EXP, STRING_EQUAL, statementNodePtr->lineNumber, statementNodePtr->columnNumber); }}static ElementPtr CheckName(NodePtr classNodePtr, NodePtr nameNodePtr, Boolean isTop, SymbolTablePtr symbolTablePtr){ NodePtr varNodePtr = NULL; NodePtr subClassNodePtr = NULL; NodePtr attributeNodePtr = NULL; if (nameNodePtr == NULL) { return(unknownTypePtr); } varNodePtr = nameNodePtr->children[0]; switch (varNodePtr->type) { case NODE_TYPE_KEYWORD: varNodePtr->typePtr = classNodePtr->typePtr; break; case NODE_TYPE_IDENTIFIER: CheckIdentifier(classNodePtr, varNodePtr, isTop, symbolTablePtr); break; case NODE_TYPE_ARRAY_ACCESS: CheckArrayAccess(classNodePtr, varNodePtr, isTop, symbolTablePtr); break; default: break; } if (nameNodePtr->numberOfChildren == 1) { nameNodePtr->typePtr = varNodePtr->typePtr; lastNameNodePtr = nameNodePtr; } else { if (IsPrimitiveType(varNodePtr->typePtr) == TRUE) { ReportError(ERROR_NOT_CLASS_INSTANCE, varNodePtr->info.lexeme, varNodePtr->lineNumber, varNodePtr->columnNumber); nameNodePtr->typePtr = unknownTypePtr; } else if (IsArrayType(varNodePtr->typePtr) == TRUE) { attributeNodePtr = nameNodePtr->children[1]->children[0]; if (strcmp(attributeNodePtr->info.lexeme, STRING_LENGTH) == 0) { if (nameNodePtr->children[1]->numberOfChildren > 1) { ReportError(ERROR_NOT_CLASS_INSTANCE, attributeNodePtr->info.lexeme, attributeNodePtr->lineNumber, attributeNodePtr->columnNumber); nameNodePtr->typePtr = unknownTypePtr; } else { nameNodePtr->typePtr = intTypePtr; } } else { ReportError( ERROR_NOT_ARRAY_LENGTH, nameNodePtr->children[1]->children[0]->info.lexeme, nameNodePtr->children[1]->children[0]->lineNumber, nameNodePtr->children[1]->children[0]->columnNumber); nameNodePtr->typePtr = unknownTypePtr; } } else { subClassNodePtr = ClassNodeOfType(varNodePtr->typePtr); nameNodePtr->typePtr = CheckName(subClassNodePtr, nameNodePtr->children[1], FALSE, subClassNodePtr->info.symbolTablePtr); } } return(nameNodePtr->typePtr);}static ElementPtr CheckExpression(NodePtr classNodePtr, NodePtr expNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr expNode1Ptr = NULL; NodePtr expNode2Ptr = NULL; if (expNodePtr == NULL) { return(unknownTypePtr); } switch (expNodePtr->type) { case NODE_TYPE_NAME: CheckName(classNodePtr, expNodePtr, TRUE, symbolTablePtr); break; case NODE_TYPE_NUMBER: expNodePtr->typePtr = intTypePtr; break; case NODE_TYPE_KEYWORD: expNodePtr->typePtr = refTypePtr; break; case NODE_TYPE_FUNCTION_EXP: CheckFunctionCall(classNodePtr, expNodePtr, symbolTablePtr); break; case NODE_TYPE_READ_EXP: expNodePtr->typePtr = intTypePtr; break; case NODE_TYPE_NEW_EXP: CheckNewExpression(classNodePtr, expNodePtr, symbolTablePtr); break; case NODE_TYPE_UNARY_EXP: expNodePtr->typePtr = CheckExpression(classNodePtr, expNodePtr->children[0], symbolTablePtr); CheckExpressionMeaning(expNodePtr); break; default: expNode1Ptr = expNodePtr->children[0]; expNode2Ptr = expNodePtr->children[1]; CheckExpression(classNodePtr, expNode1Ptr, symbolTablePtr); CheckExpression(classNodePtr, expNode2Ptr, symbolTablePtr); if (IsEquivalentType(expNode1Ptr->typePtr, expNode2Ptr->typePtr) == TRUE) { expNodePtr->typePtr = expNode1Ptr->typePtr; CheckExpressionMeaning(expNodePtr); if (IsRelationExpression(expNodePtr) == TRUE) { expNodePtr->typePtr = intTypePtr; } else { expNodePtr->typePtr = expNode1Ptr->typePtr; } } else { if (expNode1Ptr->type == NODE_TYPE_FUNCTION_EXP) { if ((currentMethodDecNodePtr != NULL) && (currentMethodDecNodePtr->lineNumber > expNode1Ptr->lineNumber)) { ReportError( ERROR_CONFLICTING_METHOD_DEC, currentMethodDecNodePtr->children[1]->info.lexeme, currentMethodDecNodePtr->lineNumber, currentMethodDecNodePtr->columnNumber); } } else if (expNode2Ptr->type == NODE_TYPE_FUNCTION_EXP) { if ((currentMethodDecNodePtr != NULL) && (currentMethodDecNodePtr->lineNumber > expNode2Ptr->lineNumber)) { ReportError( ERROR_CONFLICTING_METHOD_DEC, currentMethodDecNodePtr->children[1]->info.lexeme, currentMethodDecNodePtr->lineNumber, currentMethodDecNodePtr->columnNumber); } } ReportError(ERROR_INCOMPATIBLE_EXP, expNodePtr->info.lexeme, expNodePtr->lineNumber, expNodePtr->columnNumber); expNodePtr->typePtr = unknownTypePtr; } break; } return(expNodePtr->typePtr);}static ElementPtr CheckIdentifier(NodePtr classNodePtr, NodePtr varNodePtr, Boolean isTop, SymbolTablePtr symbolTablePtr){ ElementPtr elementPtr = NULL; if (isTop == TRUE) { elementPtr = Lookup(symbolTablePtr, varNodePtr->info.lexeme); if (elementPtr == NULL) { elementPtr = Lookup(classNodePtr->info.symbolTablePtr, varNodePtr->info.lexeme); } } else { elementPtr = Lookup(classNodePtr->info.symbolTablePtr, varNodePtr->info.lexeme); } if (elementPtr == NULL) { ReportError(ERROR_UNDEFINED_VARIABLE, varNodePtr->info.lexeme, varNodePtr->lineNumber, varNodePtr->columnNumber); varNodePtr->typePtr = unknownTypePtr; } else { varNodePtr->typePtr = elementPtr->typePtr; }}static ElementPtr CheckArrayAccess(NodePtr classNodePtr, NodePtr varNodePtr, Boolean isTop, SymbolTablePtr symbolTablePtr){ int dimension; NodePtr idNodePtr = NULL; int i; dimension = varNodePtr->numberOfChildren - 1; #ifdef DEBUG printf("dimension is %d\n", dimension); #endif idNodePtr = varNodePtr->children[0]; CheckIdentifier(classNodePtr, idNodePtr, isTop, symbolTablePtr); if (idNodePtr->typePtr != unknownTypePtr) { if (DimensionOfType(idNodePtr->typePtr) < dimension) { ReportError(ERROR_INCOMPATIBLE_DIMENSION, idNodePtr->info.lexeme, idNodePtr->lineNumber, idNodePtr->columnNumber); varNodePtr->typePtr = unknownTypePtr; } else { varNodePtr->typePtr = TypeOfArrayAcess(idNodePtr->typePtr, dimension); } for (i = 1; i < dimension + 1; i ++) { if (CheckExpression(classNodePtr, varNodePtr->children[i], symbolTablePtr) != intTypePtr) { ReportError(ERROR_NON_INT_INDEX, varNodePtr->children[i]->info.lexeme, varNodePtr->children[i]->lineNumber, varNodePtr->children[i]->columnNumber); } } } return(varNodePtr->typePtr);}static ElementPtr CheckNewExpression(NodePtr classNodePtr, NodePtr expNodePtr, SymbolTablePtr symbolTablePtr){ ElementPtr typePtr = NULL; NodePtr idNodePtr = NULL; NodePtr argListNodePtr = NULL; NodePtr indexListNodePtr = NULL; NodePtr newClassNodePtr = NULL; NodePtr constructorDecNodePtr = NULL; int i; idNodePtr = expNodePtr->children[0]; typePtr = Lookup(typeSymbolTable, idNodePtr->info.lexeme); if (typePtr == NULL) { ReportError(ERROR_UNDEFINED_TYPE, idNodePtr->info.lexeme, idNodePtr->lineNumber, idNodePtr->columnNumber); idNodePtr->typePtr = unknownTypePtr; expNodePtr->typePtr = unknownTypePtr; } else { if (expNodePtr->children[1] == NULL) { idNodePtr->typePtr = typePtr; expNodePtr->typePtr = typePtr; } else { if (expNodePtr->children[1]->type == NODE_TYPE_ARG_LIST) { argListNodePtr = expNodePtr->children[1]; if (IsPrimitiveType(typePtr) == TRUE) { ReportError(ERROR_NEW_NON_CLASS_OBJ, idNodePtr->info.lexeme, idNodePtr->lineNumber, idNodePtr->columnNumber); expNodePtr->typePtr = unknownTypePtr; } else { expNodePtr->typePtr = typePtr; newClassNodePtr = ClassNodeOfType(typePtr); if (newClassNodePtr->children[1] != NULL) { constructorDecNodePtr = newClassNodePtr->children[1]->children[1]; if (constructorDecNodePtr == NULL) { if (argListNodePtr->numberOfChildren > 1) { ReportError( ERROR_TOO_MANY_ARGUMENTS, newClassNodePtr->children[0]->info.lexeme, argListNodePtr->lineNumber, argListNodePtr->columnNumber); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -