我有一些主机功能和其他枚举的头文件。
所以在文件Lexer.h中,我有一个名为getNextToken()
的函数,它返回一个标记,在这个函数中,我需要调用在token.h中找到的一个名为reservedLookup(string tokenString)
的函数。
reservedWords是另一个名为reservedWords.h
的头文件,它具有保留字的枚举声明
此功能可在token.h中找到
reservedWords reservedLookup (string tokenString)
{
for(rIt = reservedMap.begin(); rIt!= reservedMap.end(); rIt++)
{
if(tokenString == (rIt->first))
{
return rIt->second;
}
}
}
在lexer.h中我尝试私下使用它(甚至在公共场合:):
reservedWords reservedLookup(string tokenString);
它编译,但在函数Token* getNextToken()
中我使用
int tokenType = reservedLookup(strBuffer);
它给我一个错误说明:
obj\Release\main.o:main.cpp:(.text$_ZN5Lexer12getNextTokenEv[__ZN5Lexer12getNextTokenEv]+0x371)||undefined reference to `Lexer::reservedLookup(std::string)'|
我不希望我的编译器读取reservedLookup作为Lexer::reservedLookup(string str)
的一部分,但是Token::reservedLookup(string str)
我有什么方法可以做到吗?
编辑:
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;
}
}
}
#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
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
答案 0 :(得分:3)
让我们先看一下代码的这一部分:
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
...
};
在此文件中,您已声明了一个完整范围名称为Token::reservedLookup
的函数。 (如果你不熟悉“完全作用域”这个术语,那么,对于我们这里的目的,重要的是这是命名这个函数的一种特定方法。)我们可以在前面写Token::
name,因为此函数是类Token
的成员。您还通过提供函数体(括号{
和}
中包含的代码)来定义函数。我在函数体开始和结束的行上添加了注释。
到目前为止,这么好。现在,这个函数是类Token
的普通成员,而不是“静态”函数,所以为了调用它,你必须首先得到一个Token
类型的对象,然后你可以调用这个函数在该对象上,例如通过在其他函数中编写这样的代码:
Token token;
token.reservedDeclare();
reservedWords word = token.reservedLookup("read");
现在是事情变得困惑的部分。你写了这段代码:
class Lexer
{
private:
...
reservedWords reservedLookup(string tokenString);
...
};
这样做是为了从第一个声明不同的函数。此函数的完全范围名称为Lexer::reservedLookup
。但是,您没有提供该函数的任何定义(既不在这里,也不在任何其他地方)。所以当你在Lexer
类的代码中并且你写了一行这样的行时,
tokenType = reservedLookup(strBuffer);
编译器按照C ++语言规范所说的方式对此进行解释,这应该是对函数reservedLookup
的调用,该函数属于该调用出现的同一函数的类。简而言之,这是对Lexer::reservedLookup
的调用。由于您从未定义过该函数,因此无法生成正确调用函数的代码,因此您会出错。
所以你可能根本不想定义Lexer::reservedLookup
。如果您未从类Token::reservedLookup
本身的某个功能中调用Token
,则可以提供类型为Token
的对象,以便您可以拨打电话功能,正如我在我的例子中所做的那样。或者,您可能希望将函数的定义设置为static,以便可以通过这种方式调用它,而无需Token
类型的对象:
reservedWords word = Token::reservedLookup("read");
但是,为了使这项工作符合要求,您还必须使reservedDeclare
成为静态函数,并使reservedMap
成为Token
的静态变量,或进行其他更改以便Token::reservedLookup
使用的数据独立于Token
类型的特定对象。
您可能还想查看此问题的答案:The Definitive C++ Book Guide and List并阅读推荐的书籍,以帮助更好地理解语言的术语,以便您可以获得有关您的计划的更好建议。