Я изо всех сил пытаюсь понять логику с помощью моей таблицы символов, и теперь я машу белым флагом и прошу помочь. Я создаю таблицу символов, используя векторы, но мне трудно помещать запись в таблицу символов (строка на данный момент, структура позже) в правильной области. Мой код имеет 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 область объявленной переменной начинается с объявления, а не в начале закрывающего блока. Однако это может быть достаточно хорошим для создания AST, если вы выполняете все поисковые запросы символов, когда вы анализируете вход слева направо.
{q}
является родным братом{b}
, не вложенным в него. Я бы сказал, что вам нужно переосмыслить свою модель хранения данных, если вы собираетесь представлять этот вход в виде дерева. Один стек уровней области видимости слишком наивен.