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

📄 semanticchecker.c

📁 decafc的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************** * File name:	semanticChecker.c					    * * Description: semantic checker for decafc				    * * Input:       none							    * * Output:      none							    * * Author:      Luojian Chen                                                * * Date:        April 16, 1997						    * ****************************************************************************/#include "semanticChecker.h"extern SymbolTablePtr	typeSymbolTable;extern NodePtr		rootNodePtr;extern NodePtr		mainMethodDecNodePtr;extern ElementPtr	Insert(SymbolTablePtr, String, int, ElementPtr);extern ElementPtr	Lookup(SymbolTablePtr, String);extern void		DisplaySymbolTable(SymbolTablePtr);extern void		ReportError(ErrorIndex, String, int, int);ElementPtr	intTypePtr = NULL;ElementPtr	voidTypePtr = NULL;ElementPtr	refTypePtr = NULL;ElementPtr	unknownTypePtr = NULL;NodePtr		mainClassDecNodePtr = NULL;void	SemanticCheck(NodePtr);void	CreateNewArrayType(NodePtr);NodePtr	ClassNodeOfType(ElementPtr);Boolean	IsArrayType(ElementPtr);static ElementPtr	currentMethodReturnTypePtr = NULL;static NodePtr		currentMethodDecNodePtr = NULL;static NodePtr		lastNameNodePtr = NULL;static void		CheckClassDec(NodePtr);static void		CheckVarDecList(NodePtr, SymbolTablePtr, Boolean);static void		CheckConstructorDec(NodePtr, NodePtr);static void		CheckMethodDec(NodePtr, NodePtr);static void		CheckVarDec(NodePtr, SymbolTablePtr, int, Boolean);static ElementPtr	CheckReturnType(NodePtr);static void		CheckParameterList(NodePtr, SymbolTablePtr);static void		CheckBlock(NodePtr, NodePtr);static void		CheckStatementList(NodePtr, NodePtr, SymbolTablePtr);static void		CheckStatement(NodePtr, NodePtr, SymbolTablePtr);static void		CheckAssignmentStatement(NodePtr,						 NodePtr,						 SymbolTablePtr);static ElementPtr 	CheckName(NodePtr, NodePtr, Boolean, SymbolTablePtr);static ElementPtr 	CheckExpression(NodePtr, NodePtr, SymbolTablePtr);static ElementPtr	CheckIdentifier(NodePtr, 					NodePtr,					Boolean,					SymbolTablePtr);static ElementPtr	CheckArrayAccess(NodePtr,					 NodePtr,					 Boolean,					 SymbolTablePtr);static ElementPtr	CheckNewExpression(NodePtr,					   NodePtr,					   SymbolTablePtr);static ElementPtr	CheckFunctionCall(NodePtr, NodePtr, SymbolTablePtr);static ElementPtr	CheckMethodCall(NodePtr, 					NodePtr,					Boolean,					SymbolTablePtr,					String *,					NodePtr *);static ElementPtr	CheckMethodName(NodePtr, NodePtr, String *, NodePtr *);static void		CheckArgList(NodePtr,				     NodePtr,				     NodePtr,				     Boolean,				     SymbolTablePtr);static void		CheckExpressionMeaning(NodePtr);static Boolean		IsRelationExpression(NodePtr);static Boolean		IsCheckedMethodDec(NodePtr);static Boolean		IsPrimitiveType(ElementPtr);static Boolean		IsEquivalentType(ElementPtr, ElementPtr);static Boolean		DefinedBeforeUse(NodePtr, ElementPtr);static int		DimensionOfType(ElementPtr);static ElementPtr	TypeOfArrayAcess(ElementPtr, int);static ElementPtr	GetNewArrayType(NodePtr);void SemanticCheck(NodePtr	rootNodePtr){	int	i;	NodePtr	classNodePtr = NULL;	if (rootNodePtr == NULL) {		return;	}	for (i = 0; i < rootNodePtr->children[0]->numberOfChildren; i ++) {		classNodePtr = rootNodePtr->children[0]->children[i];		CheckClassDec(classNodePtr);		#ifdef DEBUG		printf("In SemanticCheck, symbol table for class %s:\n",		       classNodePtr->children[0]->info.lexeme);		DisplaySymbolTable(classNodePtr->info.symbolTablePtr);		#endif	}}void CreateNewArrayType(NodePtr	nodePtr){	NodePtr		childNodePtr = NULL;	String		typeName = NULL;	ElementPtr	typePtr = NULL;	childNodePtr = nodePtr->children[0];	if (childNodePtr->numberOfChildren == 0) {		childNodePtr->typePtr = Lookup(typeSymbolTable,					       childNodePtr->info.lexeme);		if (childNodePtr->typePtr == NULL) {		  ReportError(ERROR_UNDEFINED_TYPE,			      childNodePtr->info.lexeme,			      childNodePtr->lineNumber,			      childNodePtr->columnNumber);		  childNodePtr->typePtr = unknownTypePtr;		  nodePtr->typePtr = unknownTypePtr;		} else {		  typePtr = childNodePtr->typePtr;		  if (IsPrimitiveType(typePtr) == FALSE) {		    if (DefinedBeforeUse(nodePtr, typePtr) ==			FALSE) {		      ReportError(ERRROR_TYPE_USED_BEFORE_DEFINITION,				  childNodePtr->info.lexeme,				  childNodePtr->lineNumber,				  childNodePtr->columnNumber);		    }		  }		  typeName =		   (String)malloc(strlen(childNodePtr->info.lexeme) + 2 + 1);		  strcpy(typeName, childNodePtr->info.lexeme);		  strcat(typeName, STRING_SQUARE_BRACKETS);		  nodePtr->info.lexeme = typeName;		  nodePtr->typePtr = Lookup(typeSymbolTable, typeName);		  if (nodePtr->typePtr == NULL) {		    nodePtr->typePtr =			Insert(typeSymbolTable, typeName, 0, typePtr);		  }		}	} else {		CreateNewArrayType(childNodePtr);		typePtr = childNodePtr->typePtr;		if (typePtr == unknownTypePtr) {		  nodePtr->typePtr = unknownTypePtr;		} else {		  typeName = (String)malloc(strlen(typePtr->id) + 2 + 1);		  strcpy(typeName, typePtr->id);		  strcat(typeName, STRING_SQUARE_BRACKETS);		  nodePtr->info.lexeme = typeName;		  nodePtr->typePtr = Lookup(typeSymbolTable, typeName);		  if (nodePtr->typePtr == NULL) {		    nodePtr->typePtr =			Insert(typeSymbolTable, typeName, 0, typePtr);		  }		}	}}NodePtr ClassNodeOfType(ElementPtr	typePtr){	int	i;	NodePtr	classDecListNodePtr = NULL;	NodePtr	classDecNodePtr = NULL;	classDecListNodePtr = rootNodePtr->children[0];	for (i = 0; i < classDecListNodePtr->numberOfChildren; i ++) {		classDecNodePtr = classDecListNodePtr->children[i];		if (classDecNodePtr->typePtr == typePtr) {			return(classDecNodePtr);		}	}	return(NULL);}Boolean IsArrayType(ElementPtr	typePtr){	if (typePtr->typePtr != NULL) {		return(TRUE);	} else {		return(FALSE);	}}static void CheckClassDec(NodePtr	classNodePtr){	int	i;	NodePtr	classBodyNodePtr = NULL;	NodePtr	methodDecNodePtr = NULL;	if (classNodePtr == NULL) {		return;	}	classBodyNodePtr = classNodePtr->children[1];	CheckVarDecList(classBodyNodePtr->children[0],			classNodePtr->info.symbolTablePtr,			TRUE);	CheckConstructorDec(classNodePtr, classBodyNodePtr->children[1]);	if (classBodyNodePtr->children[2] != NULL) {		for (i = 0;		     i < classBodyNodePtr->children[2]->numberOfChildren;		     i ++) {		  methodDecNodePtr = classBodyNodePtr->children[2]->children[i];		  CheckMethodDec(classNodePtr, methodDecNodePtr);		}	}}static void CheckVarDecList(NodePtr		varDecListNodePtr,			    SymbolTablePtr	symbolTablePtr,			    Boolean		isClassVar){	int	i;	NodePtr	varDecNodePtr = NULL;	if (varDecListNodePtr == NULL) {		return;	}	for (i = 0; i < varDecListNodePtr->numberOfChildren; i ++) {		varDecNodePtr = varDecListNodePtr->children[i];		if (varDecNodePtr == NULL) {			continue;		}		CheckVarDec(varDecNodePtr, symbolTablePtr, i, isClassVar);	}}static void CheckConstructorDec(NodePtr	classNodePtr,				NodePtr	constructorNodePtr){	String	className = NULL;	if (constructorNodePtr == NULL) {		return;	}	className = classNodePtr->children[0]->info.lexeme;	currentMethodReturnTypePtr = classNodePtr->typePtr;	if ((className == NULL) ||	    (strcmp(className,		    constructorNodePtr->children[0]->info.lexeme) != 0)) {	ReportError(ERROR_BAD_CONSTRUCTOR_NAME,		    constructorNodePtr->children[0]->info.lexeme,		    constructorNodePtr->children[0]->lineNumber,		    constructorNodePtr->children[0]->columnNumber);	}	CheckParameterList(constructorNodePtr->children[1],			   constructorNodePtr->info.symbolTablePtr);	CheckBlock(classNodePtr, constructorNodePtr->children[2]);}static void CheckMethodDec(NodePtr	classNodePtr,			   NodePtr	methodDecNodePtr){	String	className = NULL;	if (methodDecNodePtr == NULL) {		return;	}	if (methodDecNodePtr == mainMethodDecNodePtr) {		mainClassDecNodePtr = classNodePtr;	}	className = classNodePtr->children[0]->info.lexeme;	#ifdef DEBUG	printf("In CheckMethodDec(), symbol table is:\n");	DisplaySymbolTable(methodDecNodePtr->info.symbolTablePtr);	#endif	if ((className != NULL) &&	    (strcmp(className,		    methodDecNodePtr->children[1]->info.lexeme) == 0)) {		ReportError(ERROR_BAD_METHOD_NAME,			    methodDecNodePtr->children[1]->info.lexeme,			    methodDecNodePtr->children[1]->lineNumber,			    methodDecNodePtr->children[1]->columnNumber);	}	if (IsCheckedMethodDec(methodDecNodePtr) == FALSE) {		methodDecNodePtr->typePtr =		  CheckReturnType(methodDecNodePtr->children[0]);		CheckParameterList(methodDecNodePtr->children[2],				   methodDecNodePtr->info.symbolTablePtr);	}	currentMethodReturnTypePtr = methodDecNodePtr->typePtr;	CheckBlock(classNodePtr, methodDecNodePtr->children[3]);}static void CheckVarDec(NodePtr		varDecNodePtr,			SymbolTablePtr	symbolTablePtr,			int		offset,			Boolean		isClassVar){	NodePtr		typeNodePtr = NULL;	NodePtr		varNodePtr = NULL;	ElementPtr	elementPtr = NULL;	if (varDecNodePtr == NULL) {		return;	}	typeNodePtr = varDecNodePtr->children[0];	varNodePtr = varDecNodePtr->children[1];	if (typeNodePtr->numberOfChildren > 0) {		CreateNewArrayType(typeNodePtr);		varNodePtr->typePtr = typeNodePtr->typePtr;		elementPtr = Lookup(symbolTablePtr, varNodePtr->info.lexeme);		elementPtr->typePtr = varNodePtr->typePtr;	} else {		#ifdef DEBUG		printf("In CheckVarDec(), Lookup type `%s'\n",		       typeNodePtr->info.lexeme);		#endif		typeNodePtr->typePtr =			Lookup(typeSymbolTable, typeNodePtr->info.lexeme);		if (typeNodePtr->typePtr == NULL) {		  ReportError(ERROR_UNDEFINED_TYPE,			      typeNodePtr->info.lexeme,			      typeNodePtr->lineNumber,			      typeNodePtr->columnNumber);		  varNodePtr->typePtr = unknownTypePtr;		} else {		  varNodePtr->typePtr = typeNodePtr->typePtr;		  if (IsPrimitiveType(typeNodePtr->typePtr) == FALSE) {		    if (DefinedBeforeUse(typeNodePtr,					 typeNodePtr->typePtr) == FALSE) {		      ReportError(ERRROR_TYPE_USED_BEFORE_DEFINITION,				  typeNodePtr->info.lexeme,				  typeNodePtr->lineNumber,				  typeNodePtr->columnNumber);		    }		  }		}		elementPtr = Lookup(symbolTablePtr, varNodePtr->info.lexeme);		elementPtr->typePtr = varNodePtr->typePtr;		/*		if (isClassVar == TRUE) {		  elementPtr->offset = offset + FIRST_CLASS_VAR_OFFSET;		} else {		  elementPtr->offset = offset - 1 + FIRST_LOCAL_VAR_OFFSET;		}		*/	}}static ElementPtr CheckReturnType(NodePtr	typeNodePtr){	if (typeNodePtr == NULL) {		return;	}	if (typeNodePtr->numberOfChildren > 0) {		CreateNewArrayType(typeNodePtr);	} else {		#ifdef DEBUG		printf("In CheckReturnType(), Lookup type `%s'\n",		       typeNodePtr->info.lexeme);		#endif		typeNodePtr->typePtr =			Lookup(typeSymbolTable, typeNodePtr->info.lexeme);		if (typeNodePtr->typePtr == NULL) {		  ReportError(ERROR_UNDEFINED_TYPE,			      typeNodePtr->info.lexeme,			      typeNodePtr->lineNumber,			      typeNodePtr->columnNumber);		  typeNodePtr->typePtr = unknownTypePtr;		} else {		  if (IsPrimitiveType(typeNodePtr->typePtr) == FALSE) {		    if (DefinedBeforeUse(typeNodePtr,					 typeNodePtr->typePtr) == FALSE) {		      ReportError(ERRROR_TYPE_USED_BEFORE_DEFINITION,				  typeNodePtr->info.lexeme,				  typeNodePtr->lineNumber,				  typeNodePtr->columnNumber);		    }		  }		}	}	return(typeNodePtr->typePtr);}static void CheckParameterList(NodePtr		parameterListNodePtr,			       SymbolTablePtr	symbolTablePtr){	int	i;	if (parameterListNodePtr == NULL) {		return;	}	#ifdef DEBUG	printf("In CheckParameterList(), symbol table is:\n");	DisplaySymbolTable(symbolTablePtr);	#endif	for (i = 0; i < parameterListNodePtr->numberOfChildren; i++) {		if (parameterListNodePtr->children[i] == NULL) {			continue;		}		CheckVarDec(parameterListNodePtr->children[i],			    symbolTablePtr,			    i,			    FALSE);	}}static void CheckBlock(NodePtr	classNodePtr,		       NodePtr	blockNodePtr){	if (blockNodePtr == NULL) {		return;	}	CheckVarDecList(blockNodePtr->children[0],			blockNodePtr->info.symbolTablePtr,			FALSE);	CheckStatementList(classNodePtr, blockNodePtr->children[1],			   blockNodePtr->info.symbolTablePtr);}static void CheckStatementList(NodePtr		classNodePtr,			       NodePtr		stmtListNodePtr,			       SymbolTablePtr	symbolTablePtr){	int	i;	NodePtr	statementNodePtr = NULL;	if (stmtListNodePtr == NULL) {		return;	}	for (i = 0; i < stmtListNodePtr->numberOfChildren; i ++) {		statementNodePtr = stmtListNodePtr->children[i];		CheckStatement(classNodePtr, statementNodePtr, symbolTablePtr);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -