i have this code style for one question

#include <sstream>
#include <iostream>

#include <string>
#include <vector>
#include <deque>
#include <map>
#include <set>

using namespace std;

void printErr(int errorPointer) {
    cerr << "ERROR at " << errorPointer + 1 << endl;
}

void print(vector<pair<string, int>> stack, int position, deque<string> inputs) {
    for (auto pair : stack) {
        if (pair.first != "") {
            cout << pair.first << " ";
        }
    }

    cout << ". ";

    for (size_t i = position; i < inputs.size(); ++i) {
        cout << inputs[i] << " ";
    }

    cout << endl;
}

int main() {
    string line;
    vector<pair<string, vector<string>>> cfg;
    deque<string> inputs;

    map<pair<int, string>, int> transitions;
    map<pair<int, string>, int> reductions;
    set<int> accept;

    int cfgIt = 0;
    string start = "";

    while (getline(cin, line)) {
        if (line == ".CFG") {
            continue;
        }
        if (line == ".INPUT") {
            break;
        }

        istringstream iss(line);
        string cfgStart;
        string it;

        vector<string> cfgResult;
        iss >> cfgStart;

        if (cfgIt == 0) {
            start = cfgStart;
        }

        while (iss >> it) {
            if (it == ".EMPTY") {
                cfgResult.clear();
                break;
            }
            cfgResult.push_back(it);
        }

        cfg.push_back({cfgStart, cfgResult});
        
        cfgIt++;
    }

    while (getline(cin, line)) {
        if (line == ".TRANSITIONS") {
            break;
        }

        istringstream iss(line);
        string it;
        while (iss >> it) {
            inputs.push_back(it);
        }
    }

    while (getline(cin, line)) {
        if (line == ".REDUCTIONS") {
            break;
        }

        istringstream iss(line);
        string it;
        int state, nextState;

        iss >> state >> it >> nextState;
        transitions[{state, it}] = nextState;
    }

    while (getline(cin, line)) {
        if (line == ".END") {
            break;
        }

        istringstream iss(line);
        int state, target;
        string token;
        
        iss >> state >> target >> token;

        if (token == ".ACCEPT") {
            accept.insert(state);
        } else {
            reductions[{state, token}] = target;
            while (iss >> token) {
                reductions[{state, token}] = target;
            }
        }
    }

    // stack of values and respective location
    // important for slr(1) parsing
    vector<pair<string, int>> stack = {{"", 0}};

    print(stack, 0, inputs);

    int curr = 0;
    int errorPointer = 0;

    while (true) {
        int currentState = stack[stack.size() - 1].second;
        string nextV = "";

        int s = inputs.size();
        if (curr < s) {
            nextV = inputs[curr];
        }
        
        if (accept.count(currentState)) {
            cout << start << " ." << endl;
            break;
        }

        if (reductions.find({currentState, nextV}) != reductions.end()) {
            auto targetValue = reductions.find({currentState, nextV});
            auto target = targetValue->second;

            int cs = cfg.size();
            
            if (target > cs) {
                printErr(errorPointer);
                break;
            }

            auto rule = cfg[target];
            auto cfgResult = rule.second;

            // pop based on number from cfg vals
            for (size_t i = 0; i < cfgResult.size(); ++i) {
                if (stack.empty()) {
                    printErr(errorPointer);
                    return 0;
                }

                stack.pop_back();
            }
            
            // continue from top of stack
            int topOfStack = stack[stack.size() - 1].second;

            if (transitions.find({topOfStack, rule.first}) != transitions.end()) {
                int newS = transitions[{topOfStack, rule.first}];
                stack.push_back({rule.first, newS});
            } else {
                printErr(errorPointer);
                return 0;
            }

            print(stack, curr, inputs);

        } else {
            if (transitions.find({currentState, nextV}) != transitions.end()) {
                string symbol = nextV;
                int newS = transitions.find({currentState, nextV})->second;

                stack.push_back({symbol, newS});

                // cout << errorPointer << endl;
                curr++;
                errorPointer++;

                print(stack, curr, inputs);
            } else {
                printErr(errorPointer);
                return 0;
            }
        }
    }

    return 0;
}

acknowledge variables, methods of parsing, the way i have my stack as one instead of two distinct things and more. for example, instead of distinct parsing functions, use my parsing strategy from above. also, base this new code below off of the strategies of the previous code, whcih was for another question though. now we are using a Node. do not use this many helper functions, streamline as much asyou can into the main(). keep some of the helper functions that you have in the original above. rewrite the code below to follow my instructions. return as ``` code block in c++```

#include <string>
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <sstream>
#include "wlp4data.h"
using namespace std;

struct Token {
    string kind;
    string lexeme;
};

class Node {
public:
    string value;
    vector<Node*> children;

    Node(const string &val) : value(val) {}
};

map<int, pair<string, vector<string>>> cfgRules;
vector<Token> inputSequence;
vector<int> stateStack;
vector<Node*> symbolStack;
Node *root = nullptr;

map<pair<int, string>, int> transitions;
map<int, vector<pair<int, set<string>>>> reductions;

set<string> terminals;
set<string> nonTerminals;

size_t inputPos = 0;

vector<string> split(const string &line) {
    vector<string> tokens;
    istringstream iss(line);
    string token;
    while (iss >> token) {
        tokens.push_back(token);
    }
    return tokens;
}

string join(const vector<string> &vec, const string &delim) {
    ostringstream oss;
    for (size_t i = 0; i < vec.size(); ++i) {
        oss << vec[i];
        if (i + 1 < vec.size()) oss << delim;
    }
    return oss.str();
}

