Attribute Parser

  • + 0 comments

    `

    include

    include

    include

    include

    include

    include

    include

    include

    using namespace std;

    // The vector will have each tag we're nested inside. // so we'll iterate through that, then add the attribute onto the end // of the string to make the unique entry. string MakeEntry(vector& context, string& attribute) { string entry; for(auto& tag : context) { entry += tag; entry.push_back('.'); }

    // clear the last .
    entry.pop_back();
    entry.push_back('~');
    entry += attribute;
    
    return entry;
    

    }

    int main() { // fetch our data entry caps int lineNo, queryNo; cin >> lineNo >> queryNo; cin.get(); // clear

    // the map stores all of our entries 
    // e.g. { ("tag1.tag2~name", "name") }
    unordered_map<string, string> entries;
    vector<string> currentContext;
    
    for(int inputLine = 0; inputLine < lineNo; inputLine++)
    {
        // grab the whole line, then yeet the opening and closing brackets
        string line;
        getline(cin, line);
        line.pop_back();
        line = line.substr(1);
    
        // if the first character is / go back up a tag and
        // ignore the rest of the line, we don't need it.
        if(line[0] == '/')
        {
            currentContext.pop_back();
            continue;
        }
    
        // using a string stream here so we can loop through it.
        stringstream iss(line);
    
        // the first chunk will always be a new tag, so add it to our context
        string newContext;
        iss >> newContext;
        currentContext.push_back(newContext);
    
        string nextToken, attribute, value;
        while(iss >> nextToken)
        {
            // search for an equal incase it's embedded inside this chunk
            // e.g. foo=bar
            size_t equalPos = nextToken.find('=');
            if(equalPos != string::npos && nextToken.size() > 1)
            {
                // this chunk has an equal in it somewhere, so
                // it must be an attribute/value pair
                attribute = nextToken.substr(0, equalPos);
                value = nextToken.substr(equalPos+2, nextToken.size()-2);
    
                // add the pair to the map.
                string entry = MakeEntry(currentContext, attribute);
                entries.insert(make_pair(entry, value));
                attribute = ""; value ="";
            } else {
    
                // if the = is at the start or the size is < 1 skip!
                if(nextToken[0] == '=')
                {
                    continue;
                }
                // there's no = sign in this chunk...
                if(attribute == "")
                {
                    // we don't have a cached entry from a previous chunk
                    // so this is a new attribute.
                    attribute = nextToken;
                } else {
                    // otherwise, we now have a pair!
                    string entry = MakeEntry(currentContext, attribute);
    
                    // bit jank here, should ideally strip unwanted characters
                    // but this works.
                    entries.insert(make_pair(entry, nextToken.substr(equalPos+2, nextToken.size()-2)));
    
                    // clear for the next line so we don't double up.
                    attribute = ""; value = "";
                }
            }
        }
    }
    
     for(int query = 0; query < queryNo; query++)
     {
        string line;
        cin >> line;
    
        // we're literally just yeeting the whole line into the map to see if anything pops out.
        unordered_map<string, string>::const_iterator entry = entries.find(line);
        cout << (entry == entries.end() ? "Not Found!" : entry->second) << endl;
     }
         `
    

    test
    return 0; }

    `