Enum & vector returns a "not declared in this scope" error when it's included in the header.

I'm trying to make a simple Lexer that breaks up a string into characters and tokenizes them. But I keep getting a "not declared in this scope" error even though that it is declared in a header, and included in main.

I have no idea why I keep getting this, and if someone could help guide me to the right direction, that would be great!

Thanks in advance!


Error:
1
2
3
4
5
6
7
8
9
10
11
[Running] cd "e:\Basic compiler in C++\BASIC\" && g++ main.cpp -o main && "e:\Basic compiler in C++\BASIC\"main
main.cpp: In function 'int main()':
main.cpp:10:25: error: 'TokenTypes' was not declared in this scope
     while(token.kind != TokenTypes[TokenType_EOF]) {
                         ^~~~~~~~~~
main.cpp:10:36: error: 'TokenType_EOF' was not declared in this scope
     while(token.kind != TokenTypes[TokenType_EOF]) {
                                    ^~~~~~~~~~~~~

[Done] exited with code=1 in 0.249 seconds
 



Token.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
#include <iostream>

class Token {
    public:

        const char* value;
        const char* kind;

        Token(const char* tokenValue, const char* tokenKind) {
            value = tokenValue;
            kind = tokenKind;
        }

};



lexer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#pragma once
#include "token.h"
#include <iostream>
#include <vector>
#include <string>

class Lexer {
    public:

        enum TokenEnum {
            TokenType_EOF,
            TokenType_NEWLINE,
            TokenType_STRING,
            TokenType_NUMBER,
            TokenType_IDENTIFIER,
            
            TokenType_PRINT,

            TokenType_PLUS,
            TokenType_MINUS,
            TokenType_ASTERISK,
            TokenType_SLASH

        };

        std::vector<std::string> TokenTypes = {

            "EOF",
            "NEWLINE",
            "STRING",
            "NUMBER",
            "IDENTIFIER",

            "PRINT",

            "PLUS",
            "MINUS",
            "ASTERISK",
            "SLASH"

        };

        std::string source;
        char currentCharacter;
        int currentPosition;
        std::vector<std::string> temp;
        std::string value;
        std::string keyword;

        Lexer(std::string input);
        void nextCharacter();
        char peek();
        void skipWhitespace();
        Token getToken();
        std::string checkIfKeyword(std::string tokenKind);

};



lexer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include "includes/lexer.h"

Lexer::Lexer(std::string input) {
    source = input + "\n";
    currentPosition = -1;
    nextCharacter();
}

void Lexer::nextCharacter() {

    currentPosition += 1;

    if(currentPosition >= source.size()) {
        currentCharacter = '\0';
    }

    else {
        currentCharacter = source[currentPosition];
    }

}

char Lexer::peek() {

    if(currentPosition >= source.size()) {
        return '\0';
    }

    return source[currentPosition];

}

Token Lexer::getToken() {

    if(currentCharacter == '+') {

        Token token(&currentCharacter, TokenTypes[TokenType_PLUS].c_str());
        nextCharacter();
        return token;

    }

    else if(currentCharacter == '\n') {

        Token token(&currentCharacter, TokenTypes[TokenType_NEWLINE].c_str());
        nextCharacter();
        return token;

    }

    else if(currentCharacter == '\0') {

        Token token(&currentCharacter, TokenTypes[TokenType_EOF].c_str());
        nextCharacter();
        return token;

    }

}

std::string Lexer::checkIfKeyword(std::string tokenKind) {

    for(int i = 0; i < TokenTypes.size(); i++) {
        if(TokenTypes[i] == tokenKind) {
            return TokenTypes[i];
        }
    }

    return "IDENTIFIER";

}



main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "includes/lexer.h"
#include <iostream>

int main() {

    std::string text = "Hello BASIC";
    Lexer lexer(text);

    Token token = lexer.getToken();
    while(token.kind != TokenTypes[TokenType_EOF]) {
        std::cout << token.kind << std::endl;
        token = lexer.getToken();
    }

    return 0;
}



Edit:

Once ran, the program should print out "NEWLINE" once, and stop running.
Last edited on
You have declared TokenTypes and TokenEnum as members of the Lexer class.

 
while(token.kind != lexer.TokenTypes[Token::TokenType_EOF]) {

Last edited on
@Peter87

I changed the main to:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include "includes/lexer.h"
#include <iostream>

int main() {

    std::string text = "Hello BASIC";
    Lexer lexer(text);

    Token token = lexer.getToken();
    while(token.kind != Lexer::TokenTypes[Lexer::TokenType_EOF]) {
        std::cout << token.kind << std::endl;
        token = lexer.getToken();
    }

    return 0;
}


But now I get

1
2
3
4
5
6
7
8
9
10
11
12
[Running] cd "e:\Basic compiler in C++\BASIC\" && g++ main.cpp -o main && "e:\Basic compiler in C++\BASIC\"main
main.cpp: In function 'int main()':
main.cpp:10:32: error: invalid use of non-static data member 'Lexer::TokenTypes'
     while(token.kind != Lexer::TokenTypes[Lexer::TokenType_EOF]) {
                                ^~~~~~~~~~
In file included from main.cpp:1:0:
includes/lexer.h:41:9: note: declared here
         };
         ^

[Done] exited with code=1 in 0.248 seconds
 
TokenTypes is a non-static data member so you need to specify which object that you want to access it from.

If every Lexer object use the same TokenTypes vector that is never modifed then you might want declare it as a const static member, or perhaps as a const global variable (in that case you might also want to make TokenEnum global).
Last edited on
Oh my gosh, how could I have missed that?
Thanks again Peter, I appreciate the help.
Topic archived. No new replies allowed.