void parseCFG(const string &cfgData) {
    istringstream cfgStream(cfgData);
    string line;
    int ruleIndex = 0;

    while (getline(cfgStream, line)) {
        if (line == ".CFG") continue;
        vector<string> tokens = split(line);
        if (tokens.empty()) continue;

        string lhs = tokens[0];
        vector<string> rhs;

        if (tokens.size() == 2 && tokens[1] == ".EMPTY") {
            rhs = {};
        } else {
            rhs.assign(tokens.begin() + 1, tokens.end());
        }

        cfgRules[ruleIndex++] = {lhs, rhs};
        nonTerminals.insert(lhs);
        for (const auto &sym : rhs) {
            if (!nonTerminals.count(sym)) {
                terminals.insert(sym);
            }
        }
    }
}

void parseTransitions(const string &transData) {
    istringstream transStream(transData);
    string line;
    while (getline(transStream, line)) {
        if (line == ".TRANSITIONS") continue;
        vector<string> tokens = split(line);
        if (tokens.size() != 3) continue;
        int fromState = stoi(tokens[0]);
        string symbol = tokens[1];
        int toState = stoi(tokens[2]);
        transitions[{fromState, symbol}] = toState;
    }
}

void parseReductions(const string &redData) {
    istringstream redStream(redData);
    string line;
    while (getline(redStream, line)) {
        if (line == ".REDUCTIONS") continue;
        vector<string> tokens = split(line);
        if (tokens.empty()) continue;

        int state = stoi(tokens[0]);
        int ruleNumber = stoi(tokens[1]);
        set<string> lookaheads(tokens.begin() + 2, tokens.end());
        reductions[state].push_back({ruleNumber, lookaheads});
    }
}

void parseInput() {
    string line;
    while (getline(cin, line)) {
        vector<string> tokens = split(line);
        if (tokens.size() >= 2) {
            inputSequence.push_back({tokens[0], tokens[1]});
        }
    }
    inputSequence.push_back({"EOF", "EOF"});
}

void executeParsing() {
    size_t shiftedTokens = 0;
    stateStack.push_back(0);

    string bofSymbol = "BOF";
    auto transIt = transitions.find({stateStack.back(), bofSymbol});
    if (transIt != transitions.end()) {
        Node *bofNode = new Node("BOF BOF");
        symbolStack.push_back(bofNode);
        stateStack.push_back(transIt->second);
    } else {
        cerr << "ERROR at 1\n";
        return;
    }

    while (true) {
        int currentState = stateStack.back();

        string nextKind;
        if (inputPos < inputSequence.size()) {
            nextKind = inputSequence[inputPos].kind;
        } else {
            nextKind = "";
        }

        auto redIt = reductions.find(currentState);
        if (redIt != reductions.end()) {
            bool reduced = false;
            for (const auto &red : redIt->second) {
                int ruleNumber = red.first;
                const auto &lookaheads = red.second;

                if (lookaheads.count(nextKind) || lookaheads.count(".ACCEPT")) {
                    const auto &rule = cfgRules[ruleNumber];
                    const string &lhs = rule.first;
                    const vector<string> &rhs = rule.second;

                    Node *parentNode = new Node(lhs + " " + (rhs.empty() ? ".EMPTY" : join(rhs, " ")));

                    for (int i = rhs.size() - 1; i >= 0; --i) {
                        if (!symbolStack.empty()) {
                            parentNode->children.insert(parentNode->children.begin(), symbolStack.back());
                            symbolStack.pop_back();
                        }
                        if (!stateStack.empty()) stateStack.pop_back();
                    }

                    symbolStack.push_back(parentNode);

                    currentState = stateStack.back();
                    auto transIt = transitions.find({currentState, lhs});
                    if (transIt != transitions.end()) {
                        stateStack.push_back(transIt->second);
                    } else if (lookaheads.count(".ACCEPT")) {
                        root = parentNode; 
                        return;
                    } else {
                        cerr << "ERROR at " << (shiftedTokens + 1) << "\n";
                        return;
                    }

                    reduced = true;

                    if (lookaheads.count(".ACCEPT")) {
                        root = parentNode;
                        Node *eofNode = new Node("EOF EOF");
                        symbolStack.push_back(eofNode);
                        root->children.push_back(eofNode);
                        return;
                    }

                    break;
                }
            }
            if (reduced) continue;
        }

        if (inputPos < inputSequence.size()) {
            string nextKind = inputSequence[inputPos].kind;
            auto transIt = transitions.find({currentState, nextKind});
            if (transIt != transitions.end()) {
                Node *leafNode = new Node(nextKind + " " + inputSequence[inputPos].lexeme);
                symbolStack.push_back(leafNode);
                stateStack.push_back(transIt->second);
                inputPos++;
                shiftedTokens++;
            } else {
                cerr << "ERROR at " << (shiftedTokens + 1) << "\n";
                return;
            }
        } else {
            cerr << "ERROR at " << (shiftedTokens + 1) << "\n";
            return;
        }
    }
}


void printParseTree(Node *node) {
    if (!node) return;
    cout << node->value << "\n";
    for (auto child : node->children) {
        printParseTree(child);
    }
}

void deleteParseTree(Node *node) {
    if (!node) return;
    for (auto child : node->children) {
        deleteParseTree(child);
    }
    delete node;
}

void cleanUpForErroredParse() {
    for (auto node : symbolStack) {
        deleteParseTree(node);
    }
    symbolStack.clear();
}

int main() {
    parseCFG(WLP4_CFG);
    parseTransitions(WLP4_TRANSITIONS);
    parseReductions(WLP4_REDUCTIONS);

    parseInput();
    executeParsing();

    if (root) {
        printParseTree(root);
        deleteParseTree(root);
    } else {
        cleanUpForErroredParse();
    }

    return 0;
}