C++ 使用向量的符号表

C++ 使用向量的符号表,c++,compiler-construction,C++,Compiler Construction,我一直在绞尽脑汁试图找出实现我的符号表的逻辑&现在我挥舞着白旗,寻求帮助。我正在使用vectors创建一个符号表,但是我现在很难将符号表条目放在字符串中,稍后将其放在正确的范围中。我的代码有一个int scopenum,它在每次打开块时递增{在每次关闭块时递减}。但是,该行会导致一个问题: {a{b}{q}}因为它把q放在范围2中,而它应该在范围3中。我的代码将新行推送到向量上,但在插入中不使用它。如何修改代码以正确说明打开和关闭作用域 #include <iostream> #in

我一直在绞尽脑汁试图找出实现我的符号表的逻辑&现在我挥舞着白旗,寻求帮助。我正在使用vectors创建一个符号表,但是我现在很难将符号表条目放在字符串中,稍后将其放在正确的范围中。我的代码有一个int scopenum,它在每次打开块时递增{在每次关闭块时递减}。但是,该行会导致一个问题: {a{b}{q}}因为它把q放在范围2中,而它应该在范围3中。我的代码将新行推送到向量上,但在插入中不使用它。如何修改代码以正确说明打开和关闭作用域

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int stacknum=-1;
vector< vector<string> > v;

void display(){
    for(int i=0; i<v.size(); i++){
        cout << "Scope " << i+1 << ": " << endl;
        for(int j=0; j<v[i].size(); j++)
            cout << v[i][j] << endl;
        cout << endl;
    }
}

void insert(string s){
    v[stacknum].push_back(s);
}

int main(){
    string data;
    ifstream file;
    file.open("input");

    if(!file.is_open()) {
        cout << "Input file not found";
        return 1; }

    while(file >> data){
        if(data=="{"){
            stacknum++;
            vector<string> row;
            v.push_back(row);
            continue;
        }

        if(data=="}"){
            stacknum--;
            continue;
        }

        insert(data);
    }
    file.close();

    display();

    return 0;
}

您不能仅使用索引跟踪当前范围;你需要一堆。或者,可能更有用的是,您需要记录每个范围的父范围,您可以使用第二个向量或通过在范围对象中包含额外的数据成员来完成

在这两种情况下,当您输入一个新范围时,您将创建一个新的范围对象,即符号向量,并在范围对象向量的末尾创建关联的父范围索引,并使该对象的索引成为当前范围索引。离开作用域时,当前作用域索引将设置为当前作用域的父级

父指针在搜索符号时很有用;您需要搜索当前作用域的所有父项,直到找到符号为止


根据您试图建模的范围规则,这可能是不够的。例如,它不能准确地建模C的作用域规则,因为在C中,已声明变量的作用域从声明开始,而不是从封闭块开始。但是,只要在从左到右解析输入时按顺序查找所有符号,就足以构建AST

为什么它应该在范围3中?{q} 是{b}的兄弟,而不是嵌套在其中。我想说,如果您希望以树的形式表示这些输入,那么您需要重新考虑您的数据存储模型。单个范围级别堆栈太幼稚了。与其像您一样有一个非常扁平的结构,只有一个嵌套向量只允许单个级别的嵌套,不如想想树。嵌套向量可以工作吗?谷歌上的大多数结果都告诉我使用哈希表作为符号表,但它们不会有类似的功能吗?我正在描绘2D向量的每一行,表示变量范围{inta;float b;}。我只需要把代码放进右边的行。标准C++库中的HASH表比普通向量更好。但对于任意嵌套作用域所需的树状结构,它仍然没有帮助。相反,每个作用域都有一个结构,其中包含嵌套作用域的容器。然后在嵌套作用域中使用相同的结构,这将为您提供一个具有无限嵌套作用域的树状结构。