示例#1
0
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;
    }
}
示例#3
0
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;
    }
}
示例#5
0
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);
  }
}
示例#6
0
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);
  }
}
示例#7
0
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);
  }
}
示例#8
0
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);
        }
      }
    }
  }
}
示例#9
0
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);
    }
  }
}
示例#10
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);
      }
    }
  }
}
示例#11
0
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;
}