UVA 1596 Bug Hunt

第一次见到题目里带了个BNF,有意思。基本就是STL的map、stack应用。解析求值就按着编译器的来。赋值语句的右值、左值的参数、声明语句的参数需要求值到底,其余语句保留。栈arr用于存储当前操作的数组名,不过其实也可以不用栈。判断的函数可以内联,但是直接写出来更加清晰。

#include <iostream>
#include <map>
#include <string>
#include <stack>

using namespace std;

bool isArrayName(char c) {
    return 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z';
}

bool isNum(char c) {
    return '0' <= c && c <= '9';
}

string line;
map<char, map<int, int>> env;
map<char, int> sizes;
stack<char> arr; int num;

bool validInd() {
    char n = arr.top();
    return env.count(n) > 0 && 0 <= num && num < sizes[n];
}

bool parse(int st, int ed, bool rt) {
    int pEnd = st; bool bug;
    if (isArrayName(line[st])) {
        arr.push(line[st]);
        if (bug = parse(st + 2, ed - 1, true)) return true;
        if (rt) { // Query
            if (!validInd() || env[arr.top()].count(num) == 0)
                return true;
            num = env[arr.top()][num];
            arr.pop();
        }
    } else {
        // num
        while (++pEnd < ed && isNum(line[pEnd]));
        num = stoi(line.substr(st, pEnd));
    }
    return false;
}

int main() {
    int posEq, lineCnt = 0, rValue; bool flag = false, bug = false;
    while (cin >> line) {
        if (line[0] == '.') {
            if (flag) break;
            env.clear();
            sizes.clear();
            if (!bug) cout << 0 << endl;
            else if (lineCnt) cout << lineCnt << endl;
            lineCnt = 0;
            flag = true; bug = false;
            continue;
        }
        flag = false;
        if (bug) continue;
        // Read
        posEq = 0; lineCnt++;
        while (++posEq < line.size() && line[posEq] != '=');
        if (posEq == line.size()) {
            // declaration
            if (bug = parse(0, line.size() - 1, false))
                continue;
            sizes[arr.top()] = num;
            env[arr.top()] = map<int, int>();
            arr.pop();
        } else {
            // rt
            if (bug = parse(posEq + 1, line.size() - 1, true))
                continue;
            rValue = num;
            if (bug = parse(0, posEq, false)) continue;
            if (bug = !validInd()) continue;
            env[arr.top()][num] = rValue;
            arr.pop();
        }
    }
    return 0;
}

发布者:KAAAsS

喜欢二次元的程序员,喜欢发发教程,或者偶尔开坑。(←然而并不打算填)

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注