#include #include #include #include #include #include bool bracketsMatch(std::istream &in) { std::stack expectedDelimiters; int lineNum = 0; std::string line; while (std::getline(in, line)) { lineNum++; size_t pos = 0; while (std::string::npos != (pos = line.find_first_of("(){}[]", pos))) { int colNum = pos + 1; switch (line[pos]) { case '(': expectedDelimiters.push(')'); break; case '{': expectedDelimiters.push('}'); break; case '[': expectedDelimiters.push(']'); break; case ']': case '}': case ')': if (expectedDelimiters.empty()) { std::cout << "Mismatched " << line[pos] << " at line " << lineNum << ", col " << colNum << std::endl; return false; } if (line[pos] != expectedDelimiters.top()) { std::cout << "Expected " << expectedDelimiters.top() << ", found " << line[pos] << " at line " << lineNum << ", col " << colNum << std::endl; return false; } expectedDelimiters.pop(); } pos = colNum; } } // Should check for a possible input error here, but I didn't bother. if (!expectedDelimiters.empty()) { std::cout << "Expected " << expectedDelimiters.top() << " at end of file" << std::endl; return false; } return true; } int main(int argc, const char *argv[]) { // The command-line parsing below is a bit sloppy (no validation, // help message, or option handling, for example). std::ifstream f; std::istream &in = (argc > 1) ? (f.open(argv[1]), f) : std::cin; if (!in) { std::cerr << argv[0] << ": " << argv[1] << ": " << std::strerror(errno) << std::endl; return 2; // A rather arbitrary error code } return bracketsMatch(in) ? EXIT_SUCCESS : EXIT_FAILURE; }