Link 编译基本汇编程序时出错
Link error when compiling basic assembler
我试图创建一个特殊的汇编器,它将 运行 用于特定的机器类型。我试图编译程序,但出现链接器错误:
/usr/bin/ld: lexer.o: 在函数`Lexer::lex(std::__cxx11::basic_string , std::allocator >)':
lexer.cpp:(.text+0x2ee): 未定义对`Lexer::isSpecial(char)'的引用
collect2:错误:ld 返回 1 退出状态
Screenshot here
我有 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 << "3[1;31m" << s[i] << "3[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
}
感谢您的回答。
您在函数定义中缺少 class 引用。
bool Lexer::isSpecial(char c)
^^^^^^^
我试图创建一个特殊的汇编器,它将 运行 用于特定的机器类型。我试图编译程序,但出现链接器错误:
/usr/bin/ld: lexer.o: 在函数`Lexer::lex(std::__cxx11::basic_string , std::allocator >)':
lexer.cpp:(.text+0x2ee): 未定义对`Lexer::isSpecial(char)'的引用
collect2:错误:ld 返回 1 退出状态
Screenshot here
我有 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 << "3[1;31m" << s[i] << "3[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
}
感谢您的回答。
您在函数定义中缺少 class 引用。
bool Lexer::isSpecial(char c)
^^^^^^^