X-Git-Url: http://git.tdb.fi/?p=libs%2Fdatafile.git;a=blobdiff_plain;f=source%2Fparser.cpp;h=7e4d3dd7f93942b9d4c9c3b69f2715d93b25b492;hp=fce12e245b3f6ab011e4ca45851b0086847a4e5f;hb=705aca1ca0f63e7314a25f528e6e7c76765c04b8;hpb=01de40aa67599511f7843ab5b5aa24ec59a2768f diff --git a/source/parser.cpp b/source/parser.cpp index fce12e2..7e4d3dd 100644 --- a/source/parser.cpp +++ b/source/parser.cpp @@ -1,6 +1,7 @@ #include #include "binaryparser.h" -#include "dataerror.h" +#include "except.h" +#include "jsonparser.h" #include "parser.h" #include "statement.h" #include "textparser.h" @@ -14,16 +15,21 @@ Parser::Parser(IO::Base &i, const string &s): in(i), main_src(s), src(s), - good(true), - mode(new TextParser(in, src)) -{ } + good(true) +{ + char c = in.peek(); + if(c=='{' || c=='[') + mode = new JsonParser(in, src); + else + mode = new TextParser(in, src); +} Parser::~Parser() { delete mode; } -Statement Parser::parse() +Statement Parser::parse(bool raw) { if(!good) throw logic_error("Parser::parse() !good"); @@ -33,33 +39,16 @@ Statement Parser::parse() while(1) { Statement st = mode->parse(); - if(st.keyword=="__bin") + if(!st.keyword.compare(0, 2, "__")) { - delete mode; - mode = new BinaryParser(in, src); - } - else if(st.keyword=="__text") - { - delete mode; - mode = new TextParser(in, src); - } - else if(st.keyword=="__z") - in.set_decompress(); - else if(st.keyword=="__src") - { - string s = st.args[0].get(); - if(s.empty()) - src = main_src; - else - src = format("%s[%s]", main_src, s); - } - else if(st.keyword=="__end") - { - good = false; - return Statement(); + st.control = true; + process_control_statement(st); } - else + + if(raw || !st.control) return st; + else if(!good) // This will occur with an __end statement + return Statement(); } } catch(const exception &e) @@ -72,5 +61,57 @@ Statement Parser::parse() } } +void Parser::process_control_statement(const Statement &st) +{ + if(st.keyword=="__bin") + { + delete mode; + mode = new BinaryParser(in, src); + + while(in.peek()=='\n') + in.get(); + } + else if(st.keyword=="__text") + { + delete mode; + mode = new TextParser(in, src); + } + else if(st.keyword=="__z") + in.set_decompress(); + else if(st.keyword=="__src") + { + string s = st.args[0].get(); + if(s.empty()) + src = main_src; + else + src = format("%s[%s]", main_src, s); + } + else if(st.keyword=="__end") + good = false; + else + mode->process_control_statement(st); +} + +const StatementKey *Parser::peek(unsigned level) +{ + while(good) + { + const StatementKey *key = mode->peek(level); + if(key && !key->keyword.compare(0, 2, "__")) + process_control_statement(mode->parse()); + else + return key; + } + + return 0; +} + +bool Parser::parse_and_load(unsigned level, Loader &ldr, const LoaderAction &act) +{ + // Peek first to get any control statements processed + peek(level); + return mode->parse_and_load(level, ldr, act); +} + } // namespace DataFile } // namespace Msp