Cygwin控制台倾倒大量神秘输出然后键入1; 2; 6; 22c

时间:2016-08-20 02:33:45

标签: c++ cygwin

我正在用C ++编写词法分析器,我能够编译程序并将其链接得很好;然而,当涉及到它的运行时,我得到了一个巨大的输出转储,我不知道它为什么会发生,或者它是否与我写的程序有关。我甚至无法复制整个转储,但这里发生了gif。 这是一个很好的衡量标准。

我在Windows 10上编译并运行cygwin。

  

token.h

#ifndef TOKEN_H
#define TOKEN_H

#include <string>

class ice_lexer;

enum ice_type_enum {
    ICE_NONE,
    ICE_EOF,
    ICE_MODULE,
    ICE_IDENT,
    ICE_FLT,
    ICE_NUM,
    ICE_STR,
    // SYMBOLS
    ICE_RPARA,
    ICE_LPARA,
    ICE_RBRAC,
    ICE_LBRAC,
    ICE_RCURL,
    ICE_LCURL,
    ICE_PERIOD,
    ICE_COLON,
    ICE_SEMIC,
    ICE_COMMA,
    // COMPARISON
    ICE_EQLTO,
    ICE_NOTEQL,
    ICE_GRT,
    ICE_GRTEQL,
    ICE_LES,
    ICE_LESEQL,
    // ASSIGNMENT
    ICE_EQL,
    ICE_ADDEQL,
    ICE_SUBEQL,
    ICE_MULEQL,
    ICE_DIVEQL,
    ICE_CAREQL,
    // URNARY
    ICE_URNARYNOT,
    ICE_URNARYSUB,
    // BINARY
    ICE_ADD,
    ICE_SUB,
    ICE_MUL,
    ICE_DIV,
    ICE_MOD,
    ICE_CAR,
    ICE_CAT,
    // TERNARY
    ICE_TERNARY,
    // KEYWORDS
    ICE_IMPORT,
    ICE_AS,
    ICE_WHILE,
    ICE_FOR,
    ICE_BREAK,
    ICE_IF,
    ICE_RETURN,
    ICE_TRUE,
    ICE_FALSE,
    // TYPES
    ICE_TYPEDEF,
    ICE_CLASS,
    ICE_ENUM,
    ICE_INT,
    ICE_FLOAT,
    ICE_STRING,
    ICE_BOOLEAN,
    ICE_VOID,
    ICE_STRUCT
};

typedef struct ice_keyword {
    std::string word;
    ice_type_enum type;
} ice_keyword;

class ice_type {
public:
    std::string string;
    ice_type_enum type;
    ice_type(ice_type_enum t);
};

class ice_token {
public:
    ice_type type;
    size_t line;
    size_t pos;

    std::string str;
    double flt;
    size_t num;

    ice_token(const ice_lexer* lexer, ice_type_enum t);
    ~ice_token() {};
    void print();
};

#endif
  

token.cpp

#include <string>
#include <iostream>
#include "token.h"
#include "lexer.h"

static const std::string ice_type_enum_strings[] = {
    // ABSTRACT
    "no type",
    "end of file",
    "module",
    "identifier",
    "floating",
    "number",
    "string",
    // SYMBOLS
    "left para",
    "right para",
    "left brac",
    "right brac",
    "left curl",
    "right curl",
    "period",
    "colon",
    "semi",
    "comma",
    // COMPARISON
    "eql to",
    "not eql",
    "grt",
    "grt eql",
    "les",
    "les eql",
    // ASSIGNMENT
    "eql",
    "add eql",
    "sub eql",
    "mul eql",
    "div eql",
    "car eql",
    // URNARY
    "urnarynot",
    "urnarysub",
    // BINARY
    "add",
    "sub",
    "mul",
    "div",
    "mod",
    "car",
    "cat",
    // TERNARY
    "ternary",
    // KEYWORDS
    "import",
    "as",
    "while",
    "for",
    "break",
    "if",
    "return",
    "true",
    "false",
    // TYPES
    "typedef",
    "class",
    "enum",
    "int",
    "float",
    "string",
    "bool",
    "void",
    "struct"
};

ice_type::ice_type(ice_type_enum t) {
    string = ice_type_enum_strings[t];
    type = t;
}

ice_token::ice_token(const ice_lexer* lexer, ice_type_enum t):type(t) {
    line = lexer->line;
    pos = lexer->pos;
    num = 0;
}

void ice_token::print() {
    std::cout << "TYPE [ STR: \'" << this->type.string << "\' | ENUM: " << this->type.type << " ]:" << std::endl;
    std::cout << "\tLINE NO. " << this->line << " IN THE " << this->pos << "TH ROW" << std::endl;

    if (this->type.type == ICE_NUM)
        std::cout << "\tNUMBER VALUE: \'" << this->num << "\'" << std::endl;

    if (this->type.type == ICE_FLT)
        std::cout << "\tFLOAT VALUE: \'" << this->flt << "\'" << std::endl;

    if (this->type.type != ICE_NUM && this->type.type != ICE_FLT)
        std::cout << "\tSTR VALUE: \'" << this->str << "\'" << std::endl;
}
  

lexer.h

#ifndef LEXER_H
#define LEXER_H

#include "token.h"
#include <string>

class ice_token;

#define newline() {     \
    this->line++;       \
    this->pos = 0;      \
}

class ice_lexer {
public:
    std::string source;
    size_t length;
    size_t line;
    size_t pos;
    size_t ptr;
    ice_lexer(std::string file_name);
    ~ice_lexer() {};
    ice_token lexer_next();
private:
    const char look(int offset);
    const char advance(int offset);
    void comment(void);
    void nested(void);
    ice_token symbol(ice_type_enum type, std::string string, int move);
    void ident(void);
};

#endif
  

lexer.cpp

#include <fstream>
#include <string>
#include <assert.h>
#include "token.h"
#include "lexer.h"

extern const ice_keyword keywords[] = {
    {"import", ICE_IMPORT},
    {"as", ICE_AS},
    {"while", ICE_WHILE},
    {"for", ICE_FOR},
    {"break", ICE_BREAK},
    {"if", ICE_IF},
    {"return", ICE_RETURN},
    {"true", ICE_TRUE},
    {"false", ICE_FALSE},
    {"typedef", ICE_TYPEDEF},
    {"class", ICE_CLASS},
    {"enum", ICE_ENUM},
    {"int", ICE_INT},
    {"float", ICE_FLOAT},
    {"string", ICE_STRING},
    {"bool", ICE_BOOLEAN},
    {"void", ICE_VOID},
    {"struct", ICE_STRUCT}
};

ice_lexer::ice_lexer(std::string file_name) {
    std::ifstream input_file(file_name);
    std::string content((std::istreambuf_iterator<char>(input_file)),
        (std::istreambuf_iterator<char>()));

    line = 1;
    pos = 0;
    ptr = 0;
}

const char ice_lexer::look(int offset = 0) {
    if (this->ptr + offset < this->length)
        return '\0';
    return this->source[this->ptr + offset];
}

const char ice_lexer::advance(int offset) {
    assert(this->ptr + offset < this->length);
    return look();
}

void ice_lexer::comment(void) {
    while (look() != '\n') { advance(1); }
    newline();
}

void ice_lexer::nested(void) {
    size_t depth = 1;

    while (depth > 0) {
        if (look(0) == '\\' && look(1) == '\\') {
            advance(2);
            depth--;
        } else if (look(0) == '/' && look(1) == '/') {
            advance(2);
            depth++;
        } else {
            advance(1);
        }
    }
}

ice_token ice_lexer::symbol(ice_type_enum type, std::string string, int move) {
    ice_token token(this, type);
    token.str = string;
    advance(move);

    return token;
}

ice_token ice_lexer::lexer_next() {
    /*
    while (look() != '\0') {
        switch (look()) {
        case '+':
            if (look(1) == '=')
                return symbol(ICE_ADDEQL, "+=", 2);
            else
                return symbol(ICE_ADD, "+", 1);
            break;
        case '-':
            if (look(1) == '=')
                return symbol(ICE_ADDEQL, "+=", 2);
            else
                return symbol(ICE_SUB, "-", 1);
            break;
        case '*':
            if (look(1) == '=')
                return symbol(ICE_ADDEQL, "+=", 2);
            else
                return symbol(ICE_MUL, "*", 1);
            break;
        case '/':
            if (look(1) == '=')
                return symbol(ICE_DIVEQL, "/=", 2);
            else if(look(1) == '/')
                nested();
            else
                return symbol(ICE_DIV, "/", 1);
            break;
        case '^':
            if (look(1) == '=')
                return symbol(ICE_CAREQL, "^=", 2);
            else
                return symbol(ICE_CAR, "^", 1);
            break;
        case '~':
            comment();
        case '(':
            return symbol(ICE_LPARA, "(", 1);
            break;
        case ')':
            return symbol(ICE_RPARA, ")", 1);
            break;
        case '[':
            return symbol(ICE_LBRAC, "[", 1);
            break;
        case ']':
            return symbol(ICE_RBRAC, "]", 1);
            break;
        case '{':
            return symbol(ICE_LCURL, "{", 1);
            break;
        case '}':
            return symbol(ICE_RCURL, "}", 1);
            break;
        default:

            break;
        }
    }
    */
}

1 个答案:

答案 0 :(得分:0)

我做了一些改变,有点工作了。你正在做的一些事情有点不稳定。

ice_lexer::ice_lexer(std::string file_name) {
    std::ifstream input_file(file_name);
    std::string content((std::istreambuf_iterator<char>(input_file)),
        (std::istreambuf_iterator<char>()));

    line = 1;
    pos = 0;
    ptr = 0;
}

您正在将文件读入content,这是一个局部变量。您可能打算将其读入source。您还没有更新length,我认为应该是source.size()

ice_lexer::look()中有一个错误:

const char ice_lexer::look(int offset = 0) {
    if (this->ptr + offset < this->length)
        return '\0';
    return this->source[this->ptr + offset];
}

条件应为>=,而不是<ice_lexer::advance()中的另一个类似错误:

const char ice_lexer::advance(int offset) {
    assert(this->ptr + offset < this->length);
    return look();
}

应为<=

当你在控制台上看到垃圾时,通常意味着你正在打印一个最后没有\0的字符串,它只是在内存中运行,直到它找到{{1在某个地方。如果你正在读某个你不应该去的地方,它也可能会崩溃。这反过来可能意味着你有未初始化的变量。

学会正确使用调试器。通过逐步执行函数和查看变量,很容易弄明白。