c ++:在外部声明和填充地图

c++: declaring and populating map externally

所以我一直在努力整理我的代码,想知道是否有一种方法可以声明我的地图并将它们填充到其他文件甚至其他函数中。

到目前为止,这是我的代码:(这使用了一个我没有代码的内置标记器,但基本上映射存储了输入机器代码的二进制文件,并将输出 a 指令和 c 指令取决于输入)

代码:

// 将 Hack 汇编转换为二进制

#include <iostream>
#include "tokens.h"
#include <bitset>
#include <cctype>
#include <string>
#include <map>

using namespace std ;

bool isNumber(string s){
    for (size_t n = 0; n < s.length(); n++){
        if (!(isdigit(s[n]))){
            return false;
        } else {
            return true;
        }
    }    
}

int main(){
// Declaring lookup tables (want to make this global [seperate file])
std::map<std::string, std::string> compTable;
std::map<std::string, std::string> destTable;
std::map<std::string, std::string> jumpTable;

// Inserting table data (want to make this global [seperate file])
// Jump Table Data
    jumpTable.insert(pair<string, string> ("NULL", "000"));
    jumpTable.insert(pair<string, string> ("JGT", "001"));
    jumpTable.insert(pair<string, string> ("JEQ", "010"));
    jumpTable.insert(pair<string, string> ("JGE", "011"));
    jumpTable.insert(pair<string, string> ("JLT", "100"));
    jumpTable.insert(pair<string, string> ("JNE", "101"));
    jumpTable.insert(pair<string, string> ("JLE", "110"));
    jumpTable.insert(pair<string, string> ("JMP", "111"));

// Dest Table Data
    destTable.insert(pair<string, string> ("NULL", "000"));
    destTable.insert(pair<string, string> ("M", "001"));
    destTable.insert(pair<string, string> ("D", "010"));
    destTable.insert(pair<string, string> ("MD", "011"));
    destTable.insert(pair<string, string> ("A", "100"));
    destTable.insert(pair<string, string> ("AM", "101"));
    destTable.insert(pair<string, string> ("AD", "110"));
    destTable.insert(pair<string, string> ("AMD", "111"));

// Comp Table Data
    // When a=1
    compTable.insert(pair<string, string> ("0", "1110101010"));
    compTable.insert(pair<string, string> ("1", "1110111111"));
    compTable.insert(pair<string, string> ("-1", "1110111010"));
    compTable.insert(pair<string, string> ("D", "1110001100"));
    compTable.insert(pair<string, string> ("A", "1110110000"));
    compTable.insert(pair<string, string> ("!D", "1110001101"));
    compTable.insert(pair<string, string> ("!A", "1110110001"));
    compTable.insert(pair<string, string> ("-D", "1110001111"));
    compTable.insert(pair<string, string> ("-A", "1110110011"));
    compTable.insert(pair<string, string> ("D+1", "1110011111"));
    compTable.insert(pair<string, string> ("A+1", "1110110111"));
    compTable.insert(pair<string, string> ("D-1", "1110001110"));
    compTable.insert(pair<string, string> ("A-1", "1110110010"));
    compTable.insert(pair<string, string> ("D+A", "1110000010"));
    compTable.insert(pair<string, string> ("D-A", "1110010011"));
    compTable.insert(pair<string, string> ("A-D", "1110000111"));
    compTable.insert(pair<string, string> ("D&A", "1110000000"));
    compTable.insert(pair<string, string> ("D|A", "1110010101"));
    // when a=0
    compTable.insert(pair<string, string> ("M", "1111110000"));
    compTable.insert(pair<string, string> ("!M", "1111110001"));
    compTable.insert(pair<string, string> ("-M", "1111110011"));
    compTable.insert(pair<string, string> ("M+1", "1111110111"));
    compTable.insert(pair<string, string> ("M-1", "1111110010"));
    compTable.insert(pair<string, string> ("D+M", "1111000010"));
    compTable.insert(pair<string, string> ("D-M", "1111010011"));
    compTable.insert(pair<string, string> ("M-D", "1111000111"));
    compTable.insert(pair<string, string> ("D&M", "1111000000"));
    compTable.insert(pair<string, string> ("D|M", "1111010101"));

// Declaring Variables
    string temp;
    string tempValue;
    int skipLine = 0;
    int tokenCounter = 0;

// create a new assembler tokeniser then read the first token
tokens *tokeniser = new tokens(getchar) ;
std::string token = tokeniser->next_token() ;

while ( token != "?" )          // stop at EOF, "?" denotes EOF
{
    if(tokenCounter > 0) {
        cout << endl;
    }
    if(skipLine == 1) {
        cout << endl;
    }
    skipLine = 0;
    if(token == "address"){
        string adrsStr = tokeniser->token_value();
        if(isNumber(adrsStr)==true){
            int adrs = stoi(adrsStr);
            cout << bitset<16>(adrs);
        }
    }
    if(token == "comp" || token == "dest" || token == "dest-comp?" || token == "null"){
        tempValue = tokeniser->token_value();
        temp = token;
        token = tokeniser->next_token() ;
        if(token == "equals"){
            token = tokeniser->next_token() ;
            if(temp == "null") {
                    std::cout << compTable.find(tokeniser->token_value())->second;
                    std::cout << destTable.find("NULL")->second;
                    std::cout << jumpTable.find("NULL")->second;
            }else if(temp == "dest" || temp == "dest-comp?"){
                if (token == "comp" || token == "dest-comp?"){
                    std::cout << compTable.find(tokeniser->token_value())->second;
                    std::cout << destTable.find(tempValue)->second;
                    std::cout << jumpTable.find("NULL")->second;
                }
            }
        }else if(token == "semi") {
            std::cout << compTable.find(tempValue)->second;
            std::cout << destTable.find("NULL")->second;    
            token = tokeniser->next_token() ;
            if (token == "jump"){
                std::cout << jumpTable.find(tokeniser->token_value())->second;
            } else if(token == "null") {
                std::cout <<jumpTable.find("NULL")->second;
            }
        }else if (token != "equal" || token != "semi"){
            std::cout << compTable.find(tempValue)->second;
            std::cout << destTable.find("NULL")->second;  
            std::cout << jumpTable.find("NULL")->second;
            if (token!= "semi" || token!="equals"){
                skipLine=1;
                continue;
            }
        }
    }
    tokenCounter++;
    token = tokeniser->next_token() ;


}
cout << endl;
/*cout << jumpTable.find("NULL")->second << endl;
cout << compTable.find("A")->second << endl;
cout << destTable.find("A")->second << endl;*/
return 0 ;
}

