90
查看原帖
90
84282
andyli楼主2023/11/22 21:33

#9

#include <bits/stdc++.h>

constexpr int mask = (1 << 27) - 1;
constexpr int unreachable = 1 << 26;
int main() {
    std::vector<std::string> program;
    std::string line;
    while (std::getline(std::cin, line)) {
        program.emplace_back(line);
    }
    std::vector<std::pair<int, int>> warnings;
    auto execute = [&](auto&& execute, auto it, auto end, int status) -> int {
        auto check = [&](int lid, char c) {
            if (!(status & (1 << (c - 'A')))) {
                warnings.emplace_back(lid, c);
            }
        };
        auto checkstr = [&](int lid, const std::string& s) {
            for (auto&& c: s) {
                if (isupper(c)) {
                    check(lid, c);
                }
            }
        };
        while (it != end) {
            auto&& line = *it;
            if (line.empty()) {
                ++it;
                continue;
            }
            if (status & unreachable) {
                if (!line.starts_with("END") && !line.starts_with("ELSE")) {
                    warnings.emplace_back(it - program.begin() + 1, -1);
                }
                ++it;
                continue;
            }
            if (line.starts_with("PARAM")) {
                for (auto&& c: line.substr(5)) {
                    if (isupper(c)) {
                        status |= 1 << (c - 'A');
                    }
                }
                ++it;
            }
            else if (line.starts_with("RETURN")) {
                checkstr(it - program.begin() + 1, line.substr(6));
                status |= mask;
                ++it;
            }
            else if (line.starts_with("IF")) {
                checkstr(it - program.begin() + 1, line.substr(3, line.size() - 8));
                auto endit = it;
                int dep = 1;
                while (dep) {
                    ++endit;
                    if (endit->starts_with("IF")) {
                        ++dep;
                    }
                    if (endit->starts_with("END")) {
                        --dep;
                    }
                    if (endit->starts_with("ELSE") && dep == 1) {
                        break;
                    }
                }
                if (endit->starts_with("ELSE")) {
                    auto it2 = endit;
                    while (dep) {
                        ++it2;
                        if (it2->starts_with("IF")) {
                            ++dep;
                        }
                        if (it2->starts_with("END")) {
                            --dep;
                        }
                    }
                    int status1 = execute(execute, it + 1, endit, status);
                    int status2 = execute(execute, endit + 1, it2, status);
                    status = status1 & status2;
                    it = it2 + 1;
                }
                else {
                    execute(execute, it + 1, endit, status);
                    it = endit + 1;
                }
            }
            else {
                checkstr(it - program.begin() + 1, line.substr(4));
                status |= 1 << (line[0] - 'A');
                ++it;
            }
        }
        return status;
    };
    execute(execute, program.begin(), program.end(), 0);
    std::sort(warnings.begin(), warnings.end());
    warnings.erase(std::unique(warnings.begin(), warnings.end()), warnings.end());
    for (auto&& [x, y]: warnings) {
        if (y == -1) {
            std::cout << "Line " << x << ": unreachable code\n";
        }
        else {
            std::cout << "Line " << x << ": variable " << char(y) << " might not have been initialized\n";
        }
    }
    return 0;
}
2023/11/22 21:33
加载中...