示例#1
0
/**
 * Checks assignment type1 statements for type errors.
 */
void checkAssignmentType1()
{
	// Current receives current node at stmt.
	astTree stmtNode = currentASTNode->childNode->childNode;
	astTree idNode = stmtNode->childNode;
	char* idName = idNode->data.token_data;
	token type = checkTypeInSymbolTable(idName,idNode->data.lineNumber,idNode->data.charNumber);
	if(type == INVALID)
		return;
	astTree rhsNodes = stmtNode->sisterNode;
	switch(rhsNodes->ruleNum)
	{
		case 26: checkArithmeticExpression(idName,type,rhsNodes);break;// Arithmetic Expression
		case 27: checkSizeExpression(type,rhsNodes);break;// Size Expression
		case 28: break; // Function call
	}
}
std::shared_ptr<inter::LogicalExpression> SemanticChecker::checkLogicalExpression(inter::ScopePrototype & scopePrototype, syntax::LogicalExpression & condition)
{
    CHECK_FAIL(nullptr);

    std::shared_ptr<inter::LogicalExpression> obj = std::make_shared<inter::LogicalExpression>();

    obj->operation = condition._operation;
    obj->negated = condition._isNegated;

    for (auto & operand : condition._operands)
    {
        if (operand->getType() == syntax::Node::Type::LogicalExpression)
        {
            obj->operands.push_back(checkLogicalExpression(scopePrototype, *(static_cast<syntax::LogicalExpression*>(operand.get()))));
        }
        else if (operand->getType() == syntax::Node::Type::Variable)
        {
            obj->operands.push_back(checkVariable(scopePrototype, *(static_cast<syntax::Variable*>(operand.get()))));
        }
        else if (operand->getType() == syntax::Node::Type::Call)
        {
            obj->operands.push_back(checkFunctionCall(scopePrototype, *(static_cast<syntax::Call*>(operand.get()))));
        }
        else if (operand->getType() == syntax::Node::Type::ArithmeticExpression)
        {
            obj->operands.push_back(checkArithmeticExpression(scopePrototype, *(static_cast<syntax::ArithmeticExpression*>(operand.get()))));
        }
        else
        {
            typedef syntax::Node::Type Type;
            Type nodeType = operand->getType();
            if (nodeType == Type::Number)
                obj->operands.push_back(this->checkLiteral(scopePrototype, *(static_cast<syntax::Literal*>(operand.get())), "float"));
            else if (nodeType == Type::Bool)
                obj->operands.push_back(this->checkLiteral(scopePrototype, *(static_cast<syntax::Literal*>(operand.get())), "bool"));
            else
            {
                MessageHandler::error(std::string("Invalid logical expression operand!"));
                FAIL;
                return nullptr;
            }
        }
    }

    return obj;
}
示例#3
0
/**
 * Checks an arithmetic expression and reports type errors
 * if any.
 * @param idName
 * @param type
 * @param nodes
 */
