From 29fafaa2c570b0cf92f41eeb534cfb65a841a892 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 5 Aug 2013 12:19:31 +0300 Subject: [PATCH] Restructure control statement processing Binary format control statements can no longer occur as substatements, but that was an accidental feature at best. --- source/binaryparser.cpp | 71 ++++++++++++++++++----------------------- source/binaryparser.h | 4 +-- source/parser.cpp | 62 +++++++++++++++++++---------------- source/parser.h | 4 +++ source/parsermode.h | 3 +- source/statement.h | 1 + source/textparser.cpp | 2 +- source/textparser.h | 2 +- tool/packer.cpp | 5 ++- tool/tool.cpp | 2 +- 10 files changed, 80 insertions(+), 76 deletions(-) diff --git a/source/binaryparser.cpp b/source/binaryparser.cpp index 7d1591d..25edd63 100644 --- a/source/binaryparser.cpp +++ b/source/binaryparser.cpp @@ -32,45 +32,7 @@ BinaryParser::BinaryParser(Input &i, const string &s): dict[-3] = StatementKey("__flt", "i"); } -Statement BinaryParser::parse(bool raw) -{ - while(1) - { - Statement st = parse_statement(raw); - if(st.keyword=="__kwd") - { - int id = st.args[0].get(); - if(id<=0) - throw bad_definition("__kwd"); - - const string &kw = st.args[1].get(); - const string &args = st.args[2].get(); - for(string::const_iterator i=args.begin(); i!=args.end(); ++i) - for(unsigned j=0; valid_signatures[j]!=*i; ++j) - if(!valid_signatures[j]) - throw bad_definition("__kwd"); - - dict[id] = StatementKey(kw, args); - } - else if(st.keyword=="__str") - { - int id = st.args[0].get(); - if(id<=0) - throw bad_definition("__str"); - - strings[id] = st.args[1].get(); - } - else if(st.keyword=="__flt") - float_precision = st.args[0].get(); - else - return st; - - if(raw) - return st; - } -} - -Statement BinaryParser::parse_statement(bool raw) +Statement BinaryParser::parse() { while(first && in.peek()=='\n') in.get(); @@ -110,13 +72,42 @@ Statement BinaryParser::parse_statement(bool raw) unsigned nsub = parse_int(); for(unsigned j = 0; j(); + if(id<=0) + throw bad_definition("__kwd"); + + const string &kw = st.args[1].get(); + const string &args = st.args[2].get(); + for(string::const_iterator i=args.begin(); i!=args.end(); ++i) + for(unsigned j=0; valid_signatures[j]!=*i; ++j) + if(!valid_signatures[j]) + throw bad_definition("__kwd"); + + dict[id] = StatementKey(kw, args); + } + else if(st.keyword=="__str") + { + int id = st.args[0].get(); + if(id<=0) + throw bad_definition("__str"); + + strings[id] = st.args[1].get(); + } + else if(st.keyword=="__flt") + float_precision = st.args[0].get(); +} + IntType::Store BinaryParser::parse_int() { IntType::Store result = 0; diff --git a/source/binaryparser.h b/source/binaryparser.h index d275290..6a46639 100644 --- a/source/binaryparser.h +++ b/source/binaryparser.h @@ -25,9 +25,9 @@ private: public: BinaryParser(Input &i, const std::string &s); - virtual Statement parse(bool); + virtual Statement parse(); + virtual void process_control_statement(const Statement &); private: - Statement parse_statement(bool); IntType::Store parse_int(); FloatType::Store parse_float(); StringType::Store parse_string(); diff --git a/source/parser.cpp b/source/parser.cpp index 3957cf3..6166e56 100644 --- a/source/parser.cpp +++ b/source/parser.cpp @@ -32,37 +32,17 @@ Statement Parser::parse(bool raw) { while(1) { - Statement st = mode->parse(raw); - if(st.keyword=="__bin") + Statement st = mode->parse(); + if(!st.keyword.compare(0, 2, "__")) { - delete mode; - mode = new BinaryParser(in, src); + st.control = true; + process_control_statement(st); } - 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 raw ? st : Statement(); - } - else - return st; - if(raw) + if(raw || !st.control) return st; + else if(!good) // This will occur with an __end statement + return Statement(); } } catch(const exception &e) @@ -75,5 +55,33 @@ Statement Parser::parse(bool raw) } } +void Parser::process_control_statement(const Statement &st) +{ + if(st.keyword=="__bin") + { + 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; + else + mode->process_control_statement(st); +} + } // namespace DataFile } // namespace Msp diff --git a/source/parser.h b/source/parser.h index 6ad28b5..0989bd9 100644 --- a/source/parser.h +++ b/source/parser.h @@ -36,6 +36,10 @@ public: */ Statement parse(bool raw = false); +private: + void process_control_statement(const Statement &); + +public: operator bool() const { return good && in; } }; diff --git a/source/parsermode.h b/source/parsermode.h index 58a7e27..620e9a9 100644 --- a/source/parsermode.h +++ b/source/parsermode.h @@ -21,7 +21,8 @@ protected: public: virtual ~ParserMode() { } - virtual Statement parse(bool) = 0; + virtual Statement parse() = 0; + virtual void process_control_statement(const Statement &) { } }; } // namespace DataFile diff --git a/source/statement.h b/source/statement.h index 1df3438..80b7b15 100644 --- a/source/statement.h +++ b/source/statement.h @@ -15,6 +15,7 @@ public: std::string keyword; Arguments args; bool valid; + bool control; std::string source; unsigned line; std::list sub; diff --git a/source/textparser.cpp b/source/textparser.cpp index afa78b9..05521a9 100644 --- a/source/textparser.cpp +++ b/source/textparser.cpp @@ -35,7 +35,7 @@ TextParser::TextParser(Input &i, const string &s): ParserMode(i, s) { } -Statement TextParser::parse(bool) +Statement TextParser::parse() { return parse_statement(0); } diff --git a/source/textparser.h b/source/textparser.h index 8235dc6..e8c8922 100644 --- a/source/textparser.h +++ b/source/textparser.h @@ -13,7 +13,7 @@ class TextParser: public ParserMode public: TextParser(Input &, const std::string &); - virtual Statement parse(bool); + virtual Statement parse(); protected: Statement parse_statement(const Token *); Token parse_token(); diff --git a/tool/packer.cpp b/tool/packer.cpp index 44be724..ff69912 100644 --- a/tool/packer.cpp +++ b/tool/packer.cpp @@ -106,8 +106,7 @@ void Packer::transfer_datafile(IO::Base &in, const string &fn, IO::Base &out, Ob DataFile::Statement st = parser.parse(true); if(st.valid) { - bool sys = !st.keyword.compare(0, 2, "__"); - if(collection && !sys) + if(collection && !st.control) { if(st.get_signature()=="s") { @@ -119,7 +118,7 @@ void Packer::transfer_datafile(IO::Base &in, const string &fn, IO::Base &out, Ob else collection = false; } - if(!sys || st.keyword=="__src") + if(!st.control || st.keyword=="__src") writer->write(st); } } diff --git a/tool/tool.cpp b/tool/tool.cpp index 81c6be9..a82d587 100644 --- a/tool/tool.cpp +++ b/tool/tool.cpp @@ -63,7 +63,7 @@ void DataTool::do_transfer() while(parser) { DataFile::Statement st = parser.parse(true); - if(st.valid && (st.keyword.compare(0, 2, "__") || st.keyword=="__src" || debug)) + if(st.valid && (!st.control || st.keyword=="__src" || debug)) writer->write(st); } -- 2.43.0