枚举未给出正确的值

问题描述 投票:0回答:1

我一直在为我的命令行项目制作一个简单的解释器,但是我最近偶然发现了一个我不知道原因的问题。

以下是代码:

// cls.h
#pragma once
#include <iostream>
#include <string>
#include <iomanip>

enum id {undef, kwd, idt, opr, val};    // Ignore idt

extern std::string keywords[];          // Declaring the keywords array
extern std::string operators[];         // Declaring the operators array

class Token
{
    id ID;
    std::string value;
public:
    Token() {
        ID = undef;
        value = "";
    }

    void SetID(id ID) {
        this->ID = ID;
    }

    void SetValue(std::string value) {
        this->value = value;
    }

    id GetID() {
        return ID;
    }

    std::string GetValue() {
        return value;
    }
};

std::string UserInput();
void Lexical(Token *token, int nstr, std::string str, int ntok);


// cls.cpp

#include <iostream>

// Definitions of the keywords and operators arrays
std::string keywords[] = {
                             "echo",
                             "exit"
                         };

std::string operators[] = {
                             "+",
                             "-",
                             "/",
                             "%" 
                          };


// input.cpp

#include "cls.h"

std::string UserInput()             // Function to take user's input
{
    std::string input;
    std::getline(std::cin, input);

    return input;
}


// lex.cpp

#include "cls.h"

// To check whether a token is a keyword
static bool aKeyword(std::string str)
{
    for (int i = 0; i < 10; i++) {
        if (keywords[i] == str)
            return true;
    }

    return false;
}

// To check whether a token is an operator
static bool aOperator(std::string str)
{
    for (int i = 0; i < 10; i++) {
        if (operators[i] == str)
            return true;
    }

    return false;
}

void Lexical(Token *token, int ntok, std::string str, int nstr)
{
    // Working the tokens' values
    int idx = 0;
    bool fspace = false;
    std::string plh[256];

    for (int i = 0; i < nstr; i++) {
        if ((str.at(i) == ' ') && (fspace == false)) {
            idx++;
            fspace = true;
            continue;
        } else
        if ((str.at(i) == ' ') && (fspace == true)) {
            continue;
        }

        plh[idx].append(&(str.at(i)), 1);
        fspace = false;
    }

    for (int i = 0; i < ntok; i++) {
        (token + i)->SetValue(plh[i]); 
    }

    // Working the tokens' IDs
    // Checking whether a token is a keyword, an operator or a value
    for (int i = 0; i < ntok; i++) {
        if (aKeyword((token + i)->GetValue()) == true) {
            (token + i)->SetID(kwd);
        } else
        if (aOperator((token + i)->GetValue()) == true) {       // <--- The problem
            (token + i)->SetID(opr);
        } else {
            (token + i)->SetID(val);
        }
    }

}


// init.cpp

#include "cls.h"

int main()
{
    std::string usinput;
    Token token[256];

    std::cout << "User input: ";
    usinput = UserInput();          // Taking user's input

    Lexical(token, 256, usinput, (int) usinput.size());   // Calling the lexical function

    // Outputting the tokens' values and IDs (The IDs is in the parentheses)
    for (int i = 0; i < 10; i++) {
        std::cout << "Token[" << i << "] = "
                  << token[i].GetValue()
                  << std::setfill(' ') 
                  << std::setw(15 - (token[i].GetValue()).size())
                  << "(" << token[i].GetID() << ")"
                  << std::endl;
    }

    return 0;
}

当 Lexical 函数尝试使用 ID 的关键字 (kwd)、运算符 (opr) 或值 (val) 对标记进行检查和分类时,就会出现问题。在以下枚举 id 的定义中

enum id {undef, kwd, idt, opr, val};

很明显,opr 应该具有值 3(对于运算符),但是当我尝试运行程序并看到输出时,它给出的值是 1(对于关键字)

benanthony@DESKTOP-QI9Q4LV:~/codes/CLine$ make
g++ init.cpp lex.cpp input.cpp cls.cpp -Wall -Wextra -o CLine
benanthony@DESKTOP-QI9Q4LV:~/codes/CLine$ ./CLine
User input: Hello there + - Rand - Lett - echo yes
Token[0] = Hello         (4)
Token[1] = there         (4)
Token[2] = +             (1)
Token[3] = -             (1)
Token[4] = Rand          (4)
Token[5] = -             (1)
Token[6] = Lett          (4)
Token[7] = -             (1)
Token[8] = echo          (1)
Token[9] = yes           (4)

token[2]、token[3]、token[5]和token[7]中的+和-的ID值应该是3。

我尝试过通过更改 ID 名称等方式来解决此问题,但仍然不起作用。

这似乎是一个简单的问题,但我仍然不知道如何解决。我是否遗漏了什么或犯了什么错误?

c++ enums lex
1个回答
5
投票

该问题是由

aKeyword
aOperator
方法中的未定义行为引起的。您正在比较数组之外的字符串,
i < 10
,如果修复这些字符串,您将获得预期的结果:

// To check whether a token is a keyword
static bool aKeyword(std::string str)
{
    for (int i = 0; i < 2; i++) {
        if (keywords[i] == str)
            return true;
    }

    return false;
}

// To check whether a token is an operator
static bool aOperator(std::string str)
{
    for (int i = 0; i < 4; i++) {
        if (operators[i] == str)
            return true;
    }

    return false;
}
© www.soinside.com 2019 - 2024. All rights reserved.