gpt4 book ai didi

c++ - 在 C++ 中从文件生成符号表

转载 作者:行者123 更新时间:2023-11-28 06:33:05 26 4
gpt4 key购买 nike

所以我试图从一个包含 C 风格嵌套 block 的输入文件生成一个符号表,就像在 C++ 中这样;

A: { int a; float b;
B: { float c; int d;
C: { int b; int c;
}
}
D: { float a;
}
}

输出应该是这样的。

A: a -> <int, A>
b -> <float, A>
B: a -> <int, A>
b -> <float, A>
c -> <float, B>
d -> <int, B>
C: a -> <int, A>
b -> <int, C> -> <float, A>
c -> <int C> -> <float, B>
d -> <int, local to B>
D: a -> <float D> -> <int, A>
b -> <float, A>

我已经尝试了很多东西。使用 vector 、 map ,现在我终于决定使用多重 map 。无论我做什么,我都会遇到同样的问题,所以它可能与我选择的数据结构无关。

问题是,因为我是逐行阅读,所以我最终计算的比我需要的多。但是,如果我没有计算/迭代 for 循环中每一行的多重映射,那么我会在它们被删除/弹出后进行迭代。我不确定如何在逻辑上明智地让输出按应有的方式显示,或者我是否走在正确的轨道上。

到目前为止,这是我的 .cpp 文件。忽略评论,因为它们是我暂时选择不使用的过去尝试。同样在这个版本中,我没有使用 vector ,所以你可以忽略与 vector 相关的代码。我现在只是在使用 multimap 。

#include<iostream>
#include<fstream>
#include<string>
#include <sstream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

void ReadFromFile();
void main(){

ReadFromFile();
cin.get();
}

void ReadFromFile(){

stringstream ss;
string type = "";
string var = "";
string lable = "";
string Obraket = "";
string Cbraket = "";
int braketCount = -1;

ifstream myfile("input1.txt");
multimap<string, string> symbol;
multimap<string, multimap<string, string>> symbolL;
if (myfile.is_open())
{
for (string line; getline(myfile, line);)
{

istringstream in(line);
if (in.str().find("}") == string::npos && in.str().find("{") != string::npos){

in >> lable;
in >> Obraket;

braketCount++;
cout << Obraket << endl;
in >> type;
in >> var;
symbol.insert(pair<string, string>(var.substr(0, 1), type));

if (in.str().find("float") != string::npos || in.str().find("int") != string::npos){

var = "";
type = "";
in >> type;
in >> var;
if (type.length() > 1){
symbol.insert(pair<string, string>(var.substr(0, 1), type));
}
}

symbolL.insert( pair<string, multimap<string, string>>(lable,symbol));

for (multimap<string, multimap<string, string>>::iterator it = symbolL.begin(); it != symbolL.end(); ++it){
cout << it->first;
for (multimap<string, string>::iterator it2 = symbol.begin(); it2 != symbol.end(); ++it2){
cout << it2->first << "-> " << "<" << it2->second << ">, " << it->first.substr(0, 1) << endl;
}
}
}
else if (in.str().find("}") != string::npos){
in >> Cbraket;
//braketCount--;
cout << Cbraket << endl;
symbolL.erase(prev(symbolL.end()));

//symbol.erase(prev(symbol.end()));
}

}

myfile.close();
}
else cout << "Unable to open file";



}

这是我得到的输出。

{
A:a-> <int>, A
b-> <float>, A
{
A:a-> <int>, A
b-> <float>, A
c-> <float>, A
d-> <int>, A
B:a-> <int>, B
b-> <float>, B
c-> <float>, B
d-> <int>, B
{
A:a-> <int>, A
b-> <float>, A
b-> <int>, A
c-> <float>, A
c-> <int>, A
d-> <int>, A
B:a-> <int>, B
b-> <float>, B
b-> <int>, B
c-> <float>, B
c-> <int>, B
d-> <int>, B
C:a-> <int>, C
b-> <float>, C
b-> <int>, C
c-> <float>, C
c-> <int>, C
d-> <int>, C
}
}
{
A:a-> <int>, A
a-> <float>, A
b-> <float>, A
b-> <int>, A
c-> <float>, A
c-> <int>, A
d-> <int>, A
D:a-> <int>, D
a-> <float>, D
b-> <float>, D
b-> <int>, D
c-> <float>, D
c-> <int>, D
d-> <int>, D
}
}

最佳答案

我会为顶层建议一个结构(即一个struct 或一个class),有一个std::那些顶级结构的 map 。然后每个结构依次包含一个 std::map 用于所包含的符号,同样具有一个包含符号类型等的结构。

就这么简单:

struct LocalSymbol
{
std::string name;
enum
{
FLOAT,
INT
} type;
// Possibly other information needed for local symbols
};

struct GlobalSymbol
{
std::string name;
// Possibly other information needed for global symbols
std::map<std::string, LocalSymbol> locals;
}

std::map<std::string, GlobalSymbol> globals;

这将很容易地为您提供您似乎想要的嵌套结构,并将所有保持相关的数据紧密地放在一起成为更小的结构。

您的另一个大问题似乎是解析,我建议您阅读更多关于编译器和解析的内容,并尝试实现一种更传统的词法分析器解析器类型的解析器,您将输入处理和解析分成两个部分。如果您想手动编写解析器部分,我建议使用 recursive descent style parser这将使处理范围和级别变得非常容易。

关于c++ - 在 C++ 中从文件生成符号表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27205850/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com