bool isRemainderWhenDevidingByTwo(Expr *expr)
 {
     BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(expr);
     return binaryOperator &&
         binaryOperator->getOpcode() == BO_Rem && isIntegerLiteral(binaryOperator->getRHS(), 2);
 }
 bool isRemainderEqualsOne(Expr *leftExpr, Expr *rightExpr)
 {
     return (isIntegerLiteral(rightExpr, 1) && isRemainderWhenDevidingByTwo(leftExpr)) ||
         (isIntegerLiteral(leftExpr, 1) && isRemainderWhenDevidingByTwo(rightExpr));
 }
Beispiel #3
0
//find token details and type and update token.  May require examining properties of neighbouring tokens
void TokenList::findAndSetTokenDetails(Token *token){
    //tracersing for a comment body
    //put comment case the very beginning, is case meet situation like "--and" (in case make comment body be keyword or operator)
    if(token!=nullptr  && token->prev!=nullptr && token->prev->stringRep=="--")
    {
        token->setTokenType(T_CommentBody);
        return;
    }
    //use tolower function to convert everything to lower case since VHDL is case-sensitive except literal
    string str = token->stringRep;
    int len=(int) str.length();
    for(int i=0;i<len;i++){
        str[i] = tolower(str[i]);}
    
    //first to find Keywords and set boolean type as true
    const int length_Keyword= 97; //get the length of arrayOfKeywords
    token->_isKeyword=false;
    for (int i=0; i<length_Keyword; i++)
    {
        if (str == arrayOfKeywords[i]){//compare tableOfKeywords
            token->_isKeyword=true;}
    }
    
    //traversing for operator
    //Didnt consider token like "=>, <=, ==" here, this should be done in prepareNextToken
    for (int i=0; i<28; i++)
    {
        if (str == arrayOfOperators[i]){//compare tableOfKeywords
            token->setTokenType(T_Operator);
            return;}
    }

    //traverse for literal
    //cases where it has bit vectors "0010101", x"1234ABCD"
    if ((token->stringRep).find_first_of("\"")!=std::string::npos){ //can find "
        if (token->details==nullptr)
            token->details=new tokenDetails;
        if ((token->stringRep).find_first_of("\"")==0 && (token->stringRep).find_last_of("\"") != (token->stringRep).find_first_of("\"")){// if " starts the first position of token
            token->details->width=static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1;
            token->details->type="std_logic_vector";
            token->setTokenType(T_Literal);
            return;
        }
        if ((token->stringRep).find_first_of("\"")==1){// if " is the second position of token
            if ((token->stringRep).at(0)=='X'||(token->stringRep).at(0)=='x')
            {
                token->details->width=(static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1)*4;
                token->details->type="std_logic_vector";
                token->setTokenType(T_Literal);
                return;}
            else if ((token->stringRep).at(0)=='B'||(token->stringRep).at(0)=='b')
            {
                token->details->width=static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1;
                token->details->type="std_logic_vector";
                token->setTokenType(T_Literal);
                return;}
            else if ((token->stringRep).at(0)=='O'||(token->stringRep).at(0)=='o')
            {
                token->details->width=(static_cast<int>((token->stringRep).find_last_of("\"")-(token->stringRep).find_first_of("\""))-1)*3;
                token->details->type="std_logic_vector";
                token->setTokenType(T_Literal);
                return;}
        }
    }

    //traverse for std_logic e.g. '0','1'
    if ((token->stringRep)=="'0'"||(token->stringRep)=="'1'"||(token->stringRep)=="'2'"||(token->stringRep)=="'3'"||(token->stringRep)=="'4'"||(token->stringRep)=="'5'"||(token->stringRep)=="'6'"||(token->stringRep)=="'7'"||(token->stringRep)=="'8'"||(token->stringRep)=="'9'"){
        if (token->details == nullptr)
            token->details=new tokenDetails;
        token->details->type="std_logic";
        token->details->width=1;
        token->setTokenType(T_Literal);
        return;}

    //traverse for boolean literal
    if (str=="true" || str == "false"){
        if (token->details == nullptr)
            token->details=new tokenDetails;
        token->setTokenType(T_Literal);
        token->details->type="boolean";
        token->details->width=1;
        return;
    }

    //traverse for integer literal
    if (isIntegerLiteral(token->stringRep))
    {
        if (token->details ==nullptr)
            token->details= new tokenDetails;
        token->setTokenType(T_Literal);
        token->details->width=0;
        token->details->type="integer";
        return;
    }

    //traverse for identifier
    //all start from letters except  operator, comment, and literals should be identifier
    if((str).find_first_not_of(Letter)!= 0) //as long as the first character in stringRep is in Letter
    {
        token->setTokenType(T_Identifier);
        Token *temp1, *temp = new Token;
        temp1=head;
        //first check whether this token already exists or not
        //traverse the tokenlist (where target token exists) until find same string with target token
        while (temp1 != nullptr && temp1 != token)
        {
            if (temp1->stringRep == token->stringRep){ //FIRST same stringRep means target token already exists
                token->alreadyExist=true;
                temp = temp1;}
            temp1=temp1->getNext();//else if traverse to next token
        }
        if (token != nullptr && token->alreadyExist == false) //if this token stringRep shows the first time
        {
            if (token->getNext() != nullptr && token->getNext()->getNext() != nullptr && token->getNext()->getStringRep() == ":") //which imply it is a vector
            {
                if (token->details==nullptr) //initialize token detail
                    token->details=new tokenDetails;
               
    //----------Set detail type--------because VHDL is non-sensitive about capitalization, I try to convert to lower case---//
                string lowerStringRep = token->getNext()->getNext()->getStringRep();
                int len=(int) lowerStringRep.length();
                for(int i=0;i<len;i++){
                    lowerStringRep[i] = tolower(lowerStringRep[i]);}
                token->details->type = lowerStringRep;
                
                if (token->getNext()->getNext()->getNext() != nullptr && token->getNext()->getNext()->getNext()->getStringRep() == "(" &&token->getNext()->getNext()->getNext()->getNext() != nullptr && token->getNext()->getNext()->getNext()->getNext()-> getNext() != nullptr && token->getNext()->getNext()->getNext()->getNext()-> getNext()->getNext() != nullptr){//Find width
                    int length = std::atoi(token->getNext()->getNext()->getNext()->getNext()->getStringRep().c_str()) - std::atoi(token->getNext()->getNext()->getNext()->getNext()->getNext()->getNext()->getStringRep().c_str());
                    if (length < 0)
                        length = - length;
                    token->details->width = length + 1;}
            }
        }
        else if (token != nullptr && token->alreadyExist == true){// if find this token already exists before
            if (temp->details != nullptr && token->details != nullptr)
            {
                token->details->type= temp->details->type;
                token->details->width=temp->details->width;
            }
            else if(temp->details != nullptr){
                token->details = new tokenDetails;
                token->details->type= temp->details->type;
                token->details->width=temp->details->width;
            }}
        //return;
    }
    
    //traversing for other_type
    //if token are not be detected as comment, operator, literal or identifier, then it will be categorize as other
    else
    {
        token->setTokenType(T_Other);
        return;
    }
}