地图的首选格式将包含一个用于在外部声明地图的 create() 函数和一个用于填充地图的 insert() 函数

这可能吗?

另一种在 C++11 中检查字符串是否为数字的方法:

bool isNumber(const string& str) {
    int res = std::accumulate(str.begin(), str.end(), 0, [](int r, char c){return r += isdigit(c);});

    return (res == str.size());
}

您可以这样做:

std::map<std::string, std::string> make_jump_table()
{
    return {
        {"NULL", "000"},
        {"JGT", "001"},
        {"JEQ", "010"},
        {"JGE", "011"},
        {"JLT", "100"},
        {"JNE", "101"},
        {"JLE", "110"},
        {"JMP", "111"}
    };
}

用老式的方法怎么样?通过使用 extern 并提供 main() 应该调用的函数,该函数执行所有插入。

我写了一个例子,基于 this,你可以根据它编写你的代码(我不能这样做,因为我没有你的令牌头)。

main.cpp

#include <iostream>
#include <map>
#include "myMap.h"

std::map<char,int> mymap;

int main ()
{
  myMapInsertions(mymap);

  std::cout << "mymap contains:\n";
  for (std::map<char,int>::iterator it=mymap.begin(); it!=mymap.end(); ++it)
    std::cout << it->first << " => " << it->second << '\n';

  return 0;
}

myMap.h

#ifndef MYMAP_H_
#define MYMAP_H_

#include <map>

extern std::map<char,int> mymap;

void myMapInsertions(std::map<char,int>& mymap);

#endif // MYMAP_H_

myMap.cpp

#include "myMap.h"

void myMapInsertions(std::map<char,int>& mymap)
{
    mymap.insert ( std::pair<char,int>('a',100) );
    mymap.insert ( std::pair<char,int>('z',200) );
}

这样编译:

g++ -Wall main.cpp myMap.cpp -o main


在此处了解 extern 关键字:When to use extern in C++?