📄 semanticchecker.c
字号:
} CheckArgList(classNodePtr, argListNodePtr, constructorDecNodePtr, TRUE, symbolTablePtr); } else { CheckArgList(classNodePtr, argListNodePtr, NULL, TRUE, symbolTablePtr); } } } else { typePtr = GetNewArrayType(expNodePtr); if (typePtr == NULL) { ReportError(ERROR_UNDEFINED_TYPE, expNodePtr->info.lexeme, expNodePtr->lineNumber, expNodePtr->columnNumber); expNodePtr->typePtr = unknownTypePtr; } else { expNodePtr->typePtr = typePtr; } indexListNodePtr = expNodePtr->children[1]; for (i = 0; i < indexListNodePtr->numberOfChildren; i ++) { if (CheckExpression(classNodePtr, indexListNodePtr->children[i], symbolTablePtr) != intTypePtr) { ReportError( ERROR_NON_INT_INDEX, idNodePtr->info.lexeme, indexListNodePtr->children[i]->lineNumber, indexListNodePtr->children[i]->columnNumber); } } } } } return(expNodePtr->typePtr);}static void CheckExpressionMeaning(NodePtr expNodePtr){ if (IsPrimitiveType(expNodePtr->typePtr) == FALSE) { if ((strcmp(expNodePtr->info.lexeme, STRING_EQUAL_EQUAL) != 0) && (strcmp(expNodePtr->info.lexeme, STRING_NOT_EQUAL) != 0)) { ReportError(ERROR_NON_INT_OPERAND, expNodePtr->info.lexeme, expNodePtr->lineNumber, expNodePtr->columnNumber); } }}static ElementPtr CheckFunctionCall(NodePtr classNodePtr, NodePtr callNodePtr, SymbolTablePtr symbolTablePtr){ NodePtr methodDecNodePtr = NULL; callNodePtr->typePtr = CheckMethodCall( classNodePtr, callNodePtr->children[0], TRUE, symbolTablePtr, &(callNodePtr->info.lexeme), &methodDecNodePtr); currentMethodDecNodePtr = methodDecNodePtr; if ((methodDecNodePtr != NULL) && (IsCheckedMethodDec(methodDecNodePtr) == FALSE)) { methodDecNodePtr->typePtr = CheckReturnType(methodDecNodePtr->children[0]); currentMethodReturnTypePtr = methodDecNodePtr->typePtr; CheckParameterList(methodDecNodePtr->children[2], methodDecNodePtr->info.symbolTablePtr); } CheckArgList(classNodePtr, callNodePtr->children[1], methodDecNodePtr, FALSE, symbolTablePtr); return(callNodePtr->typePtr);}static ElementPtr CheckMethodCall(NodePtr classNodePtr, NodePtr nameNodePtr, Boolean isTop, SymbolTablePtr symbolTablePtr, String *classNamePtr, NodePtr *methodDecNodePtr){ NodePtr varNodePtr = NULL; NodePtr subClassNodePtr = 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: if (nameNodePtr->numberOfChildren == 1) { CheckMethodName(classNodePtr, varNodePtr, classNamePtr, methodDecNodePtr); } else { 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; if (nameNodePtr->children[0]->type == NODE_TYPE_KEYWORD) { ReportError(ERROR_MISUSED_THIS, STRING_THIS, nameNodePtr->lineNumber, nameNodePtr->columnNumber); } } else { if ((IsPrimitiveType(varNodePtr->typePtr) == TRUE) || (IsArrayType(varNodePtr->typePtr) == TRUE)) { ReportError(ERROR_NOT_CLASS_INSTANCE, varNodePtr->info.lexeme, varNodePtr->lineNumber, varNodePtr->columnNumber); nameNodePtr->typePtr = unknownTypePtr; } else { subClassNodePtr = ClassNodeOfType(varNodePtr->typePtr); nameNodePtr->typePtr = CheckMethodCall(subClassNodePtr, nameNodePtr->children[1], FALSE, subClassNodePtr->info.symbolTablePtr, classNamePtr, methodDecNodePtr); } } return(nameNodePtr->typePtr);}static ElementPtr CheckMethodName(NodePtr classNodePtr, NodePtr idNodePtr, String *classNamePtr, NodePtr *methodDecNodePtrPtr){ int i; NodePtr methodDecListNodePtr = NULL; if (idNodePtr == NULL) { *methodDecNodePtrPtr = NULL; return(unknownTypePtr); } if (strcmp(idNodePtr->info.lexeme, classNodePtr->children[0]->info.lexeme) == 0) { ReportError(ERROR_CONSTRUCTOR_CALL, idNodePtr->info.lexeme, idNodePtr->lineNumber, idNodePtr->columnNumber); *methodDecNodePtrPtr = NULL; idNodePtr->typePtr = unknownTypePtr; return(idNodePtr->typePtr); } methodDecListNodePtr = classNodePtr->children[1]->children[2]; if (methodDecListNodePtr == NULL) { return(unknownTypePtr); } for (i = 0; i < methodDecListNodePtr->numberOfChildren; i ++) { *methodDecNodePtrPtr = methodDecListNodePtr->children[i]; if (strcmp(idNodePtr->info.lexeme, (*methodDecNodePtrPtr)->children[1]->info.lexeme) == 0) { idNodePtr->typePtr = (*methodDecNodePtrPtr)->children[0]->typePtr; *classNamePtr = strdup(classNodePtr->children[0]->info.lexeme); return(idNodePtr->typePtr); } } ReportError(ERROR_UNDEFINED_METHOD, idNodePtr->info.lexeme, idNodePtr->lineNumber, idNodePtr->columnNumber); *methodDecNodePtrPtr = NULL; idNodePtr->typePtr = unknownTypePtr; return(idNodePtr->typePtr);}static void CheckArgList(NodePtr classNodePtr, NodePtr argListNodePtr, NodePtr methodDecNodePtr, Boolean isConstructor, SymbolTablePtr symbolTablePtr){ NodePtr parameterListNodePtr = NULL; NodePtr argumentNodePtr = NULL; NodePtr parameterNodePtr = NULL; NodePtr methodNameNodePtr = NULL; int i; if (methodDecNodePtr == NULL) { if (argListNodePtr != NULL) { for (i = 0; i < argListNodePtr->numberOfChildren; i ++) { CheckExpression(classNodePtr, argListNodePtr->children[i], symbolTablePtr); } } } else { if (isConstructor == TRUE) { methodNameNodePtr = methodDecNodePtr->children[0]; parameterListNodePtr = methodDecNodePtr->children[1]; } else { methodNameNodePtr = methodDecNodePtr->children[1]; parameterListNodePtr = methodDecNodePtr->children[2]; } if (parameterListNodePtr->numberOfChildren == 1) { if (argListNodePtr->numberOfChildren > 1) { for (i = 0; i < argListNodePtr->numberOfChildren - 1; i ++) { CheckExpression(classNodePtr, argListNodePtr->children[i], symbolTablePtr); } } } else { if (argListNodePtr->numberOfChildren > 1) { for (i = 0; i < argListNodePtr->numberOfChildren - 1; i ++) { argumentNodePtr = argListNodePtr->children[i]; CheckExpression(classNodePtr, argumentNodePtr, symbolTablePtr); if (i < parameterListNodePtr->numberOfChildren - 1) { parameterNodePtr = parameterListNodePtr->children[i]->children[1]; if (parameterNodePtr->typePtr != argumentNodePtr->typePtr) { ReportError(ERROR_CONFLICTING_ARG_TYPE, argumentNodePtr->typePtr->id, argumentNodePtr->lineNumber, argumentNodePtr->columnNumber); } } } } } if (argListNodePtr->numberOfChildren < parameterListNodePtr->numberOfChildren) { ReportError(ERROR_TOO_FEW_ARGUMENTS, methodNameNodePtr->info.lexeme, argListNodePtr->lineNumber, argListNodePtr->columnNumber); } else if (argListNodePtr->numberOfChildren > parameterListNodePtr->numberOfChildren) { ReportError(ERROR_TOO_MANY_ARGUMENTS, methodNameNodePtr->info.lexeme, argListNodePtr->lineNumber, argListNodePtr->columnNumber); } }}static Boolean IsRelationExpression(NodePtr expNodePtr){ if ((strcmp(expNodePtr->info.lexeme, STRING_EQUAL_EQUAL) == 0) || (strcmp(expNodePtr->info.lexeme, STRING_NOT_EQUAL) == 0) || (strcmp(expNodePtr->info.lexeme, STRING_LESS_EQUAL) == 0) || (strcmp(expNodePtr->info.lexeme, STRING_GREATER_EQUAL) == 0) || (strcmp(expNodePtr->info.lexeme, STRING_LESS) == 0) || (strcmp(expNodePtr->info.lexeme, STRING_GREATER) == 0)) { return(TRUE); } else { return(FALSE); }}static Boolean IsCheckedMethodDec(NodePtr methodDecNodePtr){ if (methodDecNodePtr->typePtr != NULL) { return(TRUE); } else { return(FALSE); }}static Boolean IsPrimitiveType(ElementPtr typePtr){ if ((typePtr == intTypePtr) || (typePtr == voidTypePtr) || (typePtr == refTypePtr) || (typePtr == unknownTypePtr)) { return(TRUE); } else { return(FALSE); }}static Boolean IsEquivalentType(ElementPtr typePtr1, ElementPtr typePtr2){ if (typePtr1 == typePtr2) { return(TRUE); } else { if (typePtr1 == refTypePtr) { if (IsPrimitiveType(typePtr2) == TRUE) { return(FALSE); } else { return(TRUE); } } else if (typePtr2 == refTypePtr) { if (IsPrimitiveType(typePtr1) == TRUE) { return(FALSE); } else { return(TRUE); } } else { return(FALSE); } }}static Boolean DefinedBeforeUse(NodePtr nodePtr, ElementPtr typePtr){ NodePtr classNodePtr = NULL; classNodePtr = ClassNodeOfType(typePtr); if (classNodePtr == NULL) { return(FALSE); } if (classNodePtr->children[0]->lineNumber < nodePtr->lineNumber) { return(TRUE); } else { return(FALSE); }}static int DimensionOfType(ElementPtr typePtr){ int dimension; ElementPtr parentTypePtr = NULL; dimension = 0; parentTypePtr = typePtr->typePtr; while (parentTypePtr != NULL) { dimension ++; parentTypePtr = parentTypePtr->typePtr; } #ifdef DEBUG printf("DimensionOfType returns %d\n", dimension); #endif return(dimension);}static ElementPtr TypeOfArrayAcess(ElementPtr typePtr, int dimension){ ElementPtr parentTypePtr = NULL; parentTypePtr = typePtr; while (dimension > 0) { parentTypePtr = parentTypePtr->typePtr; dimension --; } #ifdef DEBUG printf("TypeOfArrayAcess returns %x\n", parentTypePtr); #endif return(parentTypePtr);}static ElementPtr GetNewArrayType(NodePtr expNodePtr){ NodePtr idNodePtr = NULL; int dimension; String typeName = NULL; int i; idNodePtr = expNodePtr->children[0]; dimension = expNodePtr->children[1]->numberOfChildren; if (expNodePtr->children[2] != NULL) { dimension += expNodePtr->children[2]->numberOfChildren; } typeName = (String)malloc(strlen(idNodePtr->info.lexeme) + 2 * dimension + 1); strcpy(typeName, idNodePtr->info.lexeme); for (i = 0; i < dimension; i ++) { strcat(typeName, STRING_SQUARE_BRACKETS); } #ifdef DEBUG printf("In GetNewArrayType(), check type `%s'...\n", typeName); #endif expNodePtr->typePtr = Lookup(typeSymbolTable, typeName); if (expNodePtr->typePtr == NULL) { ReportError(ERROR_UNDEFINED_TYPE, typeName, expNodePtr->lineNumber, expNodePtr->columnNumber); expNodePtr->typePtr = unknownTypePtr; } free(typeName); return(expNodePtr->typePtr);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -