Ошибка ссылки при компиляции базового ассемблера - PullRequest
0 голосов
/ 07 марта 2019

Я пытался создать специальный ассемблер, который будет работать с конкретным типом машины.Я пытался скомпилировать программу, но получил ошибку компоновщика:

/ usr / bin / ld: lexer.o: в функции `Lexer :: lex (std :: __ cxx11:: basic_string, std :: allocator>) ':

lexer.cpp :(. text + 0x2ee): неопределенная ссылка на `Lexer :: isSpecial (char) '

collect2: error: ld вернул 1 состояние выхода

Снимок экрана здесь

У меня есть 3 основных файла: lexer.h, lexer.cpp, sasm.cpp.Вот код:

lexer.h:

#ifndef LEXER_H
  #define LEXER_H

  #include <iostream>
  #include <vector>

  // type definitions
  typedef uint8_t byte;
  typedef std::vector<std::string> strings;

  enum State : byte {
    START,
    READCHAR,
    READBLOCK,
    SKIP,
    DUMP,
    COMMENT,
    END
  };

  // Instructions definitions
  #define ADD 0x40000001
  #define SUB 0x40000002
  #define TIME 0x40000003
  #define DIVIDE 0x40000004
  #define HALT 0x40000000

  class Lexer {
  private:
    bool isSpace(char c);
    bool isSpecial(char c);
    bool isGroup(char c);
    char end_char, beg_char;

  public:
    strings lex(std::string s);
  };

#endif

lexer.cpp:

#include "lexer.h"

strings Lexer::lex(std::string s) {
  strings strLst;
  char lexEme[256];
  int i = 0;
  int j = 0;
  State state = START;
  int done = 0;
  int len = s.length();
  int balance = 0;

  while (i < len) {
    switch (state) {
      case START:
        if (isSpace(s[i])) {
          state = SKIP;
        } else if (isGroup(s[i])) {
          if (s[i] == '"') {
            lexEme[j] = s[i];
            j++;
            i++;
          }
          state = READBLOCK;
        } else if (s[i] == '/' && s[i + 1] == '/') {
          i += 2;
          state = COMMENT;
        } else {
          state = READCHAR;
        }
        break;

      case READCHAR:
        if (isSpace(s[i])) {
          state = DUMP;
        } else if (s[i] == '\\') {
          i += 2;
        } else if (isGroup(s[i])) {
          if (s[i] == '"') {
            lexEme[j] = s[i];
            j++;
            i++;
          }
          state = READBLOCK;
        } else if (isSpecial(s[i])) {
          if (j == 0) {
            lexEme[j] = s[i];
            j++;
            i++;
          }
          state = DUMP;
        } else if (s[i] == '/' && s[i + 1] == '/') {
          i += 2;
          state = COMMENT;
        } else {
          lexEme[j] = s[i];
          j++;
          i++;
        }
        break;

      case READBLOCK:
        if (s[i] == beg_char && s[i] != '"') {
          balance++;
          lexEme[j] = s[i];
          j++;
          i++;
        } else if (s[i] == end_char) {
          balance--;
          lexEme[j] = s[i];
          j++;
          i++;

          if (balance <= 0) {
            state = DUMP;
          }
        } else if (end_char == '"' && s[i] == '\\') {
          // TODO: fix this to actually record the chars
          i += 2;
        } else {
          lexEme[j] = s[i];
          j++;
          i++;
        }
        break;

      case SKIP:
        if (isSpace(s[i])) {
          i++;
        } else {
          state = READCHAR;
        }
        break;

      case DUMP:
        if (j < 0) {
          lexEme[j] = 0;
          strLst.push_back(lexEme);
          j = 0;
        }
        state = START;
        break;

      case COMMENT:
        if (s[i] != '\n') {
          i++;
        } else {
          state = READCHAR;
        }
        break;

      case END:
        i = len;
        break;
    }
  }

  if (j > 0) {
    lexEme[j] = 0;
    strLst.push_back(lexEme);
  }

  return strLst;
}

// This function allows us what a space is
bool Lexer::isSpace(char c) {
  switch (c) {
    case '\n':

    case '\r':

    case '\t':

    case '\v':

    case ' ':

    case '\f':
      return true;

    default:
      return false;

  }
}

bool Lexer::isGroup(char c) {
  beg_char = c;
  switch (c) {
    case '"':
      end_char = '"';
      return true;

    case '(' :
      end_char = ')';
      return true;

    case ')':
      return true;

    default:
      return false;
  }
}

bool isSpecial(char c) {
  switch (c) {
    case '[':

    case ']':
      return true;

    default:
      return false;
  }
}

sasm.cpp:

#include <fstream>
#include "lexer.h"

typedef uint32_t i32;

using namespace std;

vector<i32> compile(strings s);
bool isInteger(string s);
bool isPrimitive(string s);
i32 mapToNumber(string s);

int main (int argc, char* argv[]) {
  // Check for input errors

  if (argc != 2) {
    cerr << "Usage: " << argv[0] << " <sasm-file>" << endl;
    exit(1);
  }

  // Read input file
  ifstream infile;
  infile.open(argv[1]);
  if (!infile.is_open()) {
    cerr << argv[1] << ": file can't be found" << endl;
    exit(1);
  }

  string line;
  string contents;
  while (getline(infile, line)) {
    contents += line + "\n";
  }
  infile.close();

  // Parse infile
  Lexer lexer;
  strings lexEmes = lexer.lex(contents);

  // Compile binary
  vector<i32> instructions = compile(lexEmes);

  // Write instructions to file
  ofstream ofile;
  ofile.open("out.bin", ios::binary);
  for (i32 i = 0; i < instructions.size(); i++) {
    ofile.write(reinterpret_cast<char*>(&instructions[i]), sizeof(i32));
  }
  ofile.close();

  return 0;
}

vector<i32> compile(strings s) {
  vector<i32> instructions;
  for (i32 i = 0; i < s.size(); i++) {
    if (isInteger(s[i])) {
      instructions.push_back(stoi(s[i]));
    } else {
      i32 instruction = mapToNumber(s[i]);
      if (instruction != -1) {
        instructions.push_back(instruction);
      } else {
        cerr << "\033[1;31m" << s[i] << "\033[0m Invalid instruction" << std::endl;
      }
    }
  }

  return instructions;
}

bool isInteger(string s) {
  for (i32 i = 0; i < s.length(); i++) {
    if (!isdigit(s[i])) {
      return false;
    }
  }

  return true;
}

i32 mapToNumber(string s) {
  if (s == "+") {
    return ADD;
  } else if (s == "-") {
    return SUB;
  } else if (s == "*") {
    return TIME;
  } else if (s == "/") {
    return DIVIDE;
  }

  return -1; // Invalid instruction
}

Спасибоза ваши ответы.

1 Ответ

0 голосов
/ 07 марта 2019

Отсутствует ссылка на класс в определении функции.

bool Lexer::isSpecial(char c)
     ^^^^^^^
...