void checkParameterPassing(Parameter* formalParameter, AST_NODE* actualParameter) { while (formalParameter && actualParameter) { if (actualParameter->nodeType == EXPR_NODE) { processExprNode(actualParameter); if (formalParameter->type->kind == ARRAY_TYPE_DESCRIPTOR) { printErrorMsg(actualParameter, PASS_SCALAR_TO_ARRAY); } } else if (actualParameter->nodeType == CONST_VALUE_NODE) { } else if (actualParameter->nodeType == STMT_NODE) { checkFunctionCall(actualParameter); SymbolTableEntry *entry = retrieveSymbol(actualParameter->semantic_value.identifierSemanticValue.identifierName); if (entry != NULL) { if (formalParameter->type->kind == ARRAY_TYPE_DESCRIPTOR ) { printErrorMsg(actualParameter, PASS_SCALAR_TO_ARRAY); } else { if (getDataType(formalParameter->type) != getDataType(entry->attribute->attr.typeDescriptor)) { printErrorMsgSpecial(actualParameter, formalParameter->parameterName, PARAMETER_TYPE_UNMATCH); } } } } else if (actualParameter->nodeType == IDENTIFIER_NODE) { checkParameterIdentifier(formalParameter, actualParameter); } formalParameter = formalParameter->next; actualParameter = actualParameter->rightSibling; } }
void enterIntoHashChain (int hashIndex, SymbolTableEntry *entry) { SymbolTableEntry *current = symbolTable.hashTable[hashIndex]; SymbolTableEntry *outerLevel = retrieveSymbol(entry->name); SymbolTableEntry *scope = symbolTable.scopeDisplay[entry->nestingLevel]; while (scope->nextInSameLevel != NULL) scope = scope->nextInSameLevel; entry->sameNameInOuterLevel = outerLevel; scope->nextInSameLevel = entry; while (current != NULL) { if (current->nextInHashChain == NULL) { entry->nextInHashChain = current->nextInHashChain; current->nextInHashChain = entry; entry->prevInHashChain = current; break; } else if (current->nextInHashChain->nestingLevel <= entry->nestingLevel) { entry->nextInHashChain = current->nextInHashChain; current->nextInHashChain->prevInHashChain = entry; current->nextInHashChain = entry; entry->prevInHashChain = current; break; } current = current->nextInHashChain; } }
int declaredLocally(char* symbolName) { //this function will be programed when needed. symbolTableEntry* sym = retrieveSymbol(symbolName); if(sym == NULL)return 0; return (sym.nestingLevel == symbolTable.currentLevel); }
//remove the symbol from the current scope void removeSymbol (char *symbolName) { SymbolTableEntry *current = retrieveSymbol(symbolName); if (current != NULL) { if (current->prevInHashChain != NULL) current->prevInHashChain->nextInHashChain = current->nextInHashChain; if (current->nextInHashChain != NULL) current->nextInHashChain->prevInHashChain = current->prevInHashChain; } }
void processVariableLValue(AST_NODE* idNode) { SymbolTableEntry *entry = retrieveSymbol(idNode->semantic_value.identifierSemanticValue.identifierName); DATA_TYPE type = retrieveType(idNode->semantic_value.identifierSemanticValue.identifierName); if (entry == NULL) { printErrorMsg(idNode, SYMBOL_UNDECLARED); } else if (entry->attribute->attributeKind == FUNCTION_SIGNATURE) { printErrorMsg(idNode, IS_FUNCTION_NOT_VARIABLE); } else if (entry->attribute->attributeKind == TYPE_ATTRIBUTE) { printErrorMsg(idNode, IS_TYPE_NOT_VARIABLE); } else if (type == VOID_TYPE) { printErrorMsg(idNode, NOT_ASSIGNABLE); } }
void checkIDNode(AST_NODE *idNode){ SymbolTableEntry *entry = retrieveSymbol(idNode->semantic_value.identifierSemanticValue.identifierName); idNode->dataType = retrieveType(idNode->semantic_value.identifierSemanticValue.identifierName); if (entry == NULL) { printErrorMsg(idNode, SYMBOL_UNDECLARED); } else if (entry->attribute->attributeKind == FUNCTION_SIGNATURE) { printErrorMsg(idNode, IS_FUNCTION_NOT_VARIABLE); } else if (entry->attribute->attributeKind == TYPE_ATTRIBUTE) { printErrorMsg(idNode, IS_TYPE_NOT_VARIABLE); } else if (idNode->semantic_value.identifierSemanticValue.kind == ARRAY_ID && entry->attribute->attr.typeDescriptor->kind == SCALAR_TYPE_DESCRIPTOR) { printErrorMsg(idNode, NOT_ARRAY); } else if (idNode->semantic_value.identifierSemanticValue.kind == ARRAY_ID) { checkSubscript(idNode); } }
int checkSubscript(AST_NODE *idNode) { AST_NODE *dimNode = idNode->child; SymbolTableEntry *entry = retrieveSymbol(idNode->semantic_value.identifierSemanticValue.identifierName); int dim = 0; while (dimNode) { processExprRelatedNode(dimNode); evaluateExprValue(dimNode); if (dimNode->dataType != INT_TYPE) { printErrorMsg(dimNode, ARRAY_SUBSCRIPT_NOT_INT); } ++dim; dimNode = dimNode->rightSibling; } if (dim != entry->attribute->attr.typeDescriptor->properties.arrayProperties.dimension) { printErrorMsg(idNode, INCOMPATIBLE_ARRAY_DIMENSION); } }
void checkFunctionCall(AST_NODE* functionCallNode) { AST_NODE *idNode = functionCallNode->child; AST_NODE *firstParamNode = idNode->rightSibling; AST_NODE *paramNode = NULL; int actualParamNum = 0; int paramNum = 0; functionCallNode->dataType = ERROR_TYPE; if (strcmp(idNode->semantic_value.identifierSemanticValue.identifierName, "write") == 0) { checkWriteFunction(functionCallNode); } else if(strcmp(idNode->semantic_value.identifierSemanticValue.identifierName, "read") == 0 || strcmp(idNode->semantic_value.identifierSemanticValue.identifierName, "fread") == 0) { } else { SymbolTableEntry *entry = retrieveSymbol(idNode->semantic_value.identifierSemanticValue.identifierName); functionCallNode->dataType = retrieveType(idNode->semantic_value.identifierSemanticValue.identifierName); if (entry == NULL) { printErrorMsg(idNode, SYMBOL_UNDECLARED); } else if (entry->attribute->attributeKind != FUNCTION_SIGNATURE) { printErrorMsg(idNode, NOT_FUNCTION_NAME); } else { actualParamNum = entry->attribute->attr.functionSignature->parametersCount; if (actualParamNum > 0 && firstParamNode->nodeType == NUL_NODE) { printErrorMsg(idNode, TOO_FEW_ARGUMENTS); } else { firstParamNode = firstParamNode->child; paramNode = firstParamNode; while (firstParamNode) { firstParamNode = firstParamNode->rightSibling; ++paramNum; } if (paramNum < actualParamNum) { printErrorMsg(idNode, TOO_FEW_ARGUMENTS); } else if (paramNum > actualParamNum) { printErrorMsg(idNode, TOO_MANY_ARGUMENTS); } else { checkParameterPassing(entry->attribute->attr.functionSignature->parameterList, paramNode); } } } } }
void checkReturnStmt(AST_NODE* returnNode) { AST_NODE *exprNode = returnNode->child; switch(exprNode->nodeType){ case IDENTIFIER_NODE: { SymbolTableEntry *entry = retrieveSymbol(exprNode->semantic_value.identifierSemanticValue.identifierName); if (entry == NULL) { printErrorMsg(exprNode, SYMBOL_UNDECLARED); } else if (exprNode->semantic_value.identifierSemanticValue.kind == ARRAY_ID) { checkSubscript(exprNode); } else if (exprNode->semantic_value.identifierSemanticValue.kind == NORMAL_ID && entry->attribute->attr.typeDescriptor->kind == ARRAY_TYPE_DESCRIPTOR) { printErrorMsg(exprNode, RETURN_ARRAY); } break; } case EXPR_NODE: case CONST_VALUE_NODE: { processExprRelatedNode(exprNode); //get function node AST_NODE *funNode = returnNode; while (funNode->nodeType != DECLARATION_NODE || funNode->semantic_value.declSemanticValue.kind != FUNCTION_DECL) { funNode = funNode->parent; } if (exprNode->dataType != retrieveType(funNode->child->semantic_value.identifierSemanticValue.identifierName)) { printErrorMsg(exprNode, RETURN_TYPE_UNMATCH); } break; } default: { assert(0); } } }
void checkParameterIdentifier(Parameter *formalParameter, AST_NODE *actualParameter) { SymbolTableEntry *entry = retrieveSymbol(actualParameter->semantic_value.identifierSemanticValue.identifierName); if (entry == NULL) { printErrorMsg(actualParameter, SYMBOL_UNDECLARED); } else if (entry->attribute->attributeKind == FUNCTION_SIGNATURE || entry->attribute->attributeKind == TYPE_ATTRIBUTE) { printErrorMsgSpecial(actualParameter, formalParameter->parameterName, PARAMETER_TYPE_UNMATCH); } else { if (formalParameter->type->kind == ARRAY_TYPE_DESCRIPTOR && entry->attribute->attr.typeDescriptor->kind == SCALAR_TYPE_DESCRIPTOR) { printErrorMsg(actualParameter, PASS_SCALAR_TO_ARRAY); } else if (formalParameter->type->kind == SCALAR_TYPE_DESCRIPTOR && entry->attribute->attr.typeDescriptor->kind == ARRAY_TYPE_DESCRIPTOR) { printErrorMsg(actualParameter, PASS_ARRAY_TO_SCALAR); } else { if (getDataType(formalParameter->type) != getDataType(entry->attribute->attr.typeDescriptor)) { printErrorMsgSpecial(actualParameter, formalParameter->parameterName, PARAMETER_TYPE_UNMATCH); } } } }
SymbolTableEntry* enterSymbol(char* symbolName, SymbolAttribute* attribute) { SymbolTableEntry* oldsym = retrieveSymbol(symbolName); if(oldsym != NULL && oldsym.nestingLevel == sybolTable.currentLevel) { printf("Error: %s has been redecalred!"); g_anyErrorOccur = 1; return oldsym; } //new entry SymbolTableEntry* newsym = newSymbolTableEntry(symbolName, sybolTable.currentLevel); newsym.attribute = attribute;//the space of attribute may be changed,need to be careful. //add to scope display newsym.nextInSameLevel = symbolTable.scopeDisplay[symbolTable.currentLevel]; symbolTable.scopeDisplay[symbolTable.currentLevel] = newsym; //add to hash table if(oldsym == NULL) enterIntoHashTrain(newsym); else { removeFromHashTrain(oldsym); enterIntoHashTrain(newsym); } newsym.sameNameInOuterLevel = oldsym; }