[692] | 1 | #include <vrmllib/node.h>
|
---|
| 2 |
|
---|
| 3 | #include <iostream>
|
---|
| 4 | #include <stdexcept>
|
---|
| 5 |
|
---|
| 6 | #include <vrmllib/file.h>
|
---|
| 7 |
|
---|
| 8 | namespace vrmllib {
|
---|
| 9 | namespace bits {
|
---|
| 10 |
|
---|
| 11 | void parse_value(node *&n, std::istream &s, file &data)
|
---|
| 12 | {
|
---|
| 13 | std::string word;
|
---|
| 14 | s >> word;
|
---|
| 15 | if (!s)
|
---|
| 16 | throw std::runtime_error("parse error: end of file wile reading node");
|
---|
| 17 | n = node::parse_node_xdef(s, data, word);
|
---|
| 18 | }
|
---|
| 19 |
|
---|
| 20 | } // namespace bits
|
---|
| 21 |
|
---|
| 22 | node::~node()
|
---|
| 23 | {
|
---|
| 24 | }
|
---|
| 25 |
|
---|
| 26 | void node::parse_attribute(const std::string &name, std::istream &s, file &data)
|
---|
| 27 | {
|
---|
| 28 | std::cerr << "unknown attribute: " << name << std::endl;
|
---|
| 29 | std::string val;
|
---|
| 30 | s >> val;
|
---|
| 31 | if (!s)
|
---|
| 32 | throw std::runtime_error("parse error: end of file while reading unknown attribute");
|
---|
| 33 | if (val == "[") {
|
---|
| 34 | char c = 0;
|
---|
| 35 | int depth = 1;
|
---|
| 36 | s >> c;
|
---|
| 37 | while (depth != 0) {
|
---|
| 38 | if (!(s >> c))
|
---|
| 39 | throw std::runtime_error("parse error: end of file while scanning for end of unknown attribute");
|
---|
| 40 | if (c == '[')
|
---|
| 41 | ++depth;
|
---|
| 42 | else if (c == ']')
|
---|
| 43 | --depth;
|
---|
| 44 | }
|
---|
| 45 | } else if (val == "TRUE" || val == "FALSE" || val[0] == '-' || isdigit(val[0])) {
|
---|
| 46 | char c;
|
---|
| 47 | while (s.get(c) && c != '\n' && c != '\r')
|
---|
| 48 | ;
|
---|
| 49 | if (!s)
|
---|
| 50 | throw std::runtime_error("parse error: end of file while scanning for end of line");
|
---|
| 51 | } else {
|
---|
| 52 | parse_node_xdef(s, data, val);
|
---|
| 53 | }
|
---|
| 54 | }
|
---|
| 55 |
|
---|
| 56 | node *node::parse_node(std::istream &s, file &data,
|
---|
| 57 | const std::string &type)
|
---|
| 58 | {
|
---|
| 59 | node *n = create_node(type);
|
---|
| 60 | if (!n) {
|
---|
| 61 | char c = 0;
|
---|
| 62 | int depth = 1;
|
---|
| 63 | s >> c;
|
---|
| 64 | if (c != '{')
|
---|
| 65 | throw std::runtime_error(
|
---|
| 66 | std::string("parse error: expected {, got: ") + c);
|
---|
| 67 | while (depth != 0) {
|
---|
| 68 | if (!(s >> c))
|
---|
| 69 | throw std::runtime_error("parse error: end of file while scanning for end of unknown node");
|
---|
| 70 | if (c == '{')
|
---|
| 71 | ++depth;
|
---|
| 72 | else if (c == '}')
|
---|
| 73 | --depth;
|
---|
| 74 | }
|
---|
| 75 | return 0;
|
---|
| 76 | }
|
---|
| 77 | data.nodes.push_back(n);
|
---|
| 78 |
|
---|
| 79 | char c;
|
---|
| 80 | s >> c;
|
---|
| 81 | if (c != '{')
|
---|
| 82 | throw std::runtime_error(
|
---|
| 83 | std::string("parse error: expected {, got: ") + c);
|
---|
| 84 |
|
---|
| 85 | std::string str;
|
---|
| 86 | for (;;) {
|
---|
| 87 | s >> c;
|
---|
| 88 | if (c == '}')
|
---|
| 89 | break;
|
---|
| 90 | else
|
---|
| 91 | s.putback(c);
|
---|
| 92 |
|
---|
| 93 | s >> str;
|
---|
| 94 | n->parse_attribute(str, s, data);
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | return n;
|
---|
| 98 | }
|
---|
| 99 |
|
---|
| 100 | node *node::parse_node_xdef(std::istream &s, file &data, const std::string &fword)
|
---|
| 101 | {
|
---|
| 102 | if (fword == "DEF") {
|
---|
| 103 | std::string word;
|
---|
| 104 | s >> word;
|
---|
| 105 | std::string name = word;
|
---|
| 106 | s >> word;
|
---|
| 107 | node *n = parse_node(s, data, word);
|
---|
| 108 | node *&dest = data.defs[name];
|
---|
| 109 | if (dest)
|
---|
| 110 | throw std::runtime_error(
|
---|
| 111 | "parse error: node already defined: " + name);
|
---|
| 112 | return dest = n;
|
---|
| 113 | } else if (fword == "USE") {
|
---|
| 114 | std::string word;
|
---|
| 115 | s >> word;
|
---|
| 116 | if (node *n = data.defs[word])
|
---|
| 117 | return n;
|
---|
| 118 | else
|
---|
| 119 | throw std::runtime_error(
|
---|
| 120 | "parse error: node is not defined: " + word);
|
---|
| 121 | } else
|
---|
| 122 | return parse_node(s, data, fword);
|
---|
| 123 | }
|
---|
| 124 |
|
---|
| 125 | } // namespace vrmllib
|
---|