#include #include #include #include namespace vrmllib { namespace bits { void parse_value(node *&n, std::istream &s, file &data) { std::string word; s >> word; if (!s) throw std::runtime_error("parse error: end of file wile reading node"); n = node::parse_node_xdef(s, data, word); } } // namespace bits node::~node() { } void node::parse_attribute(const std::string &name, std::istream &s, file &data) { std::cerr << "unknown attribute: " << name << std::endl; std::string val; s >> val; if (!s) throw std::runtime_error("parse error: end of file while reading unknown attribute"); if (val == "[") { char c = 0; int depth = 1; s >> c; while (depth != 0) { if (!(s >> c)) throw std::runtime_error("parse error: end of file while scanning for end of unknown attribute"); if (c == '[') ++depth; else if (c == ']') --depth; } } else if (val == "TRUE" || val == "FALSE" || val[0] == '-' || isdigit(val[0])) { char c; while (s.get(c) && c != '\n' && c != '\r') ; if (!s) throw std::runtime_error("parse error: end of file while scanning for end of line"); } else { parse_node_xdef(s, data, val); } } node *node::parse_node(std::istream &s, file &data, const std::string &type) { node *n = create_node(type); if (!n) { char c = 0; int depth = 1; s >> c; if (c != '{') throw std::runtime_error( std::string("parse error: expected {, got: ") + c); while (depth != 0) { if (!(s >> c)) throw std::runtime_error("parse error: end of file while scanning for end of unknown node"); if (c == '{') ++depth; else if (c == '}') --depth; } return 0; } data.nodes.push_back(n); char c; s >> c; if (c != '{') throw std::runtime_error( std::string("parse error: expected {, got: ") + c); std::string str; for (;;) { s >> c; if (c == '}') break; else s.putback(c); s >> str; n->parse_attribute(str, s, data); } return n; } node *node::parse_node_xdef(std::istream &s, file &data, const std::string &fword) { if (fword == "DEF") { std::string word; s >> word; std::string name = word; s >> word; node *n = parse_node(s, data, word); node *&dest = data.defs[name]; if (dest) throw std::runtime_error( "parse error: node already defined: " + name); return dest = n; } else if (fword == "USE") { std::string word; s >> word; if (node *n = data.defs[word]) return n; else throw std::runtime_error( "parse error: node is not defined: " + word); } else return parse_node(s, data, fword); } } // namespace vrmllib