#include <istream>#include <iostream>#include <assert.h>#include "../string.h"#include "syntax_error.h"#include "parser.h"namespace nap{ namespace settings { parser::parser() { } parser::~parser() { } void parser::parse(std::istream& input) { while (!input.eof()) { char c; static std::string buf; static std::string ns; // current namespace static int line_num = 1; static bool in_string = false; static bool in_comment = false; c = input.get(); // Translate for systems that use \r\n or just \r as line // endings if (c == '\r') { c = input.get(); if (c != '\n') input.unget(); c = '\n'; } // Increment line_num if we encounter a new line... if (c == '\n') line_num++; // Are we in a comment? if (in_comment) { if (c == '\n') in_comment = false; continue; } // If we find a stray open-curly then buf should contain a // namespace declaration if (c == '{') { buf = string::strip_whitespace(buf); if (!is_identifier(buf)) throw syntax_error("expected valid identifier before " "'{' token", line_num); // namespace inside a namespace? if (!ns.empty()) ns += '.'; ns += buf; buf.clear(); } // close-curly signals the end of a namespace scope else if (c == '}') { if (ns.empty()) throw syntax_error("unexpected '}' token", line_num); ssize_t pos = ns.rfind('.'); if (pos == std::string::npos) ns.clear(); else ns = ns.substr(0, pos); } else buf += c; } } bool parser::is_identifier(const std::string& s) { const char vcs[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; return s.find_first_not_of(vcs) == std::string::npos; } }}