⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 semanticchecker.c

📁 decafc的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	}}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 + -