6
Tag() : value(""), isStart(true) {}7
Tag(string value, bool isStart) : value(value), isStart(isStart) {}10
pair<int, bool> parseCData(string &s, int pos) {11
// cout << "Parse cdata " << s.substr(pos) << endl;12
const string startPattern = "<![CDATA[";13
if (s.find(startPattern, pos) != pos) {17
const string endPattern = "]]>";18
int end = s.find(endPattern, pos);22
return {end + 3, true};25
pair<Tag, bool> parseTag(string &s, int &pos) {26
// cout << "Parse tag " << s.substr(pos) << endl;28
if (pos + 1 == s.length()) return {res, false};29
if (s[pos + 1] == '/') {34
int end = s.find(">", pos);35
if (end == -1 || end - pos < 1 || end - pos > 9) return {res, false};36
string name = s.substr(pos, end - pos);37
for (char &c : name) {38
if (c < 'A' || c > 'Z') return {res, false};44
bool isValid(vector<Tag> &tags, int start, int end) {45
// cout << start << " " << end << endl;46
if (start > end) return true;47
if (!tags[start].isStart) return false;50
while (k <= end && c > 0) {51
if (tags[k].value == tags[start].value) {52
c += (tags[k].isStart) ? 1 : -1;56
if (c != 0) return false;58
return isValid(tags, start + 1, k - 1) && isValid(tags, k + 1, end);62
bool isValid(string code) {64
int n = code.length();68
while (k < n && code[k] != '<') {72
if (i == 0) return false;74
if (i == n) return false;76
if (code[k + 1] == '!') {77
if (i == 0) return false;78
auto cdata = parseCData(code, k);79
if (!cdata.second) return false;81
if (i == n) return false;83
auto tag = parseTag(code, i);84
if (!tag.second) return false;85
if (i == n && tag.first.isStart) return false;86
tags.push_back(tag.first);90
if (tags.size() < 2) return false;92
if (tags[0].value != tags[m - 1].value || !tags[0].isStart || tags[m - 1].isStart) {95
return isValid(tags, 1, m - 2);