为什么我一直收到错误消息"没有名为" TokenType"在'令牌' '"

时间:2016-10-31 04:13:17

标签: c++ file header include

我正在使用c ++为我的一个类创建一个词法分析器,并且我的源文件中包含我的头文件的内容有问题。我将头文件#include到我的源文件中,但它一直说它无法找到包含的成员。

头文件是:

#include <string>
#include <iostream>

enum TokenType {
    ID,         // identifier
    STR,        // string
    INT,        // integer constant
    PLUS,       // the + operator
    STAR,       // the * operator
    LEFTSQ,     // the [
    RIGHTSQ,    // the ]
    PRINT,      // print keyword
    SET,        // set keyword
    SC,     // semicolon
    LPAREN,     // The (
    RPAREN,     // the )
    DONE,       // finished!
    ERR,        // an unrecoverable error
};

class Token {
private:
    TokenType   tok;
    std::string lexeme;

public:
    Token() : tok(ERR), lexeme("") {}
    Token(TokenType t, std::string s) : tok(t), lexeme(s) {}

    TokenType   getTok() const      { return tok; }
    std::string getLexeme() const   { return lexeme; }

    friend bool operator==(const Token& left, const Token& right) {
        return left.tok == right.tok;
    }

    friend std::ostream& operator<<(std::ostream& out, const Token& t);
};

extern  int linenum;
extern  Token   getToken(std::istream* instream);

虽然我从其中一个有多个错误的文件中获取了这部分代码:

 map<Token::TokenType,int> tokenCount;
    map<string,int> lexemeCount;
    Token t;

    while( (t = getTok(br)) != Token::TokenType::DONE && t !=Token::TokenType::ERR ) {
        tokenCount[t.getType()]++;
        if( t == Token::TokenType::VAR
           || t == Token::TokenType::SCONST
           || t == Token::TokenType::ICONST ) {
            lexemeCount[t.getLexeme()]++;
        }

我确信这是一个简单的修复,但我不知道如何解决这个问题。我一直试图修复它几天,但无法解决这个问题。

2 个答案:

答案 0 :(得分:0)

您的错误正是调试器告诉您的错误。 TokenType不是类Token的成员,因此您不能说Token :: TokenType。您只需要将其称为TokenType。

答案 1 :(得分:0)

您已在TokenType之外定义Token,因此TokenType内未定义名为Token的标识符,因此未定义Token::TokenType

你有两个明显的选择。在TokenType内定义Token

#include <string>
#include <iostream>

class Token {

    enum TokenType {
        ID,         // identifier
        // ...
        ERR,        // an unrecoverable error
    };

// ...    
};

...或者使用名称TokenType without the Token :: on the front. If you want to qualify the name with TokenType , use an enum class`:

enum class TokenType {
    ID,         // identifier
    // ...
    ERR,        // an unrecoverable error
};

map<TokenType, int> tokenCount;
map<string, int> lexemeCount;
Token t;

while ((t = getTok(br)) != TokenType::DONE && t != TokenType::ERR) {
    tokenCount[t.getType()]++;
    if (t == TokenType::VAR
        || t == TokenType::SCONST
        || t == TokenType::ICONST) {
        lexemeCount[t.getLexeme()]++;
    }

当然,您可以组合类型,并将TokenType定义为enum class类内部的Token(尽管有些人会认为这有点过于保护,可以这么说)。