void checkArithmeticExpression(char* idName, token type, astTree nodes)
{
	int flag = 0;
	int lowPrecedenceOnly = 0; // For Strings and Matrix
	token acceptedType = type;
	astTree expression = nodes->childNode;
	int acceptedRows = 0;
	int acceptedCols = 0;
	int stringLength = 0;
	int assignMatrix = 0; // Whether to enter the size in MatrixTable or not.
	if(acceptedType == MATRIX)
	{
		// Find the size of the LHS matrix.
		astTree temp = expression->childNode->childNode->childNode->childNode;
		matrixSizes matrix = findMatrixInMatrixTable(idName,0,temp->data.lineNumber,temp->data.charNumber);
		if(matrix == NULL)
		{
			// The name wasn't found.
			assignMatrix = 1;
		}
		else
		{
			acceptedRows = matrix->rows;
			acceptedCols = matrix->columns;
		}
	}
	while(expression != NULL)
	{
		astTree termID = expression->childNode;
		while(termID != NULL)
		{
			astTree factor = termID->childNode;
			if(factor->ruleNum == 48)
			{
				// It is a variable. Check it's type.
				astTree typeNode = factor->childNode;
				if(typeNode->ruleNum == 65)
				{
					// // Check if it is a matrix element.
					if(typeNode->childNode->sisterNode->ruleNum == 77)
					{
						if(acceptedType == RNUM)
						{
							flag = 1;
						}
						else if(acceptedType != NUM)
						{
							typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
						}
					}
					else if(typeNode->childNode->sisterNode->ruleNum == 78)
					{
						token idNode = checkTypeInSymbolTable(typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
						if(idNode == INVALID)
							return;
						// If it is an error, ignore this statement and move on after reporting the error.
						if(acceptedType == RNUM)
						{
							if(idNode == NUM)
							{
								flag = 1;
							}
							else if(idNode != RNUM)
							{
								typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
							}
						}
						else if(acceptedType == NUM)
						{
							if(idNode != NUM)
								typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
						}
						else if(acceptedType == STR)
						{
							if(idNode != STR)
							{
								typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
							}
							else
							{
								int length= getSize(typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber,stList,0);
								if(length == 0)
								{
									// No string found error.
									return;
								}
								stringLength += length;
								lowPrecedenceOnly = 1;
							}
						}
						else if(acceptedType == MATRIX)
						{
							if(idNode != MATRIX)
							{
								typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
							}
							else
							{
								// Check if their sizes match.
								matrixSizes rhsMatrix = findMatrixInMatrixTable(typeNode->childNode->data.token_data,1,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
								if(rhsMatrix == NULL)
								{
									// Matrix hasn't been defined.
									return;
								}
								if((acceptedRows != 0 && acceptedCols != 0) && (rhsMatrix->rows != acceptedRows || rhsMatrix->columns != acceptedCols))
								{
									// Sizes of matrix do not match.
									typeError(5,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
									return;
								}
								else if(acceptedRows == 0 && acceptedCols == 0)
								{
									acceptedRows = rhsMatrix->rows;
									acceptedCols = rhsMatrix->columns;
								}
								lowPrecedenceOnly = 1;
							}
						}
					}
				}
				else if(typeNode->ruleNum == 66)
				{
					// It is a NUM type
					if(acceptedType == RNUM)
						flag = 1;
					else if(acceptedType != NUM)
					{
						typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
					}
				}
				else if(typeNode->ruleNum == 67)
				{
					if(acceptedType != RNUM)
						typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
				}
				else if(typeNode->ruleNum == 68)
				{
					if(acceptedType != STR)
					{
						typeError(4,typeNode->childNode->data.token_data,typeNode->childNode->data.lineNumber,typeNode->childNode->data.charNumber);
					}
					else
					{
						int length = strlen(typeNode->childNode->data.token_data);
						stringLength += length;
						lowPrecedenceOnly = 1;
					}
				}
				else if(typeNode->ruleNum == 69)
				{
					// Matrix assignment.
				}
				else
				{
					// Some weird error.
					fprintf(stderr, "You shouldn't have got here.\n");
					exit(0);
				}
			}
			else
			{
				// rule no 53- factor -> (arithmeticExp)
				checkArithmeticExpression(idName,type,factor);
			}
			termID = termID->childNode->sisterNode;
			if(termID->ruleNum == 54)
				termID = NULL;
			else
			{
				if(termID->childNode->ruleNum == 58)
					flag = 0;
				termID = termID->childNode->sisterNode;
			}
			if(lowPrecedenceOnly == 1 || acceptedType == STR || acceptedType == MATRIX)
			{
				if(termID != NULL)
					typeError(6,termID->childNode->data.token_data,termID->childNode->childNode->data.lineNumber,termID->childNode->childNode->data.charNumber);
			}
		}
		expression = expression->childNode->sisterNode;
		if(expression->ruleNum == 51)
		{
			expression = NULL;
		}
		else
		{
			if(acceptedType == STR && expression->childNode->ruleNum == 56)
				typeError(7,expression->childNode->data.token_data,expression->childNode->childNode->data.lineNumber,expression->childNode->childNode->data.charNumber);
			expression = expression->childNode->sisterNode;
		}
		if(flag == 1)
		{
			astTree parentNode = expression->parentNode;
			while(parentNode->data.flag)
				parentNode = parentNode->childNode;
			typeError(8,parentNode->data.token_data,parentNode->data.lineNumber,parentNode->data.charNumber);
			return;
		}
	}
	if(assignMatrix)
	{
		fillDataInMatrixTable(idName,acceptedRows,acceptedCols);
	}
	if(acceptedType == STR && stringLength > 0)
	{
		fillDataInStringTable(idName,stringLength);
	}
}