Domanda

I have some header files which host functions and in other enums.

So in file Lexer.h, I have a function called getNextToken() which returns a token and in this function I need to call a function called reservedLookup(string tokenString) found in token.h

reservedWords is another header file called reservedWords.h which has enum declarations of the reserved Words

This function is found in token.h

reservedWords reservedLookup (string tokenString)
{
        for(rIt = reservedMap.begin(); rIt!= reservedMap.end(); rIt++)
        {
            if(tokenString == (rIt->first))
            {
                return rIt->second;
            }

        }
}

in lexer.h I tried using this in private (and even in public:) :

reservedWords reservedLookup(string tokenString);

it compiles, but when in function Token* getNextToken() I use

int tokenType = reservedLookup(strBuffer);

it gives me an error stating:

obj\Release\main.o:main.cpp:(.text$_ZN5Lexer12getNextTokenEv[__ZN5Lexer12getNextTokenEv]+0x371)||undefined reference to `Lexer::reservedLookup(std::string)'|

I don't want my compiler to read reservedLookup as part of Lexer::reservedLookup(string str) but as Token::reservedLookup(string str)

Is there any way I can do it?


EDIT:

Token.h

class Token
{
       .....
       .....
public:

    void reservedDeclare ()
    {
         // iterator used for looping through reservedWords

        //Taking care of the Reserved Words first

        reservedMap["function"] =  reservedWords::tkfunction;

        //if - then - else - while - halt
        reservedMap["if"] = reservedWords::tkif;
        reservedMap["else"] = reservedWords::tkelse;
        reservedMap["while"] = reservedWords::tkwhile;
        reservedMap["halt"] = reservedWords::tkhalt;

        //and, or, not, true, else
        reservedMap["and"] = reservedWords::tkand;
        reservedMap["or"] = reservedWords::tkor;
        reservedMap["not"] = reservedWords::tknot;
        reservedMap["true"] = reservedWords::tktrue;
        reservedMap["false"] = reservedWords::tkfalse;

        //sets and read/write
        reservedMap["set"] = reservedWords::tkset;
        reservedMap["let"] = reservedWords::tklet;
        reservedMap["read"] = reservedWords::tkread;
        reservedMap["write"] = reservedWords::tkwrite;

        //variable type
        reservedMap["int"] = reservedWords::tkint;
        reservedMap["char"] = reservedWords::tkchar;
        reservedMap["bool"] = reservedWords::tkbool;
        reservedMap["real"] = reservedWords::tkreal;
        reservedMap["string"] = reservedWords::tkstring;
        reservedMap["unit"] = reservedWords::tkunit;


    }

reservedWords reservedLookup (string tokenString)
{
        for(rIt = reservedMap.begin(); rIt!= reservedMap.end(); rIt++)
        {
            if(tokenString == (rIt->first))
            {
                return rIt->second;
            }

        }
}

reservedWords.h

#ifndef RESERVEDWORDS_H_INCLUDED
#define RESERVEDWORDS_H_INCLUDED

#include <string>
#include <vector> //std::vector
#include <algorithm>    // std::find

using namespace std;

/**
        All the reserved words used by the compiler

*/


    /**
        This file contains all the keywords or reserved words or reserved Symbols used by the compiler
        In the lexer, we will check whether the string we are passing is either a Reserved word
        or it is actually and identifier
    */

    enum reservedWords
    {
        tkfunction,
        tkif,
        tkelse,
        tkwhile,
        tkhalt,

        tkand,
        tkor,
        tknot,
        tktrue,
        tkfalse,

        tkset,
        tklet,
        tkread,
        tkwrite,

        tkint,
        tkchar,
        tkbool,
        tkreal,
        tkstring,
        tkunit,

        tkreservedWord,
        tkidentifier


    };

    #endif // RESERVEDWORDS_H_INCLUDED

PARTIAL Code of Lexer.h

class Lexer
{
   private:
   string strBuffer ="";//holds the current characters that have been read and waiting to be matched
   int tokenType = 0;
   reservedWords reservedLookup(string tokenString); // THIS DOES NOT WORK. SEES IT AS Lexer::reservedLookup
  ....
  ....
  ...
  ...

  tokenType = reservedLookup(strBuffer); // GIVES ME ERROR BECAUSE OF ABOVE
È stato utile?

Soluzione

Let's look at this part of your code first:

class Token
{
  ...
public:
  ...
  reservedWords reservedLookup (string tokenString)
  {       // start of function body
    for(rIt = reservedMap.begin(); rIt!= reservedMap.end(); rIt++)
    {
        if(tokenString == (rIt->first))
        {
            return rIt->second;
        }

    }
  }       // end of function body
  ...
};

In this file you have declared a function whose fully-scoped name is Token::reservedLookup. (If you're unfamiliar with the term "fully scoped", OK; for our purposes here, the important thing is that this is a specific way of naming this function.) We can write Token:: at the front of this name because this function is a member of the class Token. You have also defined the function by providing a function body (the code enclosed in braces { and }). I have added comments on the lines where the function body begins and ends.

So far, so good. Now, this function is an ordinary member of the class Token, not a "static" function, so in order to call it, you must first have an object of type Token, and then you can call this function on that object, for example by writing code like this inside some other function:

Token token;
token.reservedDeclare();
reservedWords word = token.reservedLookup("read");

Now comes the part where things get confused. You wrote this code:

class Lexer
{
private:
  ...
  reservedWords reservedLookup(string tokenString);
  ...
};

What this does is to declare a different function from the first one. This function's fully-scoped name is Lexer::reservedLookup. You have not provided any definition of the function, however (neither here, nor apparently anywhere else). So when you are within the code of the Lexer class and you write a line such as this,

tokenType = reservedLookup(strBuffer);

the compiler interprets this in the way the C++ language specification says it should, which is that this should be a call to the function reservedLookup that belongs to the class of the same function where this call appeared. In short, it is a call to Lexer::reservedLookup. Since you never defined that function, it is impossible to produce the code that calls the function correctly, and therefore you have an error.

So you probably do not want to define Lexer::reservedLookup at all. If you are not calling Token::reservedLookup from within one of the functions of the class Token itself, you may provide an object of type Token so that you may call the function, as I did in my example. Alternatively, you might want to make your definition of the function static so that you can call it this way, without requiring an object of type Token:

reservedWords word = Token::reservedLookup("read");

In order to make this work as desired, however, you would also have to make reservedDeclare a static function and make reservedMap a static variable of Token, or make some other changes so that the data used by Token::reservedLookup exists independently of a specific object of type Token.

You may also want to look at the answers to this question: The Definitive C++ Book Guide and List and read a recommended book to help understand the terminology of the language better so that you can get better advice about your programs